У меня есть переменная в 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 -->
Удачи!
json_encode
?
Я попробую более простой ответ:
Во-первых, позвольте понять поток событий, когда страница обслуживается с нашего сервера:
Так что, главное, чтобы помнить, что 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
является 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
route/file, который содержит код, который захватывает данные и что-то делает с ним, в вашем случае:
<$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, этот и этот вопрос.
parse
и stringify
). JSON по определению является последовательностью символов.
{}
является допустимым объектом JSON - см. json.org
Я обычно использую атрибуты 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 функциями, поэтому после этой модели я написал простой класс для размещения сценариев на странице в соответствии с зависимостями script и для предоставления дополнительных данных для script.
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()
предназначен для добавления script, установки сума и зависимостей других скриптов и дополнительных данных, необходимых для 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>
Независимо от того, что script 'jquery' находится в очереди после "jquery-ui", он печатается раньше, потому что он определен в "jquery-ui", который зависит от "jquery".
Дополнительные данные для "custom- script" находятся внутри нового блока script и расположены перед ним, он содержит объект mydata
, который содержит дополнительные данные, теперь доступный для "custom-script".
попробуйте это
<?php
echo "<script> var x = ". json_encode($phpVariable)."</script>";
?>
-
-После попытки этого на некоторое время Хотя он работает, однако он замедляет производительность. поскольку php является серверной стороной script, в то время как javascript является пользовательской стороной.
myPlugin.start($val); // tried this, didn't work
Это не работает, потому что $val
имеет значение undefined в отношении javascript, т.е. php ничего не выводил для $val
. Попробуйте просмотреть источник в своем браузере, и вот что вы увидите:
myPlugin.start(); // tried this, didn't work
и
<?php myPlugin.start($val); ?> // this didn't work either
Это не работает, потому что php будет пытаться рассматривать myPlugin
как константу, а когда это не удается, он попытается рассматривать его как строку 'myPlugin'
, которую он попытается связать с выходом функции php start()
, и поскольку это undefined, это приведет к фатальной ошибке
и
myPlugin.start(<?=$val?> // this works sometimes, but sometimes it fails
В то время как это, скорее всего, сработает, поскольку php генерирует действительный javascript с ожидаемыми аргументами, если он терпит неудачу, скорее всего, это потому, что myPlugin
еще не готов. Проверьте порядок выполнения.
Также вы должны заметить, что php out put небезопасен и должен быть отфильтрован с помощью json_encode()
EDIT
Поскольку я не заметил отсутствующую скобку в myPlugin.start(<?=$val?>
: -\
Как отмечает @Second Rikudo, для правильной работы $val
необходимо было бы закрыть закрывающую скобку, например: $val="42);"
Значение, которое php теперь произведет myPlugin.start(42);
и будет работать как ожидалось, когда выполняется javascript
myPlugin.start(<?=json_encode($val)?>);
Я выступил с простым методом назначения переменных 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
Ее код 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");
}
Пример:
ШАГ 1
<?php
$servername = "localhost";
$username = "";
$password = "";
$dbname = "";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT id, name, image FROM phone";
$result = $conn->query($sql);
while($row = $result->fetch_assoc()){
$v[] = $row;
}
echo json_encode($v);
$conn->close();
?>
ШАГ 2
function showUser(fnc) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// STEP 3
var p = JSON.parse(this.responseText);
}
}
}
Вот трюк:
вот ваш "PHP" для использования этой переменной:
<?php
$name = 'PHP variable';
echo '<script>';
echo 'var name = ' . json_encode($name) . ';';
echo '</script>';
?>
Теперь у вас есть переменная JS с именем 'name'
, и вот ваш "Javascript" для использования этой переменной:
<script>
console.log("i am everywhere " + name);
</script>
вот один, который я не вижу в качестве опции. он похож на использование ajax, но явно отличается.
сначала установите источник script непосредственно в файл 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 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;
?>
var1=value1
. В существующем состоянии ваш скрипт сломается, если данные содержат символ '
.
var1 != [some HTML code]
... CLEARLY var1=="value1"
. Проще говоря, вы не правы, что я что-то пропустил. скрипт EXAMPLE завершен, и, как вы можете видеть, не генерирует никакого HTML-кода, а OP не упоминал HTML. это не заслуживает понижения голоса каким-то триггером
После долгих исследований я нашел самый простой способ легко передавать все виды переменных.
В сценарии сервера у вас есть две переменные, и вы пытаетесь отправить их клиентским сценариям:
$php_var1 ="Hello world";
$php_var2 ="Helloow";
echo '<script>';
echo 'var js_variable1= ' . json_encode($php_var1) . ';';
echo 'var js_variable2= ' . json_encode($php_var2) . ';';
echo '</script>';
В любом из ваших javascript, вызываемых на странице, просто вызывайте эти переменные.
пусть ваша переменная всегда целая, в этом случае это проще
<?PHP
$number = 4;
echo '<script>';
echo 'var number = ' . $number . ';';
echo 'alert(number);';
echo '</script>';
?>
выход:
<script>var number = 4;alert(number);</script>
скажем, ваша переменная не является целым числом, но если вы попробуете метод выше, вы получите что-то вроде этого:
<script>var number = abcd;alert(number);</script>
но в javascript это синтаксическая ошибка.
поэтому в php мы вызываем функцию json_encode
которая кодирует строку для json-объекта.
<?PHP
$number = 'abcd';
echo '<script>';
echo 'var number = ' . json_encode($number) . ';';
echo 'alert(number);';
echo '</script>';
?>
поскольку abcd
в json это "abcd"
, поэтому он выглядит так:
<script>var number = "abcd";alert(number);</script>
Вы можете использовать тот же метод для массивов:
<?PHP
$details = [
'name' => 'supun',
'age' => 456,
'weight' => '55'
];
echo '<script>';
echo 'var details = ' . json_encode($details) . ';';
echo 'alert(details);';
echo 'console.log(details);';
echo '</script>';
?>
и ваш javascript выглядит так:
<script>var details = {"name":"supun","age":456,"weight":"55"};alert(details);console.log(details);</script>
консольный выход
Я предполагаю, что передаваемые данные являются строкой.
Как отмечают другие комментаторы, 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
$val = $myService->getValue(); // makes an api and db call
echo '<span id="value">'.$val.'</span>';
$>
Теперь вы можете получить значение с помощью DOM, используйте innerHTML идентификатора span, в этом случае вам не нужно делать вызов на сервер или ajax или любую другую вещь.
Ваша страница будет печатать его с помощью php, и ваш javascript получит значение с помощью DOM.
<
и >
. Также подобные решения уже были предложены.
<?php
$your_php_variable= 22;
echo "<script type='text/javascript'>var your_javascript_variable = $your_php_variable;</script>";
?>
и это сработает. Он просто назначает переменную javascript, а затем передает значение существующей переменной php. Поскольку php записывает здесь строки javascript, он имеет значение переменной php и может передавать ее напрямую.
Для тех, у кого есть проблемы с использованием кода ниже, и он продолжает показывать <?php echo $username?>
или что-то вроде этого. Редактируйте httpd.conf в разделе mime_module, добавив это приложение AddType/x-httpd-php.html.htm. потому что по умолчанию он может быть отключен.
<?php
$username = 1;
?>
<script type="text/javascript">
var myData = <?php echo $username ?>;
console.log(myData);
alert(myData);
</script>
$username === "hello"
, то у вас есть var myData = hello;
который ужасно сломается.
<script>
window.$val = '$myService->getValue()';
</script>
Вы можете использовать его:
<script language='javascript'> var a=<?php echo $a;?>; </script>
и помните, что php перед выполнением, когда закончить запуск javascript для запуска. aren't parallels, являются секвенциальными.
myPlugin.start(<?=$val?>
? Правда ли, что «это иногда работает»?"42)"
это будет хорошо работать: D