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

当前回答

我非常喜欢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对象,持有额外的数据,现在可用于'自定义脚本'。

其他回答

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代码执行时按预期工作。

我通常在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,但是它可以用于其他库或普通JavaScript。

你可以在这里阅读更多关于dataset属性的信息:https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.dataset

根据你的代码

<$php
     $val = $myService->getValue(); // Makes an API and database call
     echo '<span id="value">'.$val.'</span>';
$>

现在你可以使用DOM,使用innerHTML (span id)来获取值,在这种情况下你不需要调用任何服务器,或者Ajax或其他东西。

您的页面将使用PHP打印它,而JavaScript将使用DOM获取值。

只需使用以下方法之一。

<script type="text/javascript">
var js_variable  = '<?php echo $php_variable;?>';
<script>

OR

<script type="text/javascript">
    var js_variable = <?php echo json_encode($php_variable); ?>; 
</script>

试试这个:

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

--

-在尝试了一段时间之后

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