如何将variables和数据从PHP传递到JavaScript?
我有一个PHP的variables,我需要在我的JavaScript代码的价值。 我怎样才能让我的variables从PHP到JavaScript?
我有这样的代码:
<?php ... $val = $myService->getValue(); // makes an api and db call ?>
我有需要val
JavaScript代码,看起来如下:
<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从服务器获取所需的数据。
- 将数据回传到某个地方的页面,然后使用JavaScript从DOM获取信息。
- 将数据直接回传给JavaScript。
在这篇文章中,我们将检查上面的每一个方法,看看每个方法的优缺点,以及如何实现它们。
1.使用AJAX从服务器获取所需的数据
这种方法被认为是最好的,因为你的服务器端和客户端脚本是完全分离的 。
优点
- 更好地分离图层 – 如果明天停止使用PHP,并且希望移动到servlet,REST API或其他服务,则不必更改很多JavaScript代码。
- 更可读 – JavaScript是JavaScript,PHP是PHP。 如果不混合这两种语言,您将在两种语言中获得更多可读代码。
- 允许asynchronous数据传输 – 从PHP获取信息可能是时间/资源昂贵。 有时你只是不想等待信息,加载页面,并随时获取信息。
- 数据不能直接在标记中find – 这意味着您的标记保持清洁的任何额外的数据,只有JavaScript看到它。
缺点
- 延迟 – AJAX创build一个HTTP请求,并且HTTP请求通过networking传输并具有networking延迟。
- 状态 – 通过单独的HTTP请求获取的数据将不包括来自获取HTML文档的HTTP请求的任何信息。 您可能需要此信息(例如,如果HTML文档是为了响应表单提交而生成的),如果您确实需要以某种方式进行传输。 如果你已经排除了将数据embedded到页面中(如果你使用这种技术,你将会得到这些数据),那么这就限制了你可能会受到竞争条件影响的cookies /会话。
实现示例
使用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
- 如何返回来自asynchronous调用的响应?
2.将数据回传到某个地方的页面,并使用JavaScript从DOM获取信息
这种方法不如AJAX更好,但它仍然有其优点。 PHP和JavaScript之间仍然相对独立,因为JavaScript中没有直接的PHP。
优点
- 快速 DOM操作通常很快,您可以相对较快地存储和访问大量数据。
缺点
- 潜在的非语义标记 – 通常情况下,你使用某种types的
<input type=hidden>
来存储信息,因为从inputNode.value
获取信息比较容易,但是这样做意味着你没有任何意义你的HTML。 HTML具有关于文档的数据的<meta>
元素,并且HTML 5引入data-*
属性以专门用于与可以与特定元素关联的JS读取的数据。 - Dirties the Source – PHP生成的数据直接输出到HTML源代码,这意味着你得到一个更大,更less的HTML源代码。
- 更难得到结构化的数据 – 结构化的数据将必须是有效的HTML,否则你将不得不逃生并自己转换string。
- 紧密地将PHP耦合到您的数据逻辑 – 因为在演示文稿中使用了PHP,所以不能将这两者完全分开。
实现示例
有了这个,这个想法就是创build一些不会显示给用户的元素,但对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
这可能是最容易理解的,也是最可怕的使用。 除非你知道你在做什么,否则不要这样做。
优点
- 很容易实现 – 实现这一点并且理解起来很less。
- 不脏源 – variables直接输出到JavaScript,所以DOM不受影响。
缺点
- 不安全 – PHP没有简单的JavaScript转义function,而且它们不是微不足道的实现。 特别是在使用用户input时,您非常容易受到二级注入的影响。 争议见评论
- 紧密地将PHP耦合到您的数据逻辑 – 因为在演示文稿中使用了PHP,所以不能将这两者完全分开。
- 结构化的数据很难 – 你也许可以做JSON …还挺。 但是XML和HTML需要特别关注。
实现示例
实施相对简单:
<!-- snip --> <script> var data = <?php echo json_encode("42", JSON_HEX_TAG); ?>; //Don't forget the extra semicolon! </script> <!-- snip -->
祝你好运!
我会尝试一个更简单的答案:
问题的解释
首先,让我们了解从服务器提供页面时的事件stream程:
- 首先运行PHP,它生成提供给客户端的HTML。
- 然后,HTML被传送到客户端,PHP完成后,我想强调,一旦代码离开服务器 – PHP已经完成,不能再访问它。
- 然后,JavaScript的HTML到达客户端,可以在该HTML上执行JS。
所以,真正要记住的核心是HTTP是无状态的 。 一旦请求离开服务器,服务器就不能触摸它。 所以,这使我们的select:
- 初始请求完成后 ,从客户端发送更多请求。
- 在初始请求中编码服务器必须说的内容。
解决scheme
这是你应该问自己的核心问题是:
我正在写一个网站或一个应用程序?
网站主要是基于页面的,页面加载时间需要尽可能快(例如 – 维基百科)。 Web应用程序更多的AJAX沉重,并执行大量的往返获取客户的快速信息(例如 – 股票仪表板)。
网站
初始请求完成后,从客户端发送更多的请求是很慢的,因为它需要更多的HTTP请求,这些HTTP请求具有相当大的开销。 而且,它需要asynchronous性,因为在完成AJAX请求时需要一个处理程序。
除非您的网站是从服务器获取信息的应用程序 , 否则我不会build议再发送一个请求。
您希望快速的响应时间对转换和加载时间产生巨大的影响。 在这种情况下,创buildAjax请求对于初始正常运行时间是缓慢的,并且不需要。
你有两种方法来解决这个问题
- 设置一个cookie – cookies是在服务器和客户端都可以读取的HTTP请求中发送的头文件。
- 将variables编码为JSON – JSON看起来非常接近JavaScript对象, 大多数 JSON对象都是有效的JavaScriptvariables。
设置一个cookie真的不是很难,你只需要给它赋值:
setcookie("MyCookie", $value); // sets the cookie to the value, remember, do not // set it with HTTP only to true.
然后,您可以使用document.cookie
使用JavaScript进行阅读 :
这里是一个简短的滚动parsing器,但是我在上面链接的答案有更好的testing:
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.
Cookies对于一些数据很有用。 这是跟踪服务经常做的事情。
一旦我们有了更多的数据,我们就可以用JSON把它编码成一个JSvariables:
<script> var myServerData = <?=json_encode($value)?>; // don't forget to sanitize //server data </script>
假设$value
是在PHP端(通常是)的json_encode
。 这种技术是StackOverflow与聊天的例子(只使用.net而不是php)。
应用
如果您正在编写应用程序 – 突然间,初始加载时间并不总是与应用程序正在进行的性能一样重要,并且它开始为单独加载数据和代码而付出代价。
我的答案在这里解释了如何在JavaScript中使用AJAX加载数据:
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文件要求数据,并显示它,而不是要求代码或布局。 这是更清洁,并随着应用程序变得更高而开始回报。 这也是更好的分离问题,它允许testing客户端代码,而不涉及任何服务器端技术,这是另一个优点。
后记:当你从PHP到JavaScript注入任何东西时,你必须非常了解XSS攻击向量。 要正确地转义值非常困难,而且对上下文很敏感。 如果您不确定如何处理XSS,或者不知道这些,请阅读OWASP的这篇文章 ,以及这个问题 。
我通常在html中使用data- *属性。
<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('container'); // 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>
不pipe脚本“jquery”在“jquery-ui”之后排队的事实,它之前被打印,因为它在“jquery-ui”中被定义为依赖于“jquery”。 “自定义脚本”的其他数据在一个新的脚本块中,并放置在它的前面,它包含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'
,它会尝试连接php函数start()
的输出,是不确定的,它会产生一个致命的错误
和
myPlugin.start(<?=$val?> // this works sometimes, but sometimes it fails
虽然这是最有可能的工作,因为PHP正在生产有效的JavaScript与预期的参数,如果失败,很可能是因为myPlugin
还没有准备好。 检查你的执行顺序。
你也应该注意到,PHP输出是不安全的,应该用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是用户端。
我已经出来了一个简单的方法来使用PHP分配JavaScriptvariables。
它使用HTML5数据属性来存储PHPvariables,然后在页面加载时将其分配给JavaScript。
完整的教程可以在这里find
例:
<?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"); }
这里是一个我没有看到张贴作为一个选项。 它类似于使用ajax,但明显不同。
首先,将脚本的源直接设置为一个PHP文件。
<script type="text/javascript" src="url_to_your_php_file.php" /></script>
你甚至可以将一个variables传回给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; ?>
我假设要传输的数据是一个string。
正如其他评论者所说,AJAX是一个可能的解决scheme,但是利弊大于专业人员:它有一个延迟,编程更难(它需要代码来检索服务器端和客户端的值),更简单逃逸function应该足够了。
所以,我们又回到了逃跑。 json_encode($string)
在你将源string编码为UTF-8的情况下工作,因为json_encode
需要UTF-8数据。 如果string在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>";
但是,您不能在常规JS代码( <script>
… </script>
标记中包含的代码)中使用htmlspecialchars
。 这使得使用这个函数容易出错,在编写事件代码时忘记了htmlspecialchars
的分类结果。
可以编写一个没有这个问题的函数,并且可以在事件和常规的JS代码中使用,只要将事件总是放在单引号中,或者总是用双引号括起来。 这是我的build议,要求他们用双引号(我更喜欢):
<?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'"; }
该function需要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获得价值,使用span id的innerHTML,在这种情况下,您不需要对服务器,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.