PHP处理与Apache RewriteRules和RegExp:哪个更快?

3

我已经阅读了这篇文章,但它并没有回答我的问题。

这是我的情况:我一直在开发自己的框架,其中包括多语言、模板等功能。但我面临一个问题:多语言和模板处理是用Php完成的,有800行代码,需要分析主机以确定要查找哪个模板等等。这很混乱,而且我相信它不够高效,尽管我没有测试过它的效率。它涉及到很多数组(如array_push()array_key_exists()等)。

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

但我担心一件事:正则表达式快吗?在我以前的Php文件中,我经常使用array_xx()函数,但在此之前绝对没有任何Apache RewriteRules

我不知道正则表达式的性能,也不知道Apache RewriteRules和初始化环境变量所需的时间。我经常这样做(见下文)。因此,也许在这些解释之后,有人可以告诉我:“没问题,你的正则表达式不复杂,Apache可以快速处理”,或者“立即停止这样做,你可能会遇到正则表达式的问题”等等。

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

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

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]

1
好问题,但可能很难甚至不可能回答...为什么不通过进行基准测试来尝试一下呢?使用两种方法计时数千个请求应该能给你一个大致的想法,哪种方法更快并且通常使用更少的资源。 - Pekka
太长不看,但那看起来相当可怕。你应该尝试简化一切,因为我认为任何变体(无论是mod_rewrite还是PHP)都不稳定且有效。 - KingCrunch
问题在于我不能删除或更改“原则”,因为正是由于它,我今天才能得到很好的报酬。我的框架运行得相当不错,我想清理一下东西,因为我对我的Php文件感到厌烦(我在这个800行混乱的文件上失去了许多工作/调试的时间)。如何使用Apache测量“资源使用情况”?我已经阅读了这篇文章:http://httpd.apache.org/docs/2.0/misc/perf-tuning.html,但即使在那里,你也可以读到“这在实际的服务器上运行得很好,因为它们不会经常重新启动。但在可能只运行十分钟的基准测试中表现非常差。”... - Olivier Pons
3个回答

2
这将取决于您的服务器、内存等。想要确切知道可以运行性能基准测试,具体可以查看httperf
主观上讲,我们的.htaccess文件中约有450行重写规则,虽然最好尽可能少,但重写规则绝对不是应用程序的瓶颈(我们每秒处理数千个请求)。
所以,考虑这一点,我不会太担心它。在重写规则成为系统最慢的部分之前,您更有可能遇到未经优化的数据库、不足的缓存和许多其他问题。
您的重写规则集似乎有些杂乱,因此建议花些时间将其组织为更有意义的URL结构(并添加从旧URL的301重定向)。您可以了解一下Kohana、Codeigniter或Symfony等常见HMVC框架中如何处理路由。

谢谢您的评论,这正是我所想的,但我不知道我是否完全错误,或者我只需要进行基准测试。我计划使用“ab(http://httpd.apache.org/docs/2.0/programs/ab.html)”在内部进行测试。谢谢。 - Olivier Pons
我的RewriteRules已经很有组织了,只是因为我重命名了所有变量名称,在我的实际vhost conf中,我有400行注释对应100行的RewriteRules,所以这有点令人不安 :) - Olivier Pons

0
为了提高性能和服务器平台的可移植性,您应该将Apache重写到您的index.php,然后尝试使用$_SERVER['REQUEST_URI']将复杂的路径/请求处理转移到PHP中。
我会在PHP中这样做。
$uri = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$request = parse_url($uri);

然后你可以玩弄 $request 并以任何你想要的方式提取/处理它。


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

这就是我已经做过的事情(实际上也是我一直在做的事情)。我认为应该尽可能避免使用“.htaccess”。 - Olivier Pons

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接