提问



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


我的代码看起来像这样:


<?php
     ...
     $val = $myService->getValue(); // makes an api and db call
?>


我有需要val的JavaScript代码,看起来如下:


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

最佳参考


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


没有特别的顺序:



  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


更多阅读材料




  • 使用XMLHttpRequest - MDN

  • XMLHttpRequest对象引用 - MDN

  • 如何从异步调用中返回响应?



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



这种方法不如AJAX优选,但它仍然有其优点。从某种意义上说,在PHP和JavaScript之间仍然存在相对分开。在[[...]] [86] [86]


赞成




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



缺点




  • 潜在的非语义标记 - 通常情况下,您使用某种<input type=hidden>来存储信息,因为它更容易从inputNode.value中获取信息]],但这样做意味着你的HTML中有一个没有意义的元素.HTML有<meta>元素用于文档的数据,HTML 5引入了data-*属性,专门用于读取JS的数据与特定元素相关联。

  • Dirties up the Source - PHP生成的数据直接输出到HTML源代码,这意味着您可以获得更大,更少关注的HTML源代码。

  • 难以获取结构化数据 - 结构化数据必须是有效的HTML,否则您将不得不自行转义并转换字符串。

  • 将PHP与您的数据逻辑紧密结合 - 因为在演示文稿中使用了PHP,所以您不能干净利落地将它们分开。



实施例



有了这个,我们的想法是创建一些不会向用户显示但是对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



这可能是最容易理解的,也是最恐怖的。除非你知道自己在做什么,否则不要这样做。


赞成




  • 非常容易实现 - 实现这一点非常少,并且理解。

  • 不脏源 - 变量直接输出到JavaScript,因此DOM不受影响。



缺点




  • 不安全 - PHP没有简单的JavaScript转义功能,并且实现起来并不重要。特别是在使用用户输入时,你非常易受第二层注射。有争议见评论

  • 将PHP与您的数据逻辑紧密结合 - 因为在演示文稿中使用了PHP,所以您不能干净利落地将它们分开。

  • 结构化数据很难 - 你可以做JSON ......有点儿。但是XML和HTML需要特别注意。



实施例



实施相对简单:


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


祝你好运!

其它参考1


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


问题说明



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



  • 首先运行PHP,它会生成提供给客户端的HTML。

  • 然后,在PHP完成之后,HTML被传递给客户端,我想强调的是,一旦代码离开服务器 - PHP就完成了它,并且无法再访问它。

  • 然后,带有JavaScript的HTML到达客户端,可以在该html上执行JS。



所以,真正需要记住的核心是 HTTP是无状态的。请求离开服务器后,服务器无法触及它。所以,这留下了我们的选择:



  1. 在初始请求完成后,从客户端发送更多请求。

  2. 对初始请求中服务器必须说的内容进行编码。



解决方案



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


我在撰写网站或申请表吗?



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


网站



在初始请求完成后从客户端发送更多请求是,因为它需要更多具有显着开销的HTTP请求。此外,它需要 asynchronousity ,因为使AJAX请求需要处理程序才能完成。


我不建议发出另一个请求,除非您的网站是用于从服务器获取该信息的应用程序。


您需要快速响应时间,这会对转换和加载时间产生巨大影响。在这种情况下,对于初始正常运行时间而言,制作ajax请求的速度很慢且不需要。


您有两种方法可以解决这个问题



  • 设置Cookie - Cookie是HTTP请求中发送的标头,服务器和客户端都可以读取这些标头。

  • 将变量编码为JSON - JSON看起来非常接近JavaScript对象,而大多数 JSON对象都是有效的JavaScript变量。



设置一个cookie真的不是很难,你只需给它一个值:[88]


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


然后,您可以使用document.cookie使用JavaScript阅读它:


这是一个简短的手动解析器,但我在上面链接的答案有更好的测试:


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适用于少量数据。这就是跟踪服务经常做的事情。


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


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


假设$value json_encode能够在PHP端(通常是)。这种技术就是StackOverflow的聊天功能(例如只使用.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 db call
 echo json_encode($val); // write it to the output
 $>


这样,我们的JS文件会询问数据并显示它,而不是要求代码或布局。随着应用程序变得更高,这更清除并开始获得回报。它也更好地分离了关注点,它允许测试客户端代码,而不涉及任何服务器端技术,这是另一个优点。


后记:当您从PHP注入任何内容时,您必须非常了解XSS攻击媒介。它非常难以正确地逃避值并且它对上下文敏感。如果你不确定如何处理XSS,或者不知道它 - 请阅读这篇OWASP文章,这个和这个问题。[91] [92]

其它参考2


我通常在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>


这个例子使用jQuery但可以适用于另一个库或vanilla Javascript。


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

其它参考3


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


json_encode()需要:



  • PHP 5.2.0或更高版本

  • $PHPVar编码为UTF-8,Unicode。


其它参考4


只需使用以下方法之一。


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

其它参考5


我非常喜欢Wordpress使用它的enqueue和localize函数的方式,所以在这个模型之后,我编写了一个简单的类,用于根据脚本依赖关系将脚本放入页面,以及为脚本提供额外的数据。[95] [96]


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。
自定义脚本的附加数据位于新的脚本块内并放置在它的前面,它包含mydata对象,该对象保存其他数据,现在可用于自定义脚本。

其它参考6


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


它没有用,因为$val在javascript方面是未定义的,即php没有为$val输出任何内容。尝试在浏览器中查看源代码,这就是你将看到的内容:


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





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


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





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


虽然这很有可能工作,因为php正在生成带有预期参数的有效javascript,如果它失败了,很可能是因为myPlugin还没有准备好。检查你的执行顺序。


另外你应该注意到php out put是不安全的,应该用json_encode()过滤


修改


因为我没有注意到myPlugin.start(<?=$val?>中缺少的括号: - \\


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


这意味着php现在将生成myPlugin.start(42);并且在由javascript执行时将按预期工作

其它参考7


尝试这个


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


-


- 尝试了一段时间后
虽然它有效,但它会降低性能。因为php是服务器端脚本,而javascript是用户端。

其它参考8


我已经提出了一种使用PHP分配JavaScript变量的简单方法。


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


完整的教程可以在[97]找到


例:


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


她是JS代码


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

其它参考9


这是一个我没看到张贴作为选项。它类似于使用ajax,但明显不同。


首先,将脚本的源代码直接设置为PHP文件。


<script type="text/javascript" src="url_to_your_php_file.php" /></script>


您甚至可以将变量传递回PHP文件,例如:


<script type="text/javascript" src="url_to_your_php_file.php?var1=value1" /></script>


然后在your_php_file.php中:


<?php
// THIS IS A SIMPLE EXAMPLE
// it demonstrates one method of using the src attribute to link
// to a PHP file which can generate javascripts dynamically
// and share data between PHP and javascript
// you may take this learning example and develop it further
// relying on your own coding skills for validating data
// and avoiding errors, of course
header( 'content-type: text/javascript' );

// if you pass a $_GET variable from the javascript
// you should add code to validate your $_GET variable(s)

// you can add code to query a database
// using $_GET['var1'] or some other criteria

// you can add simple variable assignments
$value = 'some value';

// for the OP's needs (assumes the class object has been defined)
$val = $myService->getValue();

?>
function name() {
    // pay attention because you need to use quotes properly
    // and account for possible quotes in the variable strings
    // to avoid both php and javascript errors
    // example assumes $val has been returned as a string
    // validate $val as needed using your method of choice
    var example1 = '<?php echo '"' . $val . '"'; ?>';
    var example2 = '<?php echo '"' . $value . '"'; ?>';
    var example3 = '<?php echo '"some other data"'; ?>';
    alert( example1 + ' / ' + example2 );
}
<?php
// you may even want to include additional files (.php or .js, etc)
@include 'local_path_to_some_other_js_file.js';
@include 'local_path_to_some_other_php_file.php';

exit;
?>

其它参考10


这是诀窍:


<?php 
 $name = 'PHP variable';
 echo '<script>';
 echo 'var name = ' . json_encode($name) . ';';
 echo '</script>';
<?
<script>
  console.log("i am everywhere " + name);
</script>

其它参考11


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


正如其他评论者所说,AJAX是一种可能的解决方案,但缺点超过了优点:它有延迟并且编程更难(它需要代码来检索服务器端和客户端的值),当更简单时逃避功能应该足够了。


所以,我们回到逃避。json_encode($string)工作如果你将源字符串编码为UTF-8,如果它还没有,因为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>";


但是,您不能在常规JS代码上使用htmlspecialchars(<script> ... </script>标签中包含的代码。)这使得此函数容易出错,忘记[[htmlspecialchars编写事件代码时的结果。


编写一个没有这个问题的函数是可能的,并且可以在事件和常规JS代码中使用,只要你将事件总是用单引号括起来,或者总是用双引号括起来。这是我的建议,要求他们用双引号(我更喜欢):


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

其它参考12


根据你的代码


<$php
     $val = $myService->getValue(); // makes an api and db call
     echo '<span id="value">'.$val.'</span>';
$>


现在你可以使用DOM获取价值,使用span id的innerHTML,在这种情况下你不需要对服务器,或ajax或任何其他东西进行任何调用。


你的页面将使用php打印它,你的javascript将使用DOM获得价值。

其它参考13


让我们说你的变量总是整数,在这种情况下这更容易


<?PHP
$number = 4;

echo '<script>';
echo 'var number = ' . $number . ';';
echo 'alert(number);';
echo '</script>';

?>


输出:


<script>var number = 4;alert(number);</script>


让我们说你的变量不是一个整数,但如果你尝试上面的方法你会得到这样的东西:


<script>var number = abcd;alert(number);</script>


但在javascript中这是一个语法错误。


所以在php中我们有一个函数调用json_encode,它将字符串编码为json对象。


<?PHP
$number = 'abcd';

echo '<script>';
echo 'var number = ' . json_encode($number) . ';';
echo 'alert(number);';
echo '</script>';

?>


因为abcd在json中它是"abcd",所以它看起来像这样:


<script>var number = "abcd";alert(number);</script>


您可以对数组使用相同的方法:


<?PHP
$details = [
'name' => 'supun',
'age' => 456,
'weight' => '55'
];

echo '<script>';
echo 'var details = ' . json_encode($details) . ';';
echo 'alert(details);';
echo 'console.log(details);';
echo '</script>';

?>


你的javascript看起来像这样:


<script>var details = {"name":"supun","age":456,"weight":"55"};alert(details);console.log(details);</script>


控制台输出


[98]

其它参考14


这是我的方式(有很多方法):



  1. 将数据转换为 JSON

  2. 调用 AJAX 以接收 JSON 文件

  3. 将 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);}
       }
    }

其它参考15


    <?php 
    $your_php_variable= 22;
    echo "<script type='text/javascript'>var your_javascript_variable = $your_php_variable;</script>";  
    ?>


这将有效。它只是分配一个javascript变量,然后传递一个现有的php变量的值。由于php在这里写了javascript行,它具有php变量的值,可以直接传递它。

其它参考16


对于那些使用下面的代码有问题的人,它继续显示<?php echo $username?>或类似的东西。通过添加这个AddType application/x-httpd-php .html .htm来编辑mime_module部分中的httpd.conf它可能会默认禁用。


   <?php
        $username = 1;
    ?>

    <script type="text/javascript">
        var myData = <?php echo $username ?>;
        console.log(myData);
        alert(myData);
    </script>