У меня есть переменная в 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>
На самом деле существует несколько способов сделать это. Некоторым требуется больше накладных расходов, чем другие, и некоторые из них считаются лучше, чем другие.
В определенном порядке:
В этом посте мы рассмотрим каждый из вышеуказанных методов и рассмотрим все плюсы и минусы каждого, а также как их реализовать.
Этот метод считается лучшим, потому что сценарии на стороне сервера и на стороне клиента полностью разделены .
С AJAX вам нужны две страницы, одна из которых – PHP, генерирующая вывод, а вторая – где JavaScript получает этот вывод:
/* 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.
<!-- 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
когда файл завершит загрузку.
Этот метод менее предпочтителен для AJAX, но он по-прежнему имеет свои преимущества. Он все еще относительно разделен между PHP и JavaScript в том смысле, что в JavaScript нет PHP.
<input type=hidden>
для хранения информации, потому что легче получить информацию из inputNode.value
, но это означает, что у вас есть бессмысленный элемент в ваш HTML. HTML имеет элемент <meta>
для данных о документе, а в HTML 5 вводятся атрибуты data-*
для данных, специально предназначенных для чтения с JS, которые могут быть связаны с конкретными элементами. При этом идея состоит в том, чтобы создать какой-то элемент, который не будет отображаться для пользователя, но будет виден JavaScript.
<!-- 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 -->
Это, наверное, проще всего понять, и самое ужасное в использовании. Не делай этого, если не знаешь, что делаешь.
Реализация относительно проста:
<!-- snip --> <script> var data = <?php echo json_encode("42", JSON_HEX_TAG); ?>; //Don't forget the extra semicolon! </script> <!-- snip -->
Удачи!
Я попробую более простой ответ:
Во-первых, давайте понимать поток событий, когда страница обслуживается с нашего сервера:
Итак, главное, чтобы помнить, что HTTP не имеет апатридов . После того, как запрос покинул сервер, сервер не может его коснуться. Таким образом, это оставляет наши возможности:
Это основной вопрос, который вы должны задать себе:
Веб-сайты в основном основаны на страницах, а время загрузки страницы должно быть как можно быстрее (например, Википедия). Веб-приложения более тяжелые AJAX и совершают много круговых поездок, чтобы быстро получить информацию о клиенте (например, панель управления запасами).
Отправка большего количества запросов от клиента после выполнения первоначального запроса выполняется медленно, поскольку для этого требуется больше HTTP-запросов, которые имеют значительные накладные расходы. Более того, для асинхронности требуется асинхронность, поскольку для запроса AJAX требуется обработчик, когда он будет завершен.
Я бы не рекомендовал делать другой запрос, если ваш сайт не является приложением для получения этой информации с сервера.
Вы хотите быстрое время отклика, которое оказывает огромное влияние на время конверсии и загрузки. Выполнение ajax-запросов в этом случае медленное для первоначального времени безотказной работы и ненужное.
У вас есть два способа решить проблему
Настройка файла 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 () требует:
$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.