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

本文翻译自:How do I pass variables and data from PHP to JavaScript?

Want to improve this post? 想要改善这篇文章吗? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. 提供此问题的详细答案,包括引文和答案正确的解释。 Answers without enough detail may be edited or deleted. 答案不够详细的答案可能会被编辑或删除。

I have a variable in PHP, and I need its value in my JavaScript code. 我在PHP中有一个变量,我的JavaScript代码中需要它的值。 How can I get my variable from PHP to JavaScript? 如何将变量从PHP转换为JavaScript?

I have code that looks like this: 我有看起来像这样的代码:

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

I have JavaScript code that needs val and looks along the lines of: 我有需要val JavaScript代码,其外观如下:

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

#1楼

参考:https://stackoom.com/question/1bc04/如何将变量和数据从PHP传递到JavaScript


#2楼

There are actually several approaches to do this. 实际上,有几种方法可以做到这一点。 Some require more overhead than others, and some are considered better than others. 有些需要比其他更多的开销,而有些则被认为比其他更好。

In no particular order: 没有特别的顺序:

  1. Use AJAX to get the data you need from the server. 使用AJAX从服务器获取所需的数据。
  2. Echo the data into the page somewhere, and use JavaScript to get the information from the DOM. 将数据回显到页面中的某个位置,然后使用JavaScript从DOM获取信息。
  3. Echo the data directly to JavaScript. 将数据直接回显到JavaScript。

In this post, we'll examine each of the above methods, and see the pros and cons of each, as well as how to implement them. 在本文中,我们将研究上述每种方法,并了解每种方法的优缺点以及如何实现它们。

1. Use AJAX to get the data you need from the server 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. 更好地分隔各层 -如果明天您停止使用PHP,并且想转向Servlet,REST API或其他服务,则无需更改很多JavaScript代码。
  • More readable - JavaScript is JavaScript, PHP is PHP. 更具可读性 -JavaScript是JavaScript,PHP是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. 允许异步数据传输 -从PHP获取信息可能很耗时间/资源。 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. 不能在标记上直接找到数据 -这意味着标记不会包含任何其他数据,只有JavaScript可以看到。

Cons 缺点

  • Latency - AJAX creates an HTTP request, and HTTP requests are carried over network and have network latencies. 延迟 -AJAX创建一个HTTP请求,并且HTTP请求通过网络承载并具有网络延迟。
  • State - Data fetched via a separate HTTP request won't include any information from the HTTP request that fetched the HTML document. 状态 -通过单独的HTTP请求获取的数据将不包含来自获取HTML文档的HTTP请求的任何信息。 You may need this information (eg, if the HTML document is generated in response to a form submission) and, if you do, will have to transfer it across somehow. 您可能需要此信息(例如,如果HTML文档是为响应表单提交而生成的),并且,如果需要,则必须以某种方式进行传输。 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. 如果您排除了将数据嵌入页面的能力(如果使用此技术,则必须具有该能力),那么这将使您只能使用cookie /会话,这可能会受到竞争条件的影响。

Implementation Example 实施实例

With AJAX, you need two pages, one is where PHP generates the output, and the second is where JavaScript gets that output: 使用AJAX,您需要两个页面,一个页面是PHP生成输出的位置,第二个页面是JavaScript获取该输出的位置:

get-data.php 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 (or whatever the actual page is named like) 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. 当文件完成加载时,两个文件的上述组合将提醒42

Some more reading material 更多阅读材料

2. Echo the data into the page somewhere, and use JavaScript to get the information from the DOM 2.将数据回显到页面中的某个位置,然后使用JavaScript从DOM获取信息。

This method is less preferable to AJAX, but it still has its advantages. 这种方法不如AJAX更好,但仍具有其优点。 It's still relatively separated between PHP and JavaScript in a sense that there is no PHP directly in the JavaScript. 它仍然PHP和JavaScript之间的感觉,有没有直接PHP在JavaScript 相对分离。

Pros 优点

  • Fast - DOM operations are often quick, and you can store and access a lot of data relatively quickly. 快速 -DOM操作通常很快,因此您可以相对快速地存储和访问许多数据。

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. 潜在的非语义标记 -通常,发生的事情是您使用某种<input type=hidden>来存储信息,因为从inputNode.value获取信息更容易,但是这样做意味着您在其中没有意义您的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. HTML具有用于有关文档数据的<meta>元素,而HTML 5引入了data-*属性,专门用于data-*属性,该JavaScript可以与特定元素关联。
  • 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. 使源代码变脏-PHP生成的数据直接输出到HTML源代码,这意味着您将获得更大,更集中的HTML源代码。
  • Harder to get structured data - Structured data will have to be valid HTML, otherwise you'll have to escape and convert strings yourself. 很难获得结构化数据 -结构化数据必须是有效的HTML,否则您必须自己转义和转换字符串。
  • Tightly couples PHP to your data logic - Because PHP is used in presentation, you can't separate the two cleanly. 将PHP与数据逻辑紧密结合 -由于在演示文稿中使用了PHP,因此您无法将两者完全分开。

Implementation Example 实施实例

With this, the idea is to create some sort of element which will not be displayed to the user, but is visible to JavaScript. 这样做的目的是创建某种元素,该元素不会显示给用户,但对JavaScript可见。

index.php 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. Echo the data directly to JavaScript 3.将数据直接回显到JavaScript

This is probably the easiest to understand. 这可能是最容易理解的。

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. 不污染源 -变量直接输出到JavaScript,因此DOM不受影响。

Cons 缺点

  • Tightly couples PHP to your data logic - Because PHP is used in presentation, you can't separate the two cleanly. 将PHP与数据逻辑紧密结合 -由于在演示文稿中使用了PHP,因此您无法将两者完全分开。

Implementation Example 实施实例

Implementation is relatively straightforward: 实施相对简单:

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

Good luck! 祝好运!


#3楼

I'm going to try a simpler answer: 我将尝试一个简单的答案:

Explanation of the problem 问题说明

First, let's understand the flow of events when a page is served from our server: 首先,让我们了解从服务器提供页面时的事件流:

  • First PHP is run, it generates the HTML that is served to the client. 首先运行PHP,它将生成供客户端使用的HTML。
  • Then, the HTML is delivered to the client, after PHP is done with it, I'd like to emphasize that once the code leaves the server - PHP is done with it and can no longer access it. 然后,将HTML交付给客户端,在PHP完成后,我想强调一下,一旦代码离开服务器,PHP就完成了,并且无法再访问它。
  • Then, the HTML with JavaScript reaches the client, which can execute JavaScript on that HTML. 然后,带有JavaScript的HTML到达客户端,客户端可以在该HTML上执行JavaScript。

So really, the core thing to remember here is that HTTP is stateless . 因此,实际上,要记住的核心是HTTP是无状态的 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. Encode what the server had to say in the initial request. 编码服务器在初始请求中必须说的内容。

Solutions 解决方案

That's the core question you should be asking yourself is: 您应该问自己的核心问题是:

Am I writing a website or an application? 我在写网站还是应用程序?

Websites are mainly page based, and the page load times needs to be as fast as possible (for example - Wikipedia). 网站主要基于页面,并且页面加载时间需要尽可能快(例如Wikipedia)。 Web applications are more AJAX heavy and perform a lot of round trips to get the client fast information (for example - a stock dashboard). 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. 初始请求完成后,从客户端发送更多请求的速度慢,因为它需要更多具有大量开销的HTTP请求。 Moreover, it requires asynchronousity as making an AJAX request requires a handler for when it's complete. 而且,它要求异步,因为发出AJAX请求需要一个处理程序以完成请求。

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. 在这种情况下,发出Ajax请求对于初始正常运行时间很慢,因此是不需要的。

You have two ways to tackle the issue 您有两种方法可以解决此问题

  • Set a cookie - cookies are headers sent in HTTP requests that both the server and client can read. 设置cookie -cookie是服务器和客户端均可读取的HTTP请求中发送的标头。
  • Encode the variable as JSON - JSON looks very close to JavaScript objects and most JSON objects are valid JavaScript variables. 将变量编码为JSON -JSON看起来非常接近JavaScript对象,并且大多数 JSON对象都是有效的JavaScript变量。

Setting a cookie is really not very difficult, you just assign it a value: 设置cookie确实不是很困难,您只需为其分配一个值即可:

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 : 然后,您可以使用JavaScript使用document.cookie进行读取

Here is a short hand rolled parser, but the answer I linked to right above this has better tested ones: 这是一个简短的手动解析器,但是我链接到此上方的答案得到了更好的测试:

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 are good for a little data. Cookies有助于获取少量数据。 This is what tracking services often do. 这就是跟踪服务经常做的事情。

Once we have more data, we can encode it with JSON inside a JavaScript variable instead: 一旦有了更多数据,我们就可以使用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). 假设$value在PHP端能够json_encode (通常是)。 This technique is what Stack Overflow does with its chat for example (only using .NET instead of PHP). 例如,此技术就是Stack Overflow对其聊天进行的处理(仅使用.NET而不是PHP)。

Application 应用

If you're writing an application - suddenly the initial load time isn't always as important as the ongoing performance of the application, and it starts to pay off to load data and code separately. 如果您正在编写应用程序-突然,初始加载时间并不总是与应用程序的持续性能一样重要,并且开始获得回报以分别加载数据和代码。

My answer here explains how to load data using AJAX in JavaScript: 在这里的答案说明了如何在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();

Or with jQuery: 或使用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: 现在,服务器只需要包含一个/your/url路由/文件,其中包含可获取数据并对其进行处理的代码,在您的情况下:

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

This way, our JavaScript file asks for the data and shows it rather than asking for code or for layout. 这样,我们的JavaScript文件会要求数据并显示它,而不是要求代码或布局。 This is cleaner and starts to pay off as the application gets higher. 这是更干净的应用程序,随着应用程序变得更高,它开始获得回报。 It's also better separation of concerns and it allows testing the client side code without any server side technology involved which is another plus. 它还可以更好地分离关注点,并且它允许测试客户端代码而无需涉及任何服务器端技术,这是另一个优点。

Postscript: You have to be very aware of XSS attack vectors when you inject anything from PHP to JavaScript. 附言:从PHP到JavaScript注入任何东西时,您必须非常了解XSS攻击媒介。 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 . 如果您不确定如何处理XSS,或者不知道它-请阅读此文章OWASP这个这个问题


#4楼

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

It doesn't work because $val is undefined as far as JavaScript is concerned, ie the PHP code did not output anything for $val . 它不起作用,因为就JavaScript而言, $val是未定义的,即PHP代码没有为$val输出任何内容。 Try viewing the source in your browser and here is what you'll see: 尝试在浏览器中查看源代码,这是您将看到的内容:

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

And

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

This doesn't work because PHP will try to treat myPlugin as a constant and when that fails it will try to treat it as the string 'myPlugin' which it will try to concatenate with the output of the PHP function start() and since that is undefined it will produce a fatal error. 这是行不通的,因为PHP会尝试将myPlugin视为一个常量,如果失败,它将尝试将其视为字符串'myPlugin' ,它将尝试与PHP函数start()的输出连接起来,因为未定义,将产生致命错误。

And

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

While this is most likely to work, since the PHP code is producing valid JavaScript with the expected arguments, if it fails, chances are it's because myPlugin isn't ready yet. 尽管这很可能有效,但是由于PHP代码使用预期的参数生成有效的JavaScript,但如果失败,则可能是因为myPlugin尚未准备好。 Check your order of execution. 检查您的执行顺序。

Also you should note that the PHP code output is insecure and should be filtered with json_encode() . 您还应该注意,PHP代码输出是不安全的,应使用json_encode()进行过滤。

EDIT 编辑

Because I didn't notice the missing parenthesis in myPlugin.start(<?=$val?> :-\\ 因为我没有注意到myPlugin.start(<?=$val?> :-\\

As @Second Rikudo points out, for it to work correctly $val would need to contain the closing parenthesis, for example: $val="42);" 正如@Second Rikudo指出的那样,要使其正常工作, $val将需要包含右括号,例如: $val="42);"

Meaning that the PHP will now produce myPlugin.start(42); 这意味着PHP现在将产生myPlugin.start(42); and will work as expected when executed by the JavaScript code. 并在由JavaScript代码执行时可以按预期工作。


#5楼

I usually use data-* attributes in HTML. 我通常在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');

            // Service variable now contains the value of $myService->getValue();
        });
    });
</script>

This example uses jQuery, but it can be adapted for another library or vanilla JavaScript. 本示例使用jQuery,但可以将其改编为另一个库或原始JavaScript。

You can read more about the dataset property here: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.dataset 您可以在此处阅读有关数据集属性的更多信息: https : //developer.mozilla.org/en-US/docs/Web/API/HTMLElement.dataset


#6楼

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

json_encode() requires: json_encode()要求:

  • PHP 5.2.0 or more PHP 5.2.0或更高
  • $PHPVar encoded as UTF-8, Unicode. $PHPVar编码为UTF-8,Unicode。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值