【问题标题】:Php handling vs Apache RewriteRules and RegExp: which one is quicker?PHP 处理与 Apache RewriteRules 和 RegExp:哪个更快?
【发布时间】:2011-12-03 21:33:30
【问题描述】:

我已经阅读了this,但它没有回答我的问题。

这是我的场景:我一直在开发自己引以为豪的框架(多语言、模板等)。 但我不得不面对一个问题:多语言和模板处理是在 Php 中完成的。 800行代码,分析主机看哪里看读取模板等等。它很乱,我很确定它效率不高虽然我没有测试它的效率。它正在处理大量数组(array_push()array_key_exists() 等)

我已经重写了整个 Php 文件,现在它创建了自己的“缓存”文件,并且几乎所有的工作都是由 Apache 在进入 Php 文件之前完成的。 Php 文件只分析_GET 中的内容。

但我担心一件事:RegExp 快吗?在我之前的 Php 文件中,我玩了很多 array_xx() 函数,但之前绝对 没有 Apache RewriteRules

我不了解 RegExp 的性能,也不了解 Apache RewriteRules 以及初始化环境变量所需的时间。我经常这样做(见下文)。所以,也许,在这些解释之后,有人可以告诉我“没问题,你的 RegExp 并不复杂,Apache 处理得很快”,或者“立即停止这个,你可能会遇到 RegExp 的麻烦”等等。

这是关于“Apache RegExp RewriteRules”和“Php 处理 URLs 而不是 Apache”性能的建议和警告。

这是我所有的 RewriteRule,我只是想知道它们是否会比我以前的 Php 文件更慢减慢我的 Apache Web 服务器

RewriteMap maprns dbm:/rns.map
RewriteMap mapdps dbm:/dps.map
RewriteMap mapcts dbm:/cts.map
RewriteMap ts dbm:/ts.map
RewriteRule /404.php - [QSA,E=PLOCAL:${ts:www\.}]
RewriteCond %{ENV:PLOCAL} ^default\.([a-zA-Z0-9\-]+)\.$
RewriteRule /404.php - [QSA,E=L:%1,E=PLOCAL:${ts:%1\.}]
RewriteCond %{ENV:PLOCAL} !^$
RewriteCond %{HTTP_HOST} ([a-zA-Z0-9\-]+\.)+([a-zA-Z0-9\-]+)\.+(fr|com|net|org|eu)$
RewriteRule (.*) /404.php?L=%{ENV:L}&Pt=%{ENV:PLOCAL}&Pt_cm=${ts:cm.}&h_static=%{ENV:L}.s.%2.%3 [QSA,L]
RewriteCond %{HTTP_HOST} ((([a-zA-Z0-9\-]+)\.)+)(s|static)\.(([a-zA-Z0-9\-]+\.)+)([a-zA-Z0-9\-]+)\.+(fr|com|net|org|eu)$
RewriteRule (.*) - [QSA,E=L:%3,E=PLOCAL:${ts:%1%5|notfound},E=Pcm:${ts:cm.%5},E=STATIC:1]
RewriteCond %{ENV:PLOCAL} ^$
RewriteCond %{HTTP_HOST} ((([a-zA-Z0-9\-]+)\.)+)(s|static)\.([a-zA-Z0-9\-]+)\.+(fr|com|net|org|eu)$
RewriteRule (.*) - [QSA,E=L:%3,E=PLOCAL:${ts:%1|notfound},E=Pcm:${ts:cm.},E=STATIC:1]
RewriteCond %{ENV:PLOCAL} ^$
RewriteCond %{HTTP_HOST} (([a-zA-Z0-9\-]+)\.)((([a-zA-Z0-9\-]+)\.)+)([a-zA-Z0-9\-]+)\.+(fr|com|net|org|eu)$
RewriteRule (.*) - [QSA,E=L:%2,E=PLOCAL:${ts:%1%3|notfound},E=Pcm:${ts:cm.%3}]
RewriteCond %{ENV:PLOCAL} ^$
RewriteCond %{HTTP_HOST} (([a-zA-Z0-9\-]+)\.)([a-zA-Z0-9\-]+)\.+(fr|com|net|org|eu)$
RewriteRule (.*) - [QSA,E=L:%2,E=PLOCAL:${ts:%1|notfound},E=Pcm:${ts:cm.}]
RewriteCond %{ENV:PLOCAL} ^default\.([a-zA-Z0-9\-]+)\.(([a-zA-Z0-9\-]+\.)+)
RewriteRule (.*) - [QSA,E=L:%1,E=PLOCAL:${ts:%1\.%2|notfound},E=Pcm:${ts:cm.%2}]
RewriteCond %{ENV:PLOCAL} ^default\.([a-zA-Z0-9\-]+)\.$
RewriteRule (.*) - [QSA,E=L:%1,E=PLOCAL:${ts:%1\.|notfound},E=Pcm:${ts:cm.}]
RewriteCond %{ENV:PLOCAL} ^$ [OR]
RewriteCond %{ENV:PLOCAL} notfound
RewriteRule .* - [R=404,L]
RewriteRule (.*) $1?L=%{ENV:L}&Plocal=%{ENV:PLOCAL}&Pcm=%{ENV:Pcm} [QSA]
RewriteCond %{ENV:STATIC} !^$
RewriteRule (.*)(\.(css|js|pdf|jpg|jpeg|gif|png)){1}$ $1$2 [QSA,E=EXT:$3]
RewriteCond %{ENV:EXT} (jpg|jpeg|gif|png)
RewriteRule (.*) - [QSA,E=EXT:img]
RewriteCond %{ENV:STATIC} !^$
RewriteCond %{ENV:EXT} !([a-z]+)
RewriteRule .* - [L,R=404]
RewriteCond %{ENV:STATIC} !^$
RewriteCond %{ENV:EXT} (css|js)$
RewriteRule (.*) /%1.php?%1=$1&static=1 [QSA,L]
RewriteCond %{ENV:STATIC} !^$
RewriteCond %{DOCUMENT_ROOT}/%{ENV:PLOCAL}/%{ENV:EXT}%{REQUEST_FILENAME}  -f
RewriteRule  ^(.+) %{DOCUMENT_ROOT}/%{ENV:PLOCAL}/%{ENV:EXT}%{REQUEST_FILENAME} [QSA,L]
RewriteCond %{ENV:STATIC} !^$
RewriteCond %{DOCUMENT_ROOT}/%{ENV:Pcm}/%{ENV:EXT}%{REQUEST_FILENAME}  -f
RewriteRule  ^(.+) %{DOCUMENT_ROOT}/%{ENV:Pcm}/%{ENV:EXT}%{REQUEST_FILENAME} [QSA,L]
RewriteCond %{ENV:STATIC} !^$
RewriteRule .* - [L,R=404]
RewriteRule ^/$ /index.php [QSA,L]
RewriteRule /d-envoyer-lte-par-mail/ /d_envoyer_lte_par_mail.php [QSA,L]
RewriteRule /d-creer-editer/ /d_creer_editer.php [QSA,L]
RewriteRule /d-mail-ver/(.*)/$ /d_mail_ver.php?chaine_vation=$1 [QSA,L]
RewriteRule /d-mail-ver/ /d_mail_ver.php [QSA,L]
RewriteRule /i/lg/$ /i/lg.php [QSA,L]
RewriteRule /i/lg-ver/$ /i/lg_ver.php [QSA,L]
RewriteCond %{HTTP_HOST} ^s\.(.*) [NC]
RewriteRule /contact-([0-9]+)-([0-9]+)-([a-z0-9]+)\.png$ /d_image_telephone.php?no=$1&id=$2&chaine_vation=$3 [QSA,L]
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule /d-contact/numero-([0-9]+)-([a-z0-9]+)/$ /d_message.php?id=$1&chaine_vation=$2 [QSA,L]
RewriteRule ^/d-(dtl|ann)/offre/(.*)/$ /d-$1/$2/$3?d_type=1 [QSA,NC]
RewriteRule ^/d-(dtl|ann)/demande/(.*)/$ /d-$1/$2/$3?d_type=2 [QSA,NC]
RewriteRule ^/d-dtl/(.*)/numero-([0-9]+)/$ /d-dtl/?val_ct=$1&id=$2 [QSA,NC,E=ct:${mapcts:$1|notfound}]
RewriteRule ^/d-ann/(.*)/numero-([0-9]+)-([a-z0-9]+)/$ /d-ann/?val_ct=$1&id=$2&chaine_ann=$3 [QSA,NC,E=ct:${mapcts:$1|notfound}]
RewriteCond %{ENV:ct} ([0-9]+)
RewriteRule /d-(dtl|ann)/ /d_$1.php?ct=%{ENV:ct} [QSA,NC,L]
RewriteRule ^/d/offres/(rn|dp|ct)/(.*)/$ /d/$1/$2/?d_type=1 [QSA,NC]
RewriteRule ^/d/demandes/(rn|dp|ct)/(.*)/$ /d/$1/$2/?d_type=2 [QSA,NC]
RewriteRule ^/d/(.*)/d-([0-9]+)-a-([0-9]+)/$ /d/$1/$2/?start=$3&end=$4 [QSA,NC]
RewriteRule ^/d/rn/([a-z\-\_0-9]+)/(.*)/$ /d/$2/?val_rn=$1 [QSA,NC,E=rn:${maprns:$1|notfound}]
RewriteRule ^/d/rn/(.*)/$ /d/?val_rn=$1 [QSA,NC,E=rn:${maprns:$1|notfound}]
RewriteRule ^/d/dp/(.*)/$ /d/?val_dp=$1 [QSA,NC,E=dp:${mapdps:$1|notfound}]
RewriteRule ^/d/ct/(.*)/$ /d/?val_ct=$1 [QSA,NC,E=ct:${mapcts:$1|notfound}]
RewriteCond %{ENV:rn} notfound [OR]
RewriteCond %{ENV:dp} notfound [OR]
RewriteCond %{ENV:ct} notfound
RewriteRule .* - [L,R=404]
RewriteCond %{SCRIPT_FILENAME} /d/
RewriteCond %{QUERY_STRING} !start=(.+)
RewriteRule (.*) $1?start=1 [NC,QSA]
RewriteCond %{SCRIPT_FILENAME} /d/
RewriteCond %{QUERY_STRING} !end=(.+)
RewriteRule (.*) $1?end=20 [NC,QSA]
RewriteCond %{ENV:rn} ([0-9]+) [OR]
RewriteCond %{ENV:dp} ([0-9]+) [OR]
RewriteCond %{ENV:ct} ([0-9]+)
RewriteRule /d/ /d_lte.php?rn=%{ENV:rn}&dp=%{ENV:dp}&ct=%{ENV:ct} [QSA,L]
RewriteRule .* - [L,R=404]

【问题讨论】:

  • 好问题,但可能很难甚至不可能回答.... 为什么不尝试做一个基准测试呢?使用这两种方法对数千个请求进行计时应该可以让您大致了解哪种方法更快并且通常使用更少的资源。
  • tl;dr,但这看起来很可怕。您应该尝试简化所有内容,因为我认为它在任何变体中都不是稳定有效的(mod_rewrite 和 PHP 都不是)
  • 问题是我无法删除或更改“原则”,因为感谢它,我今天得到了不错的报酬。我的框架工作得很好,我想清理一下,因为我受够了我的 Php 文件(我已经失去了很多天的工作/调试这个 800 行凌乱的文件)。如何使用 Apache 测量“资源使用情况”?我已经读过这个:httpd.apache.org/docs/2.0/misc/perf-tuning.html,但即使在那里,你也可以读到“这在现实生活中的服务器上工作得很好,因为它们不会经常重新启动。但在可能只运行十分钟的基准测试中表现很差."...

标签: php performance mod-rewrite rewrite


【解决方案1】:

为了性能和服务器平台的可移植性,您应该让 Apache 重写您的 index.php,然后尝试使用 $_SERVER['REQUEST_URI'] 减轻对 PHP 的复杂路径/请求处理。

我会在 PHP 中做这样的事情。

$uri = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$request = parse_url($uri);

然后您可以随意使用 $request 并以任何您想要的方式提取/处理它。

【讨论】:

    【解决方案2】:

    这将取决于您的服务器、内存等。确定的唯一方法是运行性能基准测试,查看httperf 的一个。

    主观上,我可以告诉你,我们的 .htaccess 中有大约 450 行重写规则在工作,虽然最好尽可能少,但重写规则到目前为止还不是应用程序的瓶颈(我们每秒处理数千个请求)。

    所以,考虑到这一点,我不会太担心。在达到重写规则是系统中最慢的部分之前,您更有可能遇到数据库未优化、缓存不足以及许多其他问题。

    您的重写规则集似乎有点杂乱无章,所以我会尝试花一些时间将其组织成更有意义的 url 结构(并添加来自旧 URL 的 301 重定向)。您可以了解在 Kohana、Codeigniter 或 Symfony 等常见 HMVC 框架中如何处理路由。

    【讨论】:

    • 感谢您的评论,这正是我的想法,但我不知道我是否完全错了,或者我是否只需要对其进行基准测试。我打算用“ab (httpd.apache.org/docs/2.0/programs/ab.html)”在内部对其进行测试。谢谢。
    • (而且我的 RewriteRules 组织得很好,这只是令人不安,因为我已经重命名了所有变量名,并且在我实际的 vhost conf 中,对于 100 行 RewriteRules,我有 400 行注释:) )
    【解决方案3】:

    最好的办法是将其放入 apache vhost/httpd 配置文件中。然后它只被解析一次并且只被执行,这确实比在 .htaccess 文件中更快!

    【讨论】:

    • 这就是我已经做过的(以及我实际上一直在做的)。我认为尽可能避免使用“.htaccess”。
    猜你喜欢
    • 1970-01-01
    • 2013-01-13
    • 2011-01-01
    • 1970-01-01
    • 2013-05-02
    • 2011-10-21
    • 2016-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多