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

当前回答

试试这个:

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

--

-在尝试了一段时间之后

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

其他回答

我非常喜欢WordPress使用其enqueue和本地化函数的工作方式,因此遵循这个模型,我编写了一个简单的类,根据脚本依赖关系将脚本放入页面,并为脚本提供额外的数据。

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>

不管脚本'jquery'是在'jquery-ui'之后排队,它是在'jquery-ui'中定义的,它依赖于'jquery',所以它是在'jquery-ui'之前打印的。 额外的数据为'自定义脚本'是在一个新的脚本块,并放在它前面,它包含mydata对象,持有额外的数据,现在可用于'自定义脚本'。

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

排名不分先后:

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

好运!

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

正如其他评论者所述,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>';

将数据转换为JSON 调用AJAX来接收JSON文件 将JSON转换为Javascript对象

例子:

步骤1

<?php

   $servername = "localhost";
   $username = "";
   $password = "";
   $dbname = "";
   $conn = new mysqli($servername, $username, $password, $dbname);

   if ($conn->connect_error) {
      die("Connection failed: " . $conn->connect_error);
   } 

   $sql = "SELECT id, name, image FROM phone";
   $result = $conn->query($sql);

   while($row = $result->fetch_assoc()){ 
      $v[] = $row;    
   }

  echo json_encode($v);

  $conn->close();
?>

步骤2

function showUser(fnc) {
   var xhttp = new XMLHttpRequest();

   xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
         // STEP 3    
         var p = JSON.parse(this.responseText);
      }
   }
}

我想出了一个简单的方法来分配JavaScript变量使用PHP。

它使用HTML5数据属性来存储PHP变量,然后在页面加载时分配给JavaScript。

例子:

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

下面是JavaScript代码

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");
}