通过PHP加载Javascript

通过PHP加载Javascript,php,javascript,Php,Javascript,从我在Sitepoint上读到的一篇教程中,我了解到我可以通过PHP加载JS文件(无论如何,这只是一条注释)。此操作的代码如下表所示: <script src="js.php?script1=jquery.js&scipt2=main.js" /> 使用PHP的目的是减少JS文件的HTTP请求数量。但是从上面的标记来看,在我看来,仍然会有相同数量的请求,就像我为JS文件编写了两个标记一样(我可能错了,这就是为什么我要问的原因) 问题是PHP代码应该如何编写,与“普通”方

从我在Sitepoint上读到的一篇教程中,我了解到我可以通过PHP加载JS文件(无论如何,这只是一条注释)。此操作的代码如下表所示:

<script src="js.php?script1=jquery.js&scipt2=main.js" />

使用PHP的目的是减少JS文件的HTTP请求数量。但是从上面的标记来看,在我看来,仍然会有相同数量的请求,就像我为JS文件编写了两个标记一样(我可能错了,这就是为什么我要问的原因)


问题是PHP代码应该如何编写,与“普通”方法相比,这种方法的优点是什么?

这种方法的主要优点是浏览器和服务器之间只有一个请求

一旦服务器接收到请求,PHP脚本将组合javascript文件并输出结果

构建一个简单组合JS文件的PHP脚本并不困难。只需包含JS文件并发送适当的内容类型头

什么时候变得更困难取决于您是否需要担心缓存


我建议您查看

PHP将简单地连接两个脚本文件,并只发送一个包含两个文件内容的脚本,因此您将只向服务器发送一个请求。

原始海报的意思大概是

<script src="js.php?script1=jquery.js&scipt2=main.js" />

将导致比以前更少的http请求

<script src="jquery.js" />
<script src="main.js" />

这是因为js.php将从GET参数中读取所有脚本名称,然后将其打印到单个文件中。这意味着只有一次往返服务器才能获取所有脚本

js.php的实现方式可能如下:

<?php
$script1 = $_GET['script1'];
$script2 = $_GET['script2'];

echo file_get_contents($script1); // Load the content of jquery.js and print it to browser
echo file_get_contents($script2); // Load the content of main.js and print it to browser

那就是:

  • 无效(必须对符号和进行编码)
  • 难以扩展(使用
    script[]=
    会使PHP将其视为可以循环的数组)
  • 不兼容HTML(始终使用
    ,从不使用
使用PHP的目的是减少JS文件的HTTP请求数量。但是从上面的标记来看,在我看来,仍然会有相同数量的请求,就像我为JS文件编写了两个标记一样(我可能错了,这就是为什么我要问的原因)

你错了。浏览器只发出一个请求。服务器只做出一个响应。它只是在多个文件中挖掘来构建它

问题是PHP代码应该如何编写

中列出了这些步骤

与“正常”方法相比,这种方法的优点是什么

您只得到一个请求和响应,因此避免了发出多个HTTP请求的开销


您失去了服务器为静态文件发送的通常正常的缓存控制头的好处,因此您必须在脚本中设置合适的头。

查看它传递给js.php的参数,它可以在一个请求中加载两个javascript文件(或任何数字)。它只需查看其参数(script1、script2、scriptN)并一次性加载它们,而不是使用普通的script指令逐个加载它们

PHP文件还可以做其他事情,比如在输出前最小化。虽然在飞行中最小化每个请求可能不是一个好主意


PHP代码的编写方式是,查看脚本参数,然后从给定目录加载文件。但是,需要注意的是,在加载之前应该检查文件类型和/或位置。您不希望允许用户使用后门读取服务器上的所有文件

使用此方法,仍然会有相同数量的磁盘IO请求,就像您没有使用PHP方法一样。然而,对于web应用程序来说,服务器上的磁盘IO永远不是瓶颈,网络是瓶颈。这使您能够减少通过HTTP通过网络从服务器请求文件的相关开销。(减少通过网络发送的消息数量。)PHP脚本输出所有请求文件的串联,因此您可以在一个HTTP请求操作而不是多个HTTP请求操作中获得所有脚本

您可以这样做:

<?php
$script1 = $_GET['script1'];
$script2 = $_GET['script2'];

echo file_get_contents($script1); // Load the content of jquery.js and print it to browser
echo file_get_contents($script2); // Load the content of main.js and print it to browser
这个概念很简单,但是你可以让它更高级一点

步骤1:合并文件

<?php

    $scripts = $_GET['script'];
    $contents = "";
    foreach ($scripts as $script)
    {
         // validate the $script here to prevent inclusion of arbitrary files
         $contents .= file_get_contents($pathto . "/" . $script);
    }

    // post processing here
    // eg. jsmin, google closure, etc.
    echo $contents();

?>
对多种格式有很多支持:

  • js
  • css
  • 大量的缩微器和优化器(css、js、png等)
  • 支持sass

解释一切都有点超出了这个问题的范围。但请随意提出一个新问题

缺点是现在缓存成了一个问题,所以你已经从每页2->1个请求开始,但是现在可能需要在每个请求的页面上重新加载整个JS语料库,而不仅仅是从缓存中加载。如果你的脚本处理好了这一点(如两个答案中所述),就不会了。感谢你更正标记。他们写得很匆忙。谢谢你的回答,你明白我的意思。问题是,PHP仍然可以请求JS文件,这仍然是服务器上的一个负载,尽管更小。我想我将使用许多标记,以便可以缓存文件。谢谢+1给你(和其他一些人)。@afaolek,对,这并没有减少服务器上的磁盘负载,尽管它确实减少了服务器上的网络负载。减少负载的唯一方法是使用更少的JS文件,或者鼓励缓存。没有什么可以阻止浏览器缓存PHP脚本的输出,但是…同样重要的是要记住,使用PHP脚本的磁盘负载将与使用单个脚本的磁盘负载相同。您可以详细说明缓存的CPU吗?即使你所做的只是检查文件的时间戳并给它最后一个时间戳,这也不会是CPU密集型的。如果你使用这种方法,一定要做一些安全检查。@rob我的意思是加载
<script src="js.php?script[]=jquery.js&script[]=otherfile.js" type="text/javascript"></script>
<?php
    function cacheScripts($scriptsArray,$outputdir)
    {
       $filename = sha1(join("-",$scripts) . ".js";
       $path = $outputdir . "/" . $filename;
       if (file_exists($path))
       {
            return $filename;
       }
       $contents = "";
       foreach ($scripts as $script)
       {
          // validate the $script here to prevent inclusion of arbitrary files
          $contents .= file_get_contents($pathto . "/" . $script);
        }

       // post processing here
       // eg. jsmin, google closure, etc.
       $filename = sha1(join("-",$scripts) . ".js";
       file_write_contents( , $contents);
       return $filename;
    }
?>

 <script src="/js/<?php echo cacheScripts(array('jquery.js', 'myscript.js'),"/path/to/js/dir"); ?>" type="text/javascript"></script>
use Assetic\Asset\AssetCollection;
use Assetic\Asset\FileAsset;
use Assetic\Asset\GlobAsset;

$js = new AssetCollection(array(
    new GlobAsset('/path/to/js/*'),
    new FileAsset('/path/to/another.js'),
));

// the code is merged when the asset is dumped
echo $js->dump();