为啥 PHP 文件不用于(自定义)CSS 和 JS?
Posted
技术标签:
【中文标题】为啥 PHP 文件不用于(自定义)CSS 和 JS?【英文标题】:Why aren't PHP files used for (custom) CSS and JS?为什么 PHP 文件不用于(自定义)CSS 和 JS? 【发布时间】:2012-08-04 21:17:09 【问题描述】:人们为什么不为他们的 CSS
和 javascript
文件制作 .php
文件?强>
将<?php header("Content-type: text/javascript; charset: UTF-8"); ?>
添加到文件中使其可以被浏览器读取,您可以通过将Content-type
属性设置为text/css
来对css 文件执行相同的操作。
它让您可以将 PHP 的所有变量和方法用于其他语言。例如,让您根据 css 中的用户偏好更改主题主颜色,或预加载您的 javascript 可在文档加载时使用的数据。
使用这种技术有什么不好的方面吗?
【问题讨论】:
主要的坏处是这意味着文件无法被浏览器缓存,这是一个严重的性能问题。 是什么让你认为他们没有?这并不常见,但也并非闻所未闻。 可以将它们缓存起来,但它确实需要一些小技巧,因为内置的假设是 PHP 将用于动态内容。 我一直这样做。嗯,不是所有时间,但我经常在 CSS 中嵌入一点点 PHP,它使得为一件事拥有用户控制的配色方案变得非常容易。我还知道将 PHP 放在 JS 源文件中,以便用数据库结果填充它们。这是一种应该谨慎使用的技术——你需要非常仔细地考虑你的缓存设置。此外,如果您使用会话并且不完全了解它们的工作原理,您可能会严重影响页面加载时间。 @stevether,没有理由重写。我同意使用正确的缓存头。 【参考方案1】:PHP 通常用作生成动态内容的处理器。处理页面然后发送它需要时间。为了提高效率(服务器和编程所花费的时间),仅在静态文件无法成功实现其预期目标的情况下创建动态 JS 或 CSS 文件。
我建议您仅在绝对需要动态数据库驱动处理器的帮助时才这样做。
【讨论】:
【参考方案2】:运行 PHP 引擎在时间或 CPU 方面的成本都不是零。而且由于 CSS 和 JavaScript 文件通常很少更改,让它们在引擎中运行以完全不做任何事情是没有意义的;最好让浏览器在适当的时候缓存它们。
【讨论】:
更不用说静态文件可以托管在 CDN 上 @tdammers:但您仍然必须每次都调用 PHP,即使只是为了获得 304。 我认为 tdammers 意味着不改变的文件可以是静态的、CDN 的等,但那些改变的部分(例如 CMS 中的可定制样式)可以通过 PHP 提供。我同意安排缓存以便没有 PHP 调用是很棘手的,尽管这并非完全不可能。【参考方案3】:有时您可能必须动态创建 javascript 或样式。
问题是网络服务器经过优化以提供静态内容。使用 php 动态生成内容可能会对性能产生巨大影响,因为它需要在每个请求上生成。
【讨论】:
【参考方案4】:有些人会这样做,更好的做法是在 PHP 中生成 JS/CSS 脚本并将它们缓存到文件中。
如果您使用 PHP 提供所有 CSS/JS 文件,那么您必须调用更多 PHP,这会产生更多开销(cpu 和内存),这在提供静态文件时是不必要的。最好让 Web 服务器(Apache/nginx/lighttpd/iis 等)完成它们的工作并为您提供这些文件,而无需 PHP。
【讨论】:
没错。如果它们很少更改,那么能够在它们发生变化时生成和存储它们是有好处的,但在每个请求上动态构建它们几乎没有什么好处(浏览器缓存除外)。 我没有具体细节,但它会根据 PHP 的调用方式(模块、CGI)和 PHP 编译的模块(模块越多,使用的基线内存越多)而有所不同。在大多数情况下,额外的开销可能很小,但如果有大量并发用户,它可能会大大增加。基本上,当可以静态提供内容时,您最终会不必要地调用 PHP 来一遍又一遍地生成相同的内容。 这并不是反对使用 PHP 的真正理由,只是要确保正确使用它。任何具有高重新加载与修改率的内容都应该被正确缓存,无论是资产、html 页面还是纯数据。 @IMSoP 好点,PHP 擅长它的功能,但是在提供静态内容方面,PHP 是不必要的(至少除了生成初始文件然后适当缓存它之外)。跨度> “最好的办法是在 PHP 中生成 JS/CSS 脚本并将它们缓存到文件中。” - 或使用SASS【参考方案5】:不好的一面:很多,但仅举几例:
这会非常慢:为每个请求构建自定义样式表会给服务器带来巨大的负载,而不是您想要的。
设计师创建 CSS 文件,程序员不应该(在某些情况下不应该被允许)。这不是他们的工作/专长。
混合使用 JS 和 PHP,恕我直言,这是最大的错误之一。由于 jQuery 是一个非常流行的库,使用 $
符号,它可能是错误和语法错误的巨大来源。除此之外:JS 是一种与几乎任何其他编程语言完全不同的语言。很少有人知道如何充分利用它,而让 PHP 开发人员编写大量的 JS 脚本往往以泪水告终。 JavaScript 是一种功能性 OO (prototypal) 语言。不完全理解这些关键差异的人会写出糟糕的代码。我知道,因为我写了很多糟糕的 JS 代码。
实际上,您为什么要这样做? PHP 允许您在生成页面时更改所有元素的类,只需确保这些类在您的 css 文件中具有相应的样式规则,并且颜色会根据您的需要更改,而无需发送各种文件、弄乱标题和所有令人头疼的问题这种做法附带的
如果您想要更多不应该这样做的理由,我至少可以再想出几十个。 也就是说:我只能想到一个您会考虑这样做的原因:它使由客户端缓存脚本引起的问题不再是问题。并不是说这首先应该是一个问题,但是嘿...
【讨论】:
不同意“程序员不应创建 CSS 文件”。设计师应该创造设计;由程序员 / CSS 专家将它们烘焙到样式表中。 对“PHP 程序员不能写 JS”部分也持不同意见。不是每个人都是一招一式的小马;我们中的一些人可以轻松地使用六种语言工作,并且在它们之间切换没有问题。并且 JS 并没有那不同 - 它基本上是 Java 伪装中的 Scheme 的一半。如果您想要“与任何其他语言不同”,请尝试 Haskell。或者马尔博格。 反驳点:1. 缓存一旦完成就消除了速度问题,PHP 并不是“非常慢” 2. 参数是针对 CSS 文件(带有额外提示/变量),不一定是 BL 3。 PHP 在这里被争论为使用“模板” 4. 为什么不呢?这就是海报所要求的:) @tdammers:是的,这取决于前端开发人员。但是我认识和共事过的人,他们在网页设计和可用性方面具有专业知识,他们不会很乐意花时间用 PHP 编写样式表。他们会告诉你自己去 F,给你一个类和 sprite 的列表,并告诉你哪个类会让你的错误消息出现light magenta
,哪个会变成deel-blue-purple
。为双方节省了大量时间(开发人员不必解释他们的对象是如何工作的,设计人员不必费力地编写凌乱的代码)
@tdammers:看,我说得相当尖锐,因为我觉得 OP 正在考虑我认为不好的做法。一些 PHP 开发人员可以编写好的 JS 代码。但是不管你喜不喜欢,很多人仍然不知道 JS 遵循函数式范式。我见过很多 JS 只是滥用和未能理解这一点,实现经典继承的荒谬结构,匿名的事件处理程序。函数只是调用预定义函数等......是的,我知道 JS 是什么,它是第一个也是唯一一个函数式 mainstream 语言【参考方案6】:
人们这样做的频率比你想象的要多。您只是看不到它,因为通常这种技术与 URL 重写结合使用,这意味着浏览器无法区分静态提供的 .css 文件和由 PHP 脚本生成的动态样式表。
但是,有几个充分的理由不这样做:
在默认配置中,Apache 将 PHP 脚本输出视为“随时可能发生变化”,并设置适当的标头以防止缓存(否则,动态内容将无法正常工作)。然而,这意味着浏览器不会缓存您的 CSS 和 javascript,这很糟糕 - 每一个页面加载,它们都会通过网络重新加载。如果您每秒有几百个页面加载,那么这些东西绝对很重要,即使您不这样做,页面的响应性也会受到很大影响。 CSS 和 Javascript,一旦部署,就很少更改,使其动态化的理由非常少。 运行 PHP 脚本(即使只是为了启动解释器)比仅提供静态文件更昂贵,因此除非绝对必要,否则应避免使用它。 要确保您输出的 Javascript 正确且安全是非常困难的;转义 Javascript 的动态值并不像您想象的那么简单,如果这些值是用户提供的,那么您就是在自找麻烦。还有一些更容易设置的替代方案:
编写几个样式表并动态选择正确的样式表。 根据类名制定样式表规则,并在 HTML 中动态设置这些规则。 对于 javascript,在包含静态脚本之前,在父文档中定义动态部分。最典型的场景是在文档中设置一些全局变量并在静态脚本中引用它们。 在构建/部署过程中将动态脚本编译成静态文件。这样,您可以在 CSS 中使用 PHP,但您仍然可以提供静态文件。如果你毕竟想用PHP动态生成CSS:
覆盖缓存标头以允许浏览器和代理缓存它们。您甚至可以将缓存过期设置为“从不”,并添加一个伪造的查询字符串参数(例如<link rel="stylesheet" type="text/css" href="http://example.com/stylesheet.css?dummy=121748283923">
)并在脚本更改时更改它:浏览器会将其解释为不同的 URL 并跳过缓存的版本。
设置 URL 重写,以便脚本的 URL 具有 .css 扩展名:某些浏览器 (IE) 会在扩展名不匹配的某些情况下错误地获取 MIME 类型,尽管 Content-Type
标头正确。
【讨论】:
在我的测试中,我发现添加查询字符串将完全阻止 IE 缓存文件,因为它假定它是动态的。欢迎提供可靠的参考来证明或反驳我。 事实上,它甚至不仅仅是 IE - 请参阅我在页面其他地方的评论。【参考方案7】:这不是一个坏主意,或者很不常见,但也有缺点。缓存是一个重要的考虑因素——你需要让浏览器在内容相同时缓存,但在内容不同时刷新(例如当其他人登录时)。任何查询字符串都会立即停止某些浏览器缓存,因此您需要一些重写规则以及 HTTP 标头。
任何需要花费大量时间或需要锁定某些内容(例如 session_start)的处理都会在浏览器等待资产时阻止浏览器。
最后,也是非常重要的一点,混合语言会使编辑代码变得更加困难 - 语法高亮和结构浏览器可能无法处理,重叠的语法会导致丑陋的事情,例如多个反斜杠转义。
在 javascript 中,将一些 PHP 数据转换为 (JSON) 变量会很有用,然后继续处理静态 JS 代码。在浏览器一次性下载多个 JS 文件之前,连接多个 JS 文件还有性能优势。
对于 CSS,有一些特定的语言,例如更适合该目的的 Less。使用 LessPHP (http://leafo.net/lessphp/),您可以使用 PHP 脚本中的变量和回调轻松初始化 Less 模板。
【讨论】:
查询字符串不会阻止浏览器缓存。这取决于服务资源给出的缓存指令。 正如本页其他地方所提到的,这是我使用 IE 进行测试的经验;它似乎将带有查询字符串的页面解释为动态的。 IIRC,它发送一个 If-Modified-Since,但处理动态生成的内容并非易事。 我可以使用最新的 Firefox (14.0.1) 重现这一点。转到rwec.co.uk/x/caching/cache-test-dummy.html 并打开一个HTTP 调试器,例如Firebug 或Fiddler,然后反复单击“self”链接。使用 If-Modified-Since 重复检查带有查询字符串的 URL。这些都是静态文件,因此服务器会以 304 响应。如果这是一个 PHP 脚本,它将在每次页面加载时运行。【参考方案8】:这是我使用的一种方法:HTML 页面包含对 /path/12345.stylesheet.css
的引用。该文件不存在。所以.htaccess
将请求路由到/path/index.php
。该文件 (a) 执行数据库请求,(b) 创建 CSS,(c) 保存文件以供下次使用,(d) 将 CSS 提供给浏览器。这意味着下一次有/path/12345.stylesheet.css
的请求时,实际上有一个物理静态文件供 Apache 照常提供。
哦,每当编辑样式规则时(a)删除静态文件,以及(b)更改引用 ID,以便 HTML 页面将来包含对 /path/10995.stylesheet.css
的引用,或其他任何内容。 (实际上,我使用的是 UNIX 时间戳。)
我使用类似的方法来创建图像缩略图:在第一次请求时创建文件,并将静态文件保存在同一位置以供将来请求。我从来没有机会为 javascript 做同样的事情,但没有根本原因。
这也意味着我不需要担心在 PHP 中缓存标头:只有每个 CSS 文件(或图像缩略图)的 first 调用通过 PHP,如果它与反缓存头,这不是什么大问题。
【讨论】:
以上是关于为啥 PHP 文件不用于(自定义)CSS 和 JS?的主要内容,如果未能解决你的问题,请参考以下文章