我有一个变量在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>

当前回答

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

它不起作用,因为就JavaScript而言,$val是未定义的,即PHP代码没有为$val输出任何东西。试着在浏览器中查看源代码,下面是你将看到的:

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

And

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

这并不管用,因为PHP将尝试将myPlugin视为常量,当失败时,它将尝试将其视为字符串'myPlugin',它将尝试与PHP函数start()的输出连接,由于这是未定义的,它将产生一个致命的错误。

And

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

虽然这是最有可能工作的,因为PHP代码生成了带有预期参数的有效JavaScript,但如果失败,很可能是因为myPlugin还没有准备好。检查你的执行顺序。

您还应该注意到,PHP代码输出是不安全的,应该使用json_encode()进行过滤。

EDIT

因为我没有注意到myPlugin.start(<?=$val?>: \

正如@Second Rikudo指出的那样,要正确工作,$val需要包含右括号,例如:$val="42);"

这意味着PHP现在将生成myPlugin.start(42);并在JavaScript代码执行时按预期工作。

其他回答

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

排名不分先后:

使用AJAX从服务器获取所需的数据。 将数据回显到页面的某处,并使用JavaScript从DOM获取信息。 将数据直接回显到JavaScript。

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

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

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

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>
    fetch("get-data.php")
        .then((response) => {
            if(!response.ok){ // Before parsing (i.e. decoding) the JSON data,
                              // check for any errors.
                // In case of an error, throw.
                throw new Error("Something went wrong!");
            }

            return response.json(); // Parse the JSON data.
        })
        .then((data) => {
             // This is where you handle what to do with the response.
             alert(data); // Will alert: 42
        })
        .catch((error) => {
             // This is where you handle errors.
        });
</script>
<!-- snip -->

上述两个文件的组合将在文件加载完成时提醒42。

更多的阅读材料

使用Fetch API 如何从异步调用返回响应?

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

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

Pros

快速——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. 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.将数据直接回显到JavaScript

这可能是最容易理解的。

Pros

非常容易实现——它需要非常少的实现和理解。 不会弄脏源代码——变量直接输出到JavaScript,所以DOM不受影响。

Cons

将PHP与数据逻辑紧密结合——因为PHP用于表示,所以不能将两者清晰地分开。

实现示例

实现相对简单:

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

好运!

试试这个:

<?php
    echo "<script> var x = " . json_encode($phpVariable) . "</script>";
?>

--

-在尝试了一段时间之后

虽然它可以工作,但是它降低了性能。因为PHP是服务器端脚本,而JavaScript是用户端。

<?php

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

    echo "
        <script>
            myPlugin.start({$val});
        </script> ";

?>

这是在2022年对我有用的,我使用这个解决方案来获取当前用户的电子邮件

我使用PHP创建了一个短代码,并将其添加到PHP .function:

function my_get_current_user_email(){
    $current_user = wp_get_current_user();
    $email = $current_user->user_email;
    return $email;  
} 
add_shortcode( 'get_email', 'my_get_current_user_email');

然后使用div来包装短代码:

 <div id="target-content" style="display: none;">
[get_email]
 </div>

最后,使用JavaScript访问Div的内容:

const databox = document.getElementById("target-content");
const dataContent = databox.textContent;
console.log(dataContent)

这工作完美地为我想要的,我希望它也会为你工作。

我假设要传输的数据是一个字符串。

正如其他评论者所述,AJAX是一种可能的解决方案,但缺点大于优点:它有延迟,并且更难编程(它需要代码来检索服务器端和客户端值),而更简单的转义函数应该就足够了。

所以,我们又回到了逃避。如果您首先将源字符串编码为UTF-8, json_encode($string)就可以工作,因为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>";

然而,你不能在常规JavaScript代码上使用htmlspecialchars(代码包含在<script>…> < /脚本标签)。这使得使用这个函数容易出错,在编写事件代码时忘记htmlspecialchars结果。

可以编写一个不存在该问题的函数,并且可以在事件和常规JavaScript代码中使用,只要始终用单引号或双引号括起事件。以下是我的建议,要求它们在双引号中(我更喜欢这样):

<?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>';