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

IT技术 javascript php
2021-01-04 21:46:43

我在 PHP 中有一个变量,我需要在我的 JavaScript 代码中使用它的值。如何将我的变量从 PHP 获取到 JavaScript?

我有如下代码:

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

在同一页面上,我有 JavaScript 代码需要将$val变量的值作为参数传递:

<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>
6个回答

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

没有特定的顺序:

  1. 使用 AJAX 从服务器获取您需要的数据。
  2. 将数据回显到页面某处,并使用 JavaScript 从 DOM 中获取信息。
  3. 将数据直接回显到 JavaScript。

在这篇文章中,我们将检查上述每种方法,并了解每种方法的优缺点,以及如何实现它们。

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

这种方法被认为是最好的,因为您的服务器端和客户端脚本是完全独立的

优点

  • 更好的层间分离- 如果明天您停止使用 PHP,并希望转向 servlet、REST API 或其他一些服务,您不必更改大部分 JavaScript 代码。
  • 更具可读性- JavaScript 是 JavaScript,PHP 是 PHP。如果不混合这两者,您会在两种语言上获得更易读的代码。
  • 允许异步数据传输- 从 PHP 获取信息可能会耗费大量时间/资源。有时您只是不想等待信息,加载页面,并让信息随时到达。
  • 数据不是直接在标记上找到的——这意味着你的标记没有任何额外的数据,只有 JavaScript 才能看到它。

缺点

  • 延迟- AJAX 创建一个 HTTP 请求,HTTP 请求通过网络传输并具有网络延迟。
  • 状态- 通过单独的 HTTP 请求获取的数据不会包含来自获取 HTML 文档的 HTTP 请求的任何信息。您可能需要此信息(例如,如果 HTML 文档是为响应表单提交而生成的),并且如果您这样做,则必须以某种方式将其传输。如果您排除了在页面中嵌入数据的可能性(如果您使用这种技术,您就会这样做),那么这会将您限制在可能受竞争条件影响的 cookie/会话中。

实现示例

使用 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当文件加载完成时,上述两个文件的组合将发出警报

更多阅读材料

2. 将数据回显到页面某处,并使用 JavaScript 从 DOM 中获取信息

这种方法不如 AJAX 好,但它仍然有它的优点。某种意义上说,PHP 和 JavaScript 之间还是相对分离的,JavaScript 中没有直接使用 PHP。

优点

  • 快速- DOM 操作通常很快,您可以相对快速地存储和访问大量数据。

缺点

  • 潜在的非语义标记- 通常,发生的情况是您使用某种形式<input type=hidden>来存储信息,因为从 中获取信息更容易inputNode.value,但这样做意味着您的 HTML 中有一个毫无意义的元素。HTML 具有<meta>用于有关文档的数据元素,而 HTML 5 引入data-*了专门用于使用 JavaScript 读取的数据属性,这些属性可以与特定元素相关联。
  • 弄脏源- PHP 生成的数据会直接输出到 HTML 源,这意味着您将获得更大且不那么集中的 HTML 源。
  • 更难获得结构化数据- 结构化数据必须是有效的 HTML,否则你必须自己转义和转换字符串。
  • 将 PHP 与您的数据逻辑紧密结合- 因为 PHP 用于演示,所以您无法将两者完全分开。

实现示例

有了这个,我们的想法是创建某种不会向用户显示但对 JavaScript 可见的元素。

索引.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

这可能是最容易理解的。

优点

  • 非常容易实现- 只需很少的时间来实现和理解。
  • 不脏源- 变量直接输出到 JavaScript,因此 DOM 不受影响。

缺点

  • 将 PHP 与您的数据逻辑紧密结合- 因为 PHP 用于演示,所以您无法将两者完全分开。

实现示例

实现相对简单:

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

祝你好运!

发出 AJAX 请求时异步引入的显着开销和代码复杂性如何?在 JavaScript 轻量级网站上工作时 - 发出 AJAX 请求很乏味,而且不是最佳实践。
2021-02-10 21:46:43
“PHP 没有简单的 JavaScript 转义函数”——有什么问题json_encode
2021-02-11 21:46:43
@BenjaminGruenbaum — JS 无效 JSON 无关紧要。我想不出任何在作业右侧的 JavaScript 中无效的 JSON。
2021-02-13 21:46:43
@SecondRikudo 在方法 3 中,该示例可以杀死网站。例子:<?php $output = '<!--<script>'; echo json_encode($output); ?>有关详细信息,请参阅此问题解决方案:JSON_HEX_TAG用于转义<>(需要 PHP 5.3.0)。
2021-03-01 21:46:43
我不同意“非常不安全!!” 和“结构化数据很难”。将数据编码为 JSON(毕竟是JavaScript Object Notation),然后就可以了!
2021-03-04 21:46:43

我通常在 HTML 中使用 data-* 属性。

<div
    class="service-container"
    data-service="<?= htmlspecialchars($myService->getValue()) ?>"
>

</div>

<script>
    $(document).ready(function() {
        $('.service-container').each(function() {
            var container = $(this);
            var service = container.data('service');

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

此示例使用 jQuery,但它可以适用于其他库或 vanilla JavaScript。

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

@asdasd — 是的,我只是在解决您答案中的代码的具体问题,而不是一般情况。
2021-02-17 21:46:43
@Quentin 您应该转义所有输出,除非输出是 HTML 本身。
2021-02-19 21:46:43
对于大多数人来说,这个答案实际上对我来说似乎是最简单的。你赢得了一个赞!
2021-02-22 21:46:43
我同意,不想过度分析和实施一个简单问题的奇特解决方案。这种方法将 PHP 与 Javascript 分开,因此 PHP 仍然只生成 HTML,而 Javascript 可以在 PHP 文件的外部。
2021-02-23 21:46:43
我同意这是最好的选择。它解决了所有安全问题,没有延迟。您可以将 JS 完全排除在您的 HTML 页面之外。HTML 需要由应用程序服务器提供服务,但 JS(和 CSS)不需要。它也更具语义。
2021-02-26 21:46:43

我将尝试一个更简单的答案:

问题说明

首先,让我们了解从我们的服务器提供页面时的事件流:

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

所以真的,这里要记住的核心是HTTP 是无状态的一旦请求离开服务器,服务器就不能再接触它。所以,我们的选择是:

  1. 在初始请求完成从客户端发送更多请求
  2. 对服务器在初始请求中所说的内容进行编码。

解决方案

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

我是在写网站还是应用程序?

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

网站

在初始请求完成后从客户端发送更多请求很慢,因为它需要更多具有显着开销的 HTTP 请求。此外,它需要异步性,因为 AJAX 请求在完成时需要一个处理程序。

除非您的站点是从服务器获取该信息的应用程序否则建议再次发出请求

您需要快速响应时间,这会对转换和加载时间产生巨大影响。在这种情况下,发出 Ajax 请求的初始正常运行时间很慢,而且是不必要的。

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

  • 设置 cookie - cookie 是服务器和客户端都可以读取的 HTTP 请求中发送的标头。
  • 将变量编码为 JSON - JSON 看起来非常接近 JavaScript 对象,并且大多数JSON 对象都是有效的 JavaScript 变量。

设置一个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 },{});
alert(cookies["MyCookie"]); // Value set with PHP.

Cookies 适用于少量数据。这就是跟踪服务经常做的事情。

一旦我们有更多数据,我们可以在 JavaScript 变量中使用 JSON 对其进行编码:

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

假设$valuejson_encode能够在PHP端(通常是这样)。这种技术就是 Stack Overflow 对其聊天所做的事情(仅使用 .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 database call
header("Content-Type: application/json"); // Advise client of response type
echo json_encode($val); // Write it to the output

这样,我们的 JavaScript 文件会要求数据并显示它,而不是要求代码或布局。这更干净,并且随着应用程序变得更高而开始得到回报。它也是更好的关注点分离,它允许在不涉及任何服务器端技术的情况下测试客户端代码,这是另一个优点。

后记:当您将任何东西从 PHP 注入到 JavaScript 时,您必须非常了解 XSS 攻击媒介。这是非常难以逃脱正确的value观和它的上下文敏感的。如果您不确定如何处理 XSS,或者不知道它 - 请阅读这篇 OWASP 文章这篇文章这个问题

@cHao 更普遍 - 编码被定义为一系列字符,概念对象的存在是一个哲学问题。但是,有诸如 JSON 对象之类的东西,它们是由 JSON 语法定义的。{}是一个有效的 JSON 对象 - 请参阅json.org
2021-02-09 21:46:43
但是,如果您使用该定义,那么所有“JSON 对象”在 JS 中都是有效的。
2021-02-12 21:46:43
@cHao 注意微妙之处:JavaScript 有对象的概念, JSON 有对象的概念——它们不一样。当人们误用术语“JSON 对象”时,他们指的是 JS 对象,而在 JavaScript 中,JSON 用作数据序列化格式,JSON 对象出现在字符串中(有点像服务器端语言中的 SQL 查询)。但是,在这个答案中,JSON 方法依赖于这样一个事实,即大多数JSON 对象也是有效的 JavaScript 对象,因此我们将 JSON 对象写入 JavaScript 代码。
2021-02-17 21:46:43
@cHao 啊,但我昨天已经预见到了这一刻:) stackoverflow.com/questions/23752156/...
2021-02-24 21:46:43
好的,你让我到了。:) 不过它还是安全的;PHP 的默认行为是转义这些字符(以及其他非 ASCII 字符),因此它们永远不会进入输出,除了 as\u2028等。您必须明确告诉它不要这样做。
2021-03-05 21:46:43
<script>
  var jsvar = <?php echo json_encode($PHPVar); ?>;
</script>

json_encode() 要求:

  • PHP 5.2.0 或更高
  • $PHPVar 编码为 UTF-8、Unicode。
您真棒!一行代码的答案总是最好的!
2021-03-05 21:46:43

只需使用以下方法之一。

<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>
简单更好
2021-02-09 21:46:43
这对现有答案有什么value?
2021-02-17 21:46:43
@AnkitPrajapati 尝试通过检查文档就绪状态来访问它。使用以下脚本。 document.onreadystatechange = () => { if (document.readyState === 'complete') { // document ready alert(js_variable) } };
2021-02-23 21:46:43
可能这是一个愚蠢的问题,但我对 PHP 世界完全陌生。一旦我们在 .php 文件中编写了上面的代码,我如何访问我的 JavaScript 文件或我的“index.html”文件中的“js_variable”?
2021-03-02 21:46:43
保持简单和直接。对于所有有很多时间深入解释的用户
2021-03-04 21:46:43