Как передать переменные и данные с PHP на JavaScript?

У меня есть переменная в PHP, и мне нужно ее значение в моем JavaScript-коде. Как я могу получить свою переменную от PHP до JavaScript?

У меня есть код, который выглядит так:

<?php ... $val = $myService->getValue(); // makes an api and db call ?> 

У меня есть JavaScript-код, который требует val и выглядит по строкам:

 <script> myPlugin.start($val); // tried this, didn't work <?php myPlugin.start($val); ?> // this didn't work either myPlugin.start(<?=$val?> // this works sometimes, but sometimes it fails </script> 

На самом деле существует несколько способов сделать это. Некоторым требуется больше накладных расходов, чем другие, и некоторые из них считаются лучше, чем другие.

В определенном порядке:

  1. Используйте AJAX для получения необходимых данных с сервера.
  2. Повторите отправку данных на страницу и используйте JavaScript для получения информации из DOM.
  3. Отбросьте данные непосредственно на JavaScript.

В этом посте мы рассмотрим каждый из вышеуказанных методов и рассмотрим все плюсы и минусы каждого, а также как их реализовать.

1. Используйте AJAX для получения необходимых данных с сервера

Этот метод считается лучшим, потому что сценарии на стороне сервера и на стороне клиента полностью разделены .

Pros

  • Лучшее разделение между слоями. Если завтра вы перестанете использовать PHP и хотите перейти на сервлет, REST API или какую-либо другую услугу, вам не придется менять большую часть кода JavaScript.
  • Более читаемый – JavaScript – это JavaScript, PHP – это PHP. Без смешивания двух вы получите более читаемый код на обоих языках.
  • Позволяет передавать данные async. Получение информации из PHP может быть дорогостоящим временем / ресурсами. Иногда вы просто не хотите ждать информации, загружать страницу и получать информацию всякий раз.
  • Данные не обнаруживаются непосредственно в разметке – это означает, что ваша разметка не очищается от каких-либо дополнительных данных, и только JavaScript видит ее.

Cons

  • Задержка – AJAX создает HTTP-запрос, а HTTP-запросы переносятся по сети и имеют сетевые задержки.
  • Состояние. Данные, полученные с помощью отдельного HTTP-запроса, не будут содержать никакой информации из HTTP-запроса, который извлекал HTML-документ. Вам может понадобиться эта информация (например, если HTML-документ создается в ответ на отправку формы), и если вам это нужно, вам придется каким-то образом передать его. Если вы исключили вложение данных на странице (которые у вас есть, если вы используете эту технику), это ограничивает вас файлами cookie / сеансами, которые могут быть подвергнуты условиям гонки.

Пример внедрения

С AJAX вам нужны две страницы, одна из которых – PHP, генерирующая вывод, а вторая – где JavaScript получает этот вывод:

получить-data.php

 /* Do some operation here, like talk to the database, the file-session * The world beyond, limbo, the city of shimmers, and Canada. * * AJAX generally uses strings, but you can output JSON, HTML and XML as well. * It all depends on the Content-type header that you send with your AJAX * request. */ echo json_encode(42); //In the end, you need to echo the result. //All data should be json_encode() d. //You can json_encode() any value in PHP, arrays, strings, //even objects. 

index.php (или то, что именуется собственно страницей)

 <!-- snip --> <script> function reqListener () { console.log(this.responseText); } var oReq = new XMLHttpRequest(); //New request object oReq.onload = function() { //This is where you handle what to do with the response. //The actual data is found on this.responseText alert(this.responseText); //Will alert: 42 }; oReq.open("get", "get-data.php", true); // ^ Don't block the rest of the execution. // Don't wait until the request finishes to // continue. oReq.send(); </script> <!-- snip --> 

Вышеуказанная комбинация двух файлов будет предупреждать 42 когда файл завершит загрузку.

Еще несколько материалов для чтения

  • Использование XMLHttpRequest – MDN
  • Ссылка на объект XMLHttpRequest – MDN
  • Как вернуть ответ от асинхронного вызова?

2. Повторите эхо-данные на странице и используйте JavaScript для получения информации из DOM

Этот метод менее предпочтителен для AJAX, но он по-прежнему имеет свои преимущества. Он все еще относительно разделен между PHP и JavaScript в том смысле, что в JavaScript нет PHP.

Pros

  • Быстрые операции DOM часто бывают быстрыми, и вы можете хранить и получать доступ к большому количеству данных относительно быстро.

Cons

  • Потенциально нежелательная разметка. Обычно происходит то, что вы используете какой-то тип <input type=hidden> для хранения информации, потому что легче получить информацию из inputNode.value , но это означает, что у вас есть бессмысленный элемент в ваш HTML. HTML имеет элемент <meta> для данных о документе, а в HTML 5 вводятся атрибуты data-* для данных, специально предназначенных для чтения с JS, которые могут быть связаны с конкретными элементами.
  • Dirties up the Source – данные, которые генерирует PHP, выводятся непосредственно в источник HTML, что означает, что вы получаете больший и менее сфокусированный источник HTML.
  • Сложнее получить структурированные данные. Структурированные данные должны быть действительными HTML, иначе вам придется бежать и преобразовывать строки самостоятельно.
  • Плотно соединяет PHP с вашей логикой данных. Поскольку PHP используется в презентации, вы не можете отделить эти два.

Пример внедрения

При этом идея состоит в том, чтобы создать какой-то элемент, который не будет отображаться для пользователя, но будет виден JavaScript.

index.php

 <!-- snip --> <div id="dom-target" style="display: none;"> <?php $output = "42"; //Again, do some operation, get the output. echo htmlspecialchars($output); /* You have to escape because the result will not be valid HTML otherwise. */ ?> </div> <script> var div = document.getElementById("dom-target"); var myData = div.textContent; </script> <!-- snip --> 

3. Извлечь данные непосредственно на JavaScript

Это, наверное, проще всего понять, и самое ужасное в использовании. Не делай этого, если не знаешь, что делаешь.

Pros

  • Очень легко реализовано. Это очень мало для реализации этого и понимания.
  • Не загрязняет источник – переменные выводятся непосредственно на JavaScript, поэтому DOM не затрагивается.

Cons

  • Insecure – PHP не имеет тривиальных функций escape-кода JavaScript, и они не являются тривиальными для реализации. Особенно при использовании пользовательских входов вы очень уязвимы для инъекций второго уровня. Спорить см. Комментарии
  • Плотно соединяет PHP с вашей логикой данных. Поскольку PHP используется в презентации, вы не можете отделить эти два.
  • Структурированные данные сложны. Возможно, вы можете сделать JSON … kinda. Но XML и HTML потребуют особого внимания.

Пример внедрения

Реализация относительно проста:

 <!-- snip --> <script> var data = <?php echo json_encode("42", JSON_HEX_TAG); ?>; //Don't forget the extra semicolon! </script> <!-- snip --> 

Удачи!

Я попробую более простой ответ:

Объяснение проблемы

Во-первых, давайте понимать поток событий, когда страница обслуживается с нашего сервера:

  • Первый PHP запущен, он генерирует HTML, который подается клиенту.
  • Затем HTML доставляется клиенту, после того, как PHP будет с ним выполнен, я хотел бы подчеркнуть, что, как только код покидает сервер, PHP завершается с ним и больше не может его получить.
  • Затем HTML с JavaScript достигает клиента, который может выполнять JS на этом html.

Итак, главное, чтобы помнить, что HTTP не имеет апатридов . После того, как запрос покинул сервер, сервер не может его коснуться. Таким образом, это оставляет наши возможности:

  1. Отправляйте больше запросов от клиента после выполнения первоначального запроса.
  2. Кодируйте то, что сервер должен был сказать в первоначальном запросе.

Решения

Это основной вопрос, который вы должны задать себе:

Я пишу веб-сайт или приложение?

Веб-сайты в основном основаны на страницах, а время загрузки страницы должно быть как можно быстрее (например, Википедия). Веб-приложения более тяжелые AJAX и совершают много круговых поездок, чтобы быстро получить информацию о клиенте (например, панель управления запасами).

Веб-сайт

Отправка большего количества запросов от клиента после выполнения первоначального запроса выполняется медленно, поскольку для этого требуется больше HTTP-запросов, которые имеют значительные накладные расходы. Более того, для асинхронности требуется асинхронность, поскольку для запроса AJAX требуется обработчик, когда он будет завершен.

Я бы не рекомендовал делать другой запрос, если ваш сайт не является приложением для получения этой информации с сервера.

Вы хотите быстрое время отклика, которое оказывает огромное влияние на время конверсии и загрузки. Выполнение ajax-запросов в этом случае медленное для первоначального времени безотказной работы и ненужное.

У вас есть два способа решить проблему

  • Установите cookie – файлы cookie – это заголовки, отправленные в HTTP-запросах, которые могут считывать как сервер, так и клиент.
  • Кодируйте переменную как JSON – JSON очень похож на объекты JavaScript, и большинство объектов JSON являются действительными переменными JavaScript.

Настройка файла cookie действительно не очень сложна, вы просто назначаете ему значение:

 setcookie("MyCookie", $value); // sets the cookie to the value, remember, do not // set it with HTTP only to true. 

Затем вы можете прочитать его с помощью JavaScript с помощью document.cookie :

Вот короткий рулонный парсер, но ответ, который я связал прямо над ним, лучше проверял:

 var cookies = document.cookie.split(";"). map(function(el){ return el.split("="); }). reduce(function(prev,cur){ prev[cur[0]] = cur[1];return prev },{}); cookies["MyCookie"] // value set with php. 

Файлы cookie хороши для небольших данных. Это то, что часто делают службы отслеживания.

Как только у нас будет больше данных, мы можем кодировать его с помощью JSON внутри переменной JS:

 <script> var myServerData = <?=json_encode($value)?>; // don't forget to sanitize //server data </script> 

Предполагая, что $value is json_encode на стороне PHP (оно обычно есть). Этот метод – это то, что StackOverflow делает со своим чатом, например (только с использованием .net вместо php).

заявка

Если вы пишете приложение – внезапно начальное время загрузки не всегда так важно, как текущая производительность приложения, и он начинает окупаться для загрузки данных и кода отдельно.

Мой ответ здесь объясняет, как загружать данные с помощью AJAX в JavaScript:

 function callback(data){ // what do I do with the response? } var httpRequest = new XMLHttpRequest; httpRequest.onreadystatechange = function(){ if (httpRequest.readyState === 4) {// request is done if (httpRequest.status === 200) {// successfully callback(httpRequest.responseText);// we're calling our method } } }; httpRequest.open('GET', "/echo/json"); httpRequest.send(); 

Или с jQuery:

 $.get("/your/url").done(function(data){ // what do I do with the data? }); 

Теперь сервер просто должен содержать маршрут / файл /your/url , содержащий код, который захватывает данные и что-то делает с ним, в вашем случае:

 <$php ... $val = myService->getValue(); // makes an api and db call echo json_encode($val); // write it to the output $> 

Таким образом, наш JS-файл запрашивает данные и показывает их, а не запрашивает код или макет. Это чище и начинает окупаться по мере того, как приложение становится выше. Это также лучшее разделение проблем, и это позволяет тестировать код на стороне клиента без какой-либо связанной с ним технологии на стороне сервера, что является еще одним плюсом.

Постскриптум: вы должны быть очень осведомлены о векторах атаки XSS, когда вы добавляете что-либо от PHP к JavaScript. Очень трудно избежать значений правильно, и это чувствительно к контексту. Если вы не знаете, как обращаться с XSS, или не знаете об этом – прочитайте эту статью OWASP , этот и этот вопрос .

Обычно я использую атрибуты data- * в html.

 <div class="service-container" data-service="<?php echo $myService->getValue(); ?>"> </div> <script> $(document).ready(function() { $('.service-container').each(function() { var container = $(this); var service = container.data('service'); // service variable now contains the value of $myService->getValue(); }); }); </script> 

В этом примере используется jQuery, но может быть адаптирован для другой библиотеки или ванильного Javascript.

Подробнее о свойстве набора данных можно узнать здесь: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.dataset

 <script> var jsvar = <?php echo json_encode($PHPVar); ?>; </script> 

json_encode () требует:

  • PHP 5.2.0 и более
  • $PHPVar кодируется как UTF-8, Unicode.

Просто используйте один из следующих способов.

 <script type="text/javascript"> var js_variable = '<?php echo $php_variable;?>'; <script> 

ИЛИ

 <script type="text/javascript"> var js_variable = <?php echo json_encode($php_variable); ?>; </script> 

Мне очень нравится, как WordPress работает с функциями enqueue и localize , поэтому, следуя этой модели, я написал простой класс для размещения сценариев на странице в соответствии с зависимостями сценария и для предоставления дополнительных данных для скрипта.

 class mHeader { private $scripts = array(); /** * @param string $id unique script identifier * @param string $src script src attribute * @param array $deps an array of dependencies ( script identifiers ). * @param array $data an array, data that will be json_encoded and available to the script. */ function enqueue_script( $id, $src, $deps = array(), $data = array() ) { $this->scripts[$id] = array( 'src' => $src, 'deps' => $deps, 'data' => $data ); } private function dependencies( $script ) { if ( $script['deps'] ) { return array_map( array( $this, 'dependencies' ), array_intersect_key( $this->scripts, array_flip( $script['deps'] ) ) ); } } private function _unset( $key, &$deps, &$out ) { $out[$key] = $this->scripts[$key]; unset( $deps[$key] ); } private function flattern( &$deps, &$out = array() ) { foreach( $deps as $key => $value ) { empty($value) ? $this->_unset( $key, $deps, $out ) : $this->flattern( $deps[$key], $out ); } } function print_scripts() { if ( !$this->scripts ) return; $deps = array_map( array( $this, 'dependencies' ), $this->scripts ); while ( $deps ) $this->flattern( $deps, $js ); foreach( $js as $key => $script ) { $script['data'] && printf( "<script> var %s = %s; </script>" . PHP_EOL, key( $script['data'] ), json_encode( current( $script['data'] ) ) ); echo "<script id=\"$key-js\" src=\"$script[src]\" type=\"text/javascript\"></script>" . PHP_EOL; } } } 

Вызов функции enqueue_script() – это добавление сценария, настройка суба и зависимостей от других скриптов и дополнительные данные, необходимые для скрипта.

 $header = new mHeader(); $header->enqueue_script( 'jquery-ui', '//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js', array( 'jquery' ) ); $header->enqueue_script( 'jquery', '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js' ); $header->enqueue_script( 'custom-script', '//custom-script.min.js', array( 'jquery-ui' ), array( 'mydata' => array( 'value' => 20 ) ) ); $header->print_scripts(); 

И метод print_scripts() из приведенного выше примера отправит этот вывод:

 <script id="jquery-js" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script> <script id="jquery-ui-js" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js" type="text/javascript"></script> <script> var mydata = {"value":20}; </script> <script id="custom-script-js" src="//custom-script.min.js" type="text/javascript"></script> 

Независимо от того, что сценарий «jquery» находится в очереди после «jquery-ui», он печатается ранее, потому что он определен в «jquery-ui», который зависит от «jquery». Дополнительные данные для «custom-script» находятся внутри нового блока сценариев и размещаются перед ним, он содержит объект mydata который содержит дополнительные данные, теперь доступный для «настраиваемого сценария».

 myPlugin.start($val); // tried this, didn't work 

Это не работает, потому что $val не определен для javascript, т.е. php ничего не выводил для $val . Попробуйте просмотреть источник в своем браузере, и вот что вы увидите:

 myPlugin.start(); // tried this, didn't work 

А также

 <?php myPlugin.start($val); ?> // this didn't work either 

Это не сработает, потому что php попытается обработать myPlugin как константу, и когда это произойдет, он попытается рассматривать его как строку 'myPlugin' которую он попытается 'myPlugin' с выходом функции php start() и поскольку это не определено, это приведет к фатальной ошибке

А также

  myPlugin.start(<?=$val?> // this works sometimes, but sometimes it fails 

Хотя это, скорее всего, сработает, так как php генерирует допустимый javascript с ожидаемыми аргументами, если он терпит неудачу, есть вероятность, потому что myPlugin еще не готов. Проверьте порядок выполнения.

Также вы должны заметить, что php out put небезопасен и должен быть отфильтрован с помощью json_encode()

РЕДАКТИРОВАТЬ

Потому что я не заметил отсутствующую скобку в myPlugin.start(<?=$val?> : – \

Как указывает @Second Rikudo, для корректной работы $val необходимо было бы содержать закрывающую скобку, например: $val="42);"

Это означает, что php теперь будет производить myPlugin.start(42); и будет работать, как ожидалось, когда выполняется javascript

попробуй это

 <?php echo "<script> var x = ". json_encode($phpVariable)."</script>"; ?> 

-После попытки этого какое-то время Хотя он работает, однако он замедляет производительность. поскольку php является скриптом на стороне сервера, а javascript – пользователем.

Я получил простой способ присвоить переменные JavaScript с помощью PHP.

Он использует атрибуты данных HTML5 для хранения переменных PHP, а затем присваивается JavaScript при загрузке страницы.

Полное учебное пособие можно найти здесь

Пример:

 <?php $variable_1 = "QNimate"; $variable_2 = "QScutter"; ?> <span id="storage" data-variable-one="<?php echo $variable_1; ?>" data-variable-two="<?php echo $variable_2; ?>"></span> <?php 

Hers – это код JS

 var variable_1 = undefined; var variable_2 = undefined; window.onload = function(){ variable_1 = document.getElementById("storage").getAttribute("data-variable-one"); variable_2 = document.getElementById("storage").getAttribute("data-variable-two"); } 

вот один, который я не вижу в качестве опции. он похож на использование ajax, но явно отличается.

сначала установите источник скрипта непосредственно в файл PHP.

 <script type="text/javascript" src="url_to_your_php_file.php" /></script> 

вы даже можете передать переменную обратно в файл PHP, такой как этот пример:

 <script type="text/javascript" src="url_to_your_php_file.php?var1=value1" /></script> 

затем в «your_php_file.php»:

 <?php // THIS IS A SIMPLE EXAMPLE // it demonstrates one method of using the src attribute to link // to a PHP file which can generate javascripts dynamically // and share data between PHP and javascript // you may take this learning example and develop it further // relying on your own coding skills for validating data // and avoiding errors, of course header( 'content-type: text/javascript' ); // if you pass a $_GET variable from the javascript // you should add code to validate your $_GET variable(s) // you can add code to query a database // using $_GET['var1'] or some other criteria // you can add simple variable assignments $value = 'some value'; // for the OP's needs (assumes the class object has been defined) $val = $myService->getValue(); ?> function name() { // pay attention because you need to use quotes properly // and account for possible quotes in the variable strings // to avoid both php and javascript errors // example assumes $val has been returned as a string // validate $val as needed using your method of choice var example1 = '<?php echo '"' . $val . '"'; ?>'; var example2 = '<?php echo '"' . $value . '"'; ?>'; var example3 = '<?php echo '"some other data"'; ?>'; alert( example1 + ' / ' + example2 ); } <?php // you may even want to include additional files (.php or .js, etc) @include 'local_path_to_some_other_js_file.js'; @include 'local_path_to_some_other_php_file.php'; exit; ?> 

Я предполагаю, что данные для передачи – это строка.

Как отмечают другие комментаторы, AJAX – одно из возможных решений, но недостатки превосходят плюсы: он имеет задержку, и его сложнее программировать (ему нужен код для извлечения значения как на стороне сервера, так и на стороне клиента), когда более простой функция экранирования должна быть достаточной.

Итак, мы вернулись к побегу. json_encode($string) работает, если вы сначала кодируете исходную строку как UTF-8, если ее еще нет, потому что для json_encode требуются данные UTF-8. Если строка находится в ISO-8859-1, вы можете просто использовать json_encode(utf8_encode($string)) ; иначе вы всегда можете использовать iconv для выполнения преобразования.

Но есть большая добыча. Если вы используете его в событиях, вам нужно запустить htmlspecialchars() в результате, чтобы сделать правильный код. И тогда вы должны быть осторожны, чтобы использовать двойные кавычки для включения события или всегда добавлять ENT_QUOTES в htmlspecialchars. Например:

 <?php $myvar = "I'm in \"UTF-8\" encoding and I have <script>script tags</script> & ampersand!"; // Fails: //echo '<body onload="alert(', json_encode($myvar), ');">'; // Fails: //echo "<body onload='alert(", json_encode($myvar), ");'>"; // Fails: //echo "<body onload='alert(", htmlspecialchars(json_encode($myvar)), ");'>"; // Works: //echo "<body onload='alert(", htmlspecialchars(json_encode($myvar), ENT_QUOTES), ");'>"; // Works: echo '<body onload="alert(', htmlspecialchars(json_encode($myvar)), ');">'; echo "</body>"; 

Однако вы не можете использовать htmlspecialchars для обычного JS-кода (код, заключенный в теги <script></script> ). Это позволяет использовать эту функцию, подверженную ошибкам, забывая о htmlspecialchars результате при написании кода события.

Можно написать функцию, которая не имеет этой проблемы, и может использоваться как в событиях, так и в обычном JS-коде, если вы всегда включаете свои события в одинарные кавычки или всегда в двойных кавычках. Вот мое предложение, требующее, чтобы они были в двойных кавычках (что я предпочитаю):

 <?php // Optionally pass the encoding of the source string, if not UTF-8 function escapeJSString($string, $encoding = 'UTF-8') { if ($encoding != 'UTF-8') $string = iconv($encoding, 'UTF-8', $string); $flags = JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_UNESCAPED_SLASHES; $string = substr(json_encode($string, $flags), 1, -1); return "'$string'"; } 

Для функции требуется PHP 5.4+. Пример использования:

 <?php $myvar = "I'm in \"UTF-8\" encoding and I have <script>script tags</script> & ampersand!"; // Note use of double quotes to enclose the event definition! echo '<body onload="alert(', escapeJSString($myvar), ');">'; // Example with regular code: echo '<script>alert(', escapeJSString($myvar), ');</script>'; echo '</body>'; 

Вот трюк:

 <?php $name = 'PHP variable'; echo '<script>'; echo 'var name = ' . json_encode($name) . ';'; echo '</script>'; <? <script> console.log("i am everywhere " + name); </script> 

Согласно вашему коду

 <$php $val = $myService->getValue(); // makes an api and db call echo '<span id="value">'.$val.'</span>'; $> 

Теперь вы можете получить значение с помощью DOM, используйте innerHTML идентификатора span, в этом случае вам не нужно делать вызов на сервер, ajax или любую другую.

Ваша страница будет печатать его с помощью php, и вы получите Javascript, используя DOM.

For those who have some problem using below code and it keep showing <?php echo $username?> or something like this.Go edit the httpd.conf in mime_module section by add this 'AddType application/x-httpd-php .html .htm' because it may disable by default.

  <?php $username = 1; ?> <script type="text/javascript"> var myData = <?php echo $username ?>; console.log(myData); alert(myData); </script> 
  <?php $your_php_variable= 22; echo "<script type='text/javascript'>var your_javascript_variable = $your_php_variable;</script>"; ?> 

and that will work. It's just assigning a javascript variable and then passing the value of an existing php variable. Since php writes the javascript lines here, it has the value of of the php variable and can pass it directly.

  <script> window.$val = '$myService->getValue()'; </script> 

You can use it:

 <script language='javascript'> var a=<?php echo $a;?>; </script> 

and remember php is prior to execute, when finish begin javascript to run. aren´t parallels, are sequencial.