3

I've already read this but it doesn't answer to my question.

Here's my scenario: I've been working on my own framework which I'm proud of (multilanguage, templating, and so on). But I had to face one problem: the multilanguage and template handling was done in Php. 800 lines of code, analyze host to see where to look to read the templates and so on. It was messy and I'm pretty sure it wasn't efficient though I didn't test its efficiency. It was dealing with lot of array (array_push(), array_key_exists() and so on)

I've rewritten the whole Php file, now it create its own "cache" file, and almost all the work is done by Apache before going to the Php file. The Php file only analyzes what's in the _GET.

But I'm worrying about one thing: are RegExp fast? In my previous Php file, I was playing a lot with array_xx() function, but there were absolutely no Apache RewriteRules before.

I don't know about RegExp performance, and I don't know about Apache RewriteRules and the time it takes to initialize environment variables. I do this a lot (see after). So, maybe, after those explanations, someone could tell me either "no problem, your RegExp are not complex, Apache handles this quickly", or "stop this immediately, you may get in trouble with RegExp" and so on.

This is kinddof advices and warnings about performance on "Apache RegExp RewriteRules" and "Php handling URLs instead of Apache".

Here are all my RewriteRule, and I'm just wondering whether they may slow down my Apache Webserver more than my previous Php file.

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]
Community
  • 1
  • 1
Olivier Pons
  • 15,363
  • 26
  • 117
  • 213
  • 1
    Good question but probably hard or even impossible to answer.... why not try out by doing a benchmark? Timing thousands of requests using both methods should give you a rough idea which one is quicker and uses less resources generally. – Pekka Oct 09 '11 at 09:50
  • tl;dr, but that looks quite scary. You should try to simplify everything, because I don't think it's stable and effective in any variant (neither `mod_rewrite`, nor PHP) – KingCrunch Oct 09 '11 at 09:52
  • The problem is that I can't remove or change the "principle", because thanks to it, I'm well paid today. My framework works pretty well and I wanted to clean things up, because I'm fed up with my Php file (I've lost many days of work/debugging on this 800 lines messy file). How to mesure "ressource usage" with Apache? I've already read this: http://httpd.apache.org/docs/2.0/misc/perf-tuning.html but even there, you can read "This works fine in practice on real-life servers, because they aren't restarted frequently. But does really poorly on benchmarks which might only run for ten minutes."... – Olivier Pons Oct 09 '11 at 10:08

3 Answers3

2

It will depend on your servers, memory, etc. The only way to know for sure is to run a performance benchmark, take a look at httperf for one.

Subjectively, I can tell you that we have about 450 lines of rewrite rules in our .htaccess at work, and while it's always best to have as little as possible, the rewrite rules are NOT the bottleneck of the application by far (and we serve some thousands of requests per second).

So, with that in mind, I wouldn't worry too much about it. You're more likely to run into problems with unoptimized databases, insufficient caching, and many other things, before you get to the point where rewrite rules are the slowest part of your system.

Your rewrite rule set does seem kind of disorganized, so I would try to spend some time organizing it into a more meaningful url structure (and add 301 redirects from old URL's). You can look into how routing is handled in common HMVC frameworks like Kohana, Codeigniter, or Symfony.

Aeon
  • 6,467
  • 5
  • 29
  • 31
  • Thank you for your comment it's exactly what I thought but I didn't know if I were totally wrong or if I just have to benchmark it. I'm planning to test it internally with "ab (http://httpd.apache.org/docs/2.0/programs/ab.html)". Thank you. – Olivier Pons Oct 11 '11 at 08:52
  • (And my RewriteRules are well organized, this is just disturbing because I've renamed all the variable names, and in my actual vhost conf, I've got 400 lines of comment for 100 lines of RewriteRules :) ) – Olivier Pons Oct 11 '11 at 08:57
0

For performance and server platform portability you should have Apache rewrite to your index.php then try to mitigate your complex path/request handling to PHP using $_SERVER['REQUEST_URI'].

I would do something like this in PHP.

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

Then you can play around with $request and extract/handle it any way you want.

Timothy Perez
  • 20,154
  • 8
  • 51
  • 39
0

Best idea is to put that into the apache vhost/httpd config file. Then its only parsed once and only executed which is indeed faster then in the .htaccess file!

  • That's what I've already done (and what I always do actually). I think ".htaccess" are to be avoided whenever possible. – Olivier Pons Oct 11 '11 at 08:50