如何从PHP向JavaScript传递变量和数据?

javascript php


我在 PHP 中有一个变量,我需要在我的 JavaScript 代码中加入它的值。如何才能将我的变量从PHP到JavaScript?

我的代码是这样的

<?php
     ...
     $val = $myService->getValue(); // Makes an API and database call
?>

I have JavaScript code that needs val and looks along the lines of:

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



Answer 1 Madara's Ghost


实际上,有几种方法可以做到这一点。有的需要的开销比其他的多,有的人认为比其他的好。

没有特别的顺序。

  1. 使用AJAX从服务器上获取你需要的数据。
  2. 将数据回传到页面的某个地方,然后用JavaScript从DOM中获取信息。
  3. 将数据直接回传给JavaScript。

在本帖中,我们将对上述方法进行逐一研究,看看每种方法的优点和缺点,以及如何实施。

1.使用AJAX从服务器上获取你需要的数据。

This method is considered the best, because your server side and client side scripts are completely separate.

Pros

  • Better separation between layers - If tomorrow you stop using PHP, and want to move to a servlet, a REST API, or some other service, you don't have to change much of the JavaScript code.
  • More readable - JavaScript is JavaScript, PHP is PHP. Without mixing the two, you get more readable code on both languages.
  • Allows for asynchronous data transfer - Getting the information from PHP might be time/resources expensive. Sometimes you just don't want to wait for the information, load the page, and have the information reach whenever.
  • Data is not directly found on the markup - This means that your markup is kept clean of any additional data, and only JavaScript sees it.

Cons

  • Latency - AJAX creates an HTTP request, and HTTP requests are carried over network and have network latencies.
  • State - Data fetched via a separate HTTP request won't include any information from the HTTP request that fetched the HTML document. You may need this information (e.g., if the HTML document is generated in response to a form submission) and, if you do, will have to transfer it across somehow. If you have ruled out embedding the data in the page (which you have if you are using this technique) then that limits you to cookies/sessions which may be subject to race conditions.

实施例

使用AJAX,你需要两个页面,一个是PHP生成输出的地方,第二个是JavaScript获取输出的地方。

get-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 -->

The above combination of the two files will alert 42 when the file finishes loading.

更多的阅读材料

2.将数据回传到页面的某个地方,用JavaScript从DOM中获取信息。

This method is less preferable to AJAX, but it still has its advantages. It's still relatively separated between PHP and JavaScript in a sense that there is no PHP directly in the JavaScript.

Pros

  • Fast - DOM operations are often quick, and you can store and access a lot of data relatively quickly.

Cons

  • Potentially Unsemantic Markup - Usually, what happens is that you use some sort of <input type=hidden> to store the information, because it's easier to get the information out of inputNode.value , but doing so means that you have a meaningless element in your HTML. HTML has the <meta> element for data about the document, and HTML 5 introduces data-* attributes for data specifically for reading with JavaScript that can be associated with particular elements.
  • Dirties up the Source - Data that PHP generates is outputted directly to the HTML source, meaning that you get a bigger and less focused HTML source.
  • Harder to get structured data - Structured data will have to be valid HTML, otherwise you'll have to escape and convert strings yourself.
  • Tightly couples PHP to your data logic - Because PHP is used in presentation, you can't separate the two cleanly.

实施例

通过这个,我们的想法是创建某种元素,它不会显示给用户,但对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.3.将数据直接回传到JavaScript

这可能是最容易理解的。

Pros

  • Very easily implemented - It takes very little to implement this, and understand.
  • Does not dirty source - Variables are outputted directly to JavaScript, so the DOM is not affected.

Cons

  • Tightly couples PHP to your data logic - Because PHP is used in presentation, you can't separate the two cleanly.

实施例

实施起来相对简单明了。

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

祝你们好运!




Answer 2 Benjamin Gruenbaum


我想尝试一个更简单的答案。

对问题的解释

首先,让我们来了解一下,当一个页面从我们的服务器上送达的时候,事件的流程。

  • 首先运行PHP,它生成的HTML被送达给客户端。
  • 然后,将HTML交付给客户端,在PHP完成后,我想强调的是,一旦代码离开了服务器----PHP已经完成了,不能再访问了。
  • 然后,带JavaScript的HTML到达客户端,客户端可以在该HTML上执行JavaScript。

So really, the core thing to remember here is that HTTP is stateless. Once a request left the server, the server can not touch it. So, that leaves our options to:

  1. Send more requests from the client after the initial request is done.
  2. 在最初的请求中,对服务器的内容进行编码。

Solutions

这是你应该问自己的核心问题是。

我是在写网站还是在写申请?

网站主要是基于页面,页面加载时间需要尽可能快(例如--维基百科)。Web应用程序更多的是AJAX重度,需要进行大量的往返运行,以获得客户的快速信息(例如--股票仪表盘)。

Website

Sending more requests from the client after the initial request is done is slow as it requires more HTTP requests which have significant overhead. Moreover, it requires asynchronousity as making an AJAX request requires a handler for when it's complete.

I would not recommend making another request unless your site is an application for getting that information from the server.

You want fast response times which have a huge impact on conversion and load times. Making Ajax requests is slow for the initial uptime in this case and unneeded.

你有两种方法来解决这个问题

  • Set a cookie - cookies are headers sent in HTTP requests that both the server and client can read.
  • Encode the variable as JSON - JSON looks very close to JavaScript objects and most JSON objects are valid JavaScript variables.

Setting a cookie is really not very difficult, you just assign it a value:

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

Then, you can read it with JavaScript using 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是一个小数据的好东西。这就是跟踪服务经常做的事情。

一旦我们有了更多的数据,我们可以在JavaScript变量内用JSON来编码。

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

Assuming $value is json_encode able on the PHP side (it usually is). This technique is what Stack Overflow does with its chat for example (only using .NET instead of PHP).

Application

如果你正在编写一个应用程序----突然间,最初的加载时间并不总是和应用程序的持续性能一样重要,这时,将数据和代码分开加载就开始有了回报。

My answer here explains how to load data using AJAX in 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?
});

Now, the server just needs to contain a /your/url route/file that contains code that grabs the data and does something with it, in your case:

<$php
     ...
     $val = myService->getValue(); // Makes an API and database call
     echo json_encode($val); // Write it to the output
 $>

这样一来,我们的JavaScript文件就会询问数据并显示出来,而不是询问代码或布局。这样做更干净,而且随着应用的提升,开始有了回报。这也是更好的分离关注点,它可以在不涉及任何服务器端技术的情况下测试客户端代码,这也是另一个加分项。

Postscript: You have to be very aware of XSS attack vectors when you inject anything from PHP to JavaScript. It's very hard to escape values properly and it's context sensitive. If you're unsure how to deal with XSS, or unaware of it - please read this OWASP article, this one and this question.




Answer 3 yuikonnu


我通常在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('service');

            // Variable "service" now contains the value of $myService->getValue();
        });
    });
</script>

这个例子使用的是jQuery,但它可以改编成其他库或vanilla JavaScript。

You can read more about the dataset property here: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.dataset




Answer 4 Jessé Catrinck


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

json_encode()要求:

  • PHP 5.2.0或以上
  • $PHPVar encoded as UTF-8, Unicode.



Answer 5 Nishant Mendiratta


Simply use one of the following methods.

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

OR

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