Q: How the HECK does Apache server work with PHP module? What is the flow in which an HTTP request makes through a PHP-enabled Apache web server?
Problem
I have WAMP (Version 2.0) installed on my Windows 7 operating system. For those who don't know, WAMP is an acronym that stands for Windows Apache MySQL PHP. Just so you know this versino of WAMP comes with the following versions of Apache, MySQL, PHP:
- Apache version 2.2.11
- PHP version 5.3.0
- MySQL version 5.1.36
I need to enable the rewrite module of Apache to process URL rewrite rules, so I have the following line in httpd.conf:
LoadModule rewrite_module modules/mod_rewrite.so
I enable rewrite logging at "C:\wamp\logs\rewrite.log" so I can see how rewriting is done via adding the following line in httpd.conf right after Loadmodule:
RewriteLog "C:\wamp\logs\rewrite.log"
RewriteLogLevel 9
I also have the following line in httpd.conf to enable PHP processing:
LoadModule php5_module "c:/wamp/bin/php/php5.3.0/php5apache2_2.dll"
Now an HTTP request goes through Apache, which hands it to the rewrite module to process URL rewrite handling, and has the resulting URL go through PHP engine. But how does Apache rewrite module supposed to know when it should stop rewriting the URL and hand it to PHP module? Is there any way we can control when the processing goes to PHP engine through rewrite rules? Let's answer these questions below.
By the way if you need to know how Apache server variables including %{DOCUMENT_ROOT}, %{REQUEST_URI}, %{REQUEST_FILENAME} work refer to Test Whether a Server Variable is Empty in Popular Web Servers.
Questions?
My Answers
Simply by having the line 'LoadModule php5_module "c:/wamp/bin/php/php5.3.0/php5apache2_2.dll"' in httpd.conf, PHP is enabled to handle pages with extension 'php' (e.g. black-jacket.php) after Apache passes the page through to PHP module. By the way if you'd like PHP to also be able to handle pages with other extensions add the following line after LoadModule in httpd.conf (so PHP handles .html too):
AddType application/x-httpd-php .html
Now here's the interesting part. How the HECK does Apache rewrite module know when to pass through the request to PHP module? The answer is ONLY if and ONLY when the request is NOT matched by ANY rewrite rule, the request is passed through to PHP handler. Even funnier is that there is absolutely NO control you have in the rewrite rules to tell Apache to pass through to PHP handler right away! If you don't agree let me know.
I've tried [L] and [PT] on the RewriteRule directive but when the request matches that particular directive, the request is "internally redirected" to rewrite module again and it's processed by the rewrite module again! In rewrite log it looks like this:
127.0.0.1 - - [29/May/2011:22:26:46 +0800] [localhost/sid#d33140][rid#2254c80/initial/redir#1] (4) [perdir C:/repository/trunk-php/] RewriteCond: input='C:/repository/trunk-php/cache/index.php' pattern='-f' => matched
127.0.0.1 - - [29/May/2011:22:26:46 +0800] [localhost/sid#d33140][rid#2254c80/initial/redir#1] (2) [perdir C:/repository/trunk-php/] rewrite 'index.php' -> '/cache/index.php' # this rule has [L] but it's still internally redirected to rewrite module as the following log statement suggests
127.0.0.1 - - [29/May/2011:22:26:46 +0800] [localhost/sid#d33140][rid#2254c80/initial/redir#1] (1) [perdir C:/repository/trunk-php/] internal redirect with /cache/index.php [INTERNAL REDIRECT]
127.0.0.1 - - [29/May/2011:22:26:46 +0800] [localhost/sid#d33140][rid#2351398/initial/redir#2] (3) [perdir C:/repository/trunk-php/] strip per-dir prefix: C:/repository/trunk-php/cache/index.php -> cache/index.php
127.0.0.1 - - [29/May/2011:22:26:46 +0800] [localhost/sid#d33140][rid#2351398/initial/redir#2] (3) [perdir C:/repository/trunk-php/] applying pattern '(.+)$' to uri 'cache/index.php'
...
The log statement in RED tells you the request is internally redirected to Apache rewrite module for handling again. Only when no rewrite rules have been matched by the current request will you see the following line in the rewrite log:
127.0.0.1 - - [29/May/2011:22:27:52 +0800] [localhost/sid#d33140][rid#228b510/initial/redir#2] (1) [perdir C:/repository/trunk-php/] pass through C:/repository/trunk-php/cache/index.php
Meaning that the Apache rewrite module is finally done with handling the request, and it's the next handler's job to handle it. In this case PHP engine will simply render C:/repository/trunk-php/cache/index.php.
So how do you add a handler and control the order of the handlers? To my disappointment I have NOT found any document online that answers this question. There is "AddHandler" directive in httpd.conf that's supposed to do that but loading the PHP module does that implicitly already.
Conclusion
So the conclusion is that ONLY if and ONLY when the request is NOT matched by ANY rewrite rule, the request is passed through to PHP handler. There is absolutely NO control you have in the rewrite rules to tell Apache to pass through to PHP handler right away! Not by using 'last' option [L] or 'pass through' option [PT] at the end of RewriteRule directive. If you don't agree let me know.
Knowing this fact you may find it impossible to handle the rewrite logic you have in mind. Think deeper and the solution will come. For example you may have a rewrite rule that you'd like the rewritten URL to go straight to PHP engine right away, and you add [L] to that rule which immediately internally redirects the rewritten URL to rewrite engine again (and therefore all the server variables such as %{QUERY_STRING}, %{REQUEST_FILENAME} and %{REQUEST_URI} are updated accordingly) and make the request go through each rule again. In that case you'll have to make sure the request is NOT matched by any RewriteRule and therefore passed through to PHP handler.
If you have any questions please let me know and I will do my best to help you!
Tampilkan postingan dengan label PHP. Tampilkan semua postingan
Tampilkan postingan dengan label PHP. Tampilkan semua postingan
Minggu, 29 Mei 2011
Senin, 07 Februari 2011
Solve PHP "Failed To Open Stream: No such file or directory in Unknown on line 0" Error
Question
I am running WAMP on Windows 7 and my WAMP directory is at C:\wamp. I specify 'C:\wamp\www' to be my document root in Apache's httpd.conf. I create a symbolic link, C:\wamp\www\myWebSite, to point to a directory, D:\myWebSite, where my website content is located. I got the following error in the browser when trying to access any of my web pages under D:\myWebSite:
Warning: Unknown: failed to open stream: No such file or directory in Unknown on line 0
Fatal error: Unknown: Failed opening required 'C:/wamp/www/index.php' (include_path='.;C:\php5\pear') in Unknown on line 0
I've looked at the logs but there's nothing helpful. Can anyone help?
Answer
This error occurs because the latest WAMP uses PHP 5.3 which does NOT support directory junction (soft link) or hard links in Windows (refer to How To Create A Soft Link In Windows for a tutorial on creating a soft or hard link in Windows). Questions? Given this situation you have at least the following two solutions:
Solution #1: Use an older version of PHP like 5.2I tried version 5.2.11 and soft links work fine. This means rolling back PHP module to 5.2. You may have to edit the path of the following line in httpd.conf:
LoadModule php5_module "c:/wamp/bin/php/php5.3.0/php5apache2_2.dll"
And you may have to do download other related modules as well. Of course you can try to find an older WAMP that uses PHP 5.2. In my opinion this is not a good solution as you need to pull many changes once you install WAMP, which goes against the purpose of using WAMP.
Solution #2: Use correct DocumentRootIn your Apache's httpd.conf change DocumentRoot to the actual website folder which in this case is D:\myWebSite, and change other related settings accordingly. Delete the soft link C:\wamp\www\myWebSite. This should be a much better solution as your website content can be located anywhere in your file system.
Any questions let me know!
I am running WAMP on Windows 7 and my WAMP directory is at C:\wamp. I specify 'C:\wamp\www' to be my document root in Apache's httpd.conf. I create a symbolic link, C:\wamp\www\myWebSite, to point to a directory, D:\myWebSite, where my website content is located. I got the following error in the browser when trying to access any of my web pages under D:\myWebSite:
Warning: Unknown: failed to open stream: No such file or directory in Unknown on line 0
Fatal error: Unknown: Failed opening required 'C:/wamp/www/index.php' (include_path='.;C:\php5\pear') in Unknown on line 0
I've looked at the logs but there's nothing helpful. Can anyone help?
Answer
This error occurs because the latest WAMP uses PHP 5.3 which does NOT support directory junction (soft link) or hard links in Windows (refer to How To Create A Soft Link In Windows for a tutorial on creating a soft or hard link in Windows). Questions? Given this situation you have at least the following two solutions:
Solution #1: Use an older version of PHP like 5.2I tried version 5.2.11 and soft links work fine. This means rolling back PHP module to 5.2. You may have to edit the path of the following line in httpd.conf:
LoadModule php5_module "c:/wamp/bin/php/php5.3.0/php5apache2_2.dll"
And you may have to do download other related modules as well. Of course you can try to find an older WAMP that uses PHP 5.2. In my opinion this is not a good solution as you need to pull many changes once you install WAMP, which goes against the purpose of using WAMP.
Solution #2: Use correct DocumentRootIn your Apache's httpd.conf change DocumentRoot to the actual website folder which in this case is D:\myWebSite, and change other related settings accordingly. Delete the soft link C:\wamp\www\myWebSite. This should be a much better solution as your website content can be located anywhere in your file system.
Any questions let me know!
Rabu, 18 Agustus 2010
How to Install WAMP, Java, Hibernate, and Eclipse
This is not an uncommon request for someone who wants to run a web server with an underlying database, backed by a server side programming language, assisted by several important one off or periodic tasks - me. Okay if it's just me then it might have been uncommon, but I have gone through a lot to finally have all these tools set up, so I'd like to share my experiences with you.
First of all I'd like to tell you why I am doing this. I'd like my web server (Apache) to serve dynamic content (PHP) driven by my database (MySQL) and dynamic content driven by one off or regular tasks (Java) with an easy way to manipulate my database content via Java objects (Hibernate), and I'd like to develop my Java code in a user friendly IDE (Eclipse). Last but not least I'd like to do ALL of these FREE, and they certainly are![]()
Let's get right down to it! Click on the next section.
Install and Configure WAMP ▶
First of all I'd like to tell you why I am doing this. I'd like my web server (Apache) to serve dynamic content (PHP) driven by my database (MySQL) and dynamic content driven by one off or regular tasks (Java) with an easy way to manipulate my database content via Java objects (Hibernate), and I'd like to develop my Java code in a user friendly IDE (Eclipse). Last but not least I'd like to do ALL of these FREE, and they certainly are
Let's get right down to it! Click on the next section.
Install and Configure WAMP ▶
Langganan:
Postingan (Atom)