通过 PHP 加载 Javascript

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6255144/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 20:04:07  来源:igfitidea点击:

Loading Javascript through PHP

phpjavascript

提问by afaolek

From a tutorial I read on Sitepoint, I learned that I could load JS files through PHP (it was a comment, anyway). The code for this was in this form:

从我在 Sitepoint 上阅读的教程中,我了解到我可以通过 PHP 加载 JS 文件(无论如何,这是一个评论)。代码是这样的:

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

The purpose of using PHP was to reduce the number of HTTP requests for JS files. But from the markup above, it seems to me that there are still going to be the same number of requests as if I had written two tags for the JS files (I could be wrong, that's why I'm asking).

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

The question is how is the PHP code supposed to be written and what is/are the advantage(s) of this approach over the 'normal' method?

问题是应该如何编写 PHP 代码以及这种方法相对于“普通”方法的优势是什么?

回答by alexn

The original poster was presumably meaning that

原来的海报大概是这个意思

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

Will cause less http requests than

会导致比 http 请求少

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

That is because js.php will read all script names from GET parameters and then print it out to a single file. This means that there's only one roundtrip to the server to get all scripts.

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

js.php would probably be implemented like this:

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

Note that this may not be an optimal solution if there is a low number of scripts that is required. The main issue is that web browser does not load an infinitely number of scripts in parallel from the same domain.

请注意,如果需要的脚本数量很少,这可能不是最佳解决方案。主要问题是 Web 浏览器不会从同一域并行加载无限数量的脚本。

You will need to implement caching to avoid loading and concatenating all your scripts on every request. Loading and combining all scripts on every request will eat very much CPU.

您将需要实现缓存以避免在每个请求上加载和连接所有脚本。在每个请求上加载和组合所有脚本会消耗大量 CPU。

IMO, the best way to do this is to combine and minify all script files into a big one before deploying your website, and then reference that file. This way, the client just makes one roundtrip to the server, and the server does not have any extra load upon each request.

IMO,最好的方法是在部署您的网站之前将所有脚本文件合并并缩小为一个大文件,然后引用该文件。这样,客户端只需往返服务器一次,并且服务器不会对每个请求产生任何额外的负载。

Please note that the PHP solution provided is by no means a good approach, it's just a simple demonstration of the procedure.

请注意,提供的 PHP 解决方案绝不是一个好方法,它只是一个简单的过程演示。

回答by simshaun

The main advantage of this approach is that there is only a single request between the browser and server.

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

Once the server receives the request, the PHP script combines the javascript files and spits the results out.

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

Building a PHP script that simply combines JS files is not at all difficult. You simply include the JS files and send the appropriate content-type header.

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

When it gets more difficult is based on whether or not you want to worry about caching.

何时变得更困难取决于您是否要担心缓存。

I recommend you check out minify.

我建议您查看minify

回答by Quentin

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

That's:

那是:

  • invalid (ampersands have to be encoded)
  • hard to expand (using script[]=would make PHP treat it as an array you can loop over)
  • not HTML compatible (always use <script></script>, never <script />)
  • 无效(必须对符号进行编码)
  • 难以扩展(使用script[]=会使 PHP 将其视为可以循环的数组)
  • 与 HTML 不兼容(总是使用<script></script>,从不<script />

The purpose of using PHP was to reduce the number of HTTP requests for JS files. But from the markup above, it seems to me that there are still going to be the same number of requests as if I had written two tags for the JS files (I could be wrong, that's why I'm asking).

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

You're wrong. The browser makes a single request. The server makes a single response. It just digs around in multiple files to construct it.

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

The question is how is the PHP code supposed to be written

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

The steps are listed in this answer

此答案中列出了这些步骤

and what is/are the advantage(s) of this approach over the 'normal' method?

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

You get a single request and response, so you avoid the overhead of making multiple HTTP requests.

您将获得单个请求和响应,因此可以避免发出多个 HTTP 请求的开销。

You lose the benefits of the generally sane cache control headers that servers send for static files, so you have to set up suitable headers in your script.

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

回答by Arend

You can do this like this:

你可以这样做:

The concept is quite easy, but you may make it a bit more advanced

这个概念很简单,但你可以让它更高级一点

Step 1:merging the file

第一步:合并文件

<?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();

?>

usage:

用法

<script src="js.php?script[]=jquery.js&script[]=otherfile.js" type="text/javascript"></script>

Step 2:caching

第二步:缓存

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

This makes it a bit more advanced. Please note, this is semi-pseudo code to explain the concepts. In practice you will need to do more error checking and you need to do some cache invalidation.

这使它更先进一些。请注意,这是解释概念的半伪代码。在实践中,你需要做更多的错误检查,你需要做一些缓存失效。

To do this is a more managed and automated way, there's assetic (if you may use php 5.3):

要做到这一点,这是一种更受管理和自动化的方式,有资产(如果您可以使用 php 5.3):

https://github.com/kriswallsmith/assetic

https://github.com/kriswallsmith/assetic

(Which more or less does this, but much better)

(或多或少这样做,但要好得多)

AsseticDocumentation https://github.com/kriswallsmith/assetic/blob/master/README.md

Assetic文档 https://github.com/kriswallsmith/assetic/blob/master/README.md

The workflow will be something along the lines of this:

工作流程将是这样的:

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();

There is a lot of support for many formats:

对许多格式有很多支持:

  • js
  • css
  • 大量的压缩器和优化器(css​​、js、png 等)
  • 支持sass,http://sass-lang.com/

Explaining everything is a bit outside the scope of this question. But feel free to open a new question!

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

回答by DanielB

PHP will simply concatenate the two script files and sends only 1 script with the contents of both files, so you will only have 1 request to the server.

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

回答by Chris Thompson

Using this method, there will still be the same number of disk IO requests as if you had not used the PHP method. However, in the case of a web application, disk IO on the server is never the bottle neck, the network is. What this allows you to do is reduce the overhead associated with requesting the file from the server over the network via HTTP. (Reduce the number of messages sent over the network.) The PHP script outputs the concatenation of all of the requested files so you get all of your scripts in one HTTP request operation rather than multiple.

使用此方法,仍然会出现与未使用 PHP 方法相同数量的磁盘 IO 请求。但是,在 Web 应用程序的情况下,服务器上的磁盘 IO 永远不是瓶颈,网络才是。这允许您做的是减少与通过网络通过 HTTP 从服务器请求文件相关的开销。(减少通过网络发送的消息数量。)PHP 脚本输出所有请求文件的串联,因此您可以通过一个 HTTP 请求操作而不是多个请求操作来获取所有脚本。

回答by JohnP

Looking at the parameters it's passing to js.php it can load two javascript files (or any number for that matter) in one request. It would just look at its parameters (script1, script2, scriptN) and load them all in one go as opposed to loading them one by one with your normal script directive.

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

The PHP file could also do other things like minimizing before outputting. Although it's probably not a good idea to minimize every request on the fly.

PHP 文件还可以执行其他操作,例如在输出之前最小化。尽管动态地最小化每个请求可能不是一个好主意。

The way the PHP code would be written is, it would look at the script parameters and just load the files from a given directory. However, it's important to note that you should check the file type and or location before loading. You don't want allow a people a backdoor where they can read all the files on your server.

PHP 代码的编写方式是,它会查看脚本参数并从给定目录加载文件。但是,请务必注意,您应该在加载前检查文件类型和/或位置。您不想让人们有一个后门,他们可以在其中读取您服务器上的所有文件。