I'm having a hard time figuring out why my rewrite rules work perfectly online (the site is up and running), but fail when I'm trying to run a local copy on my mac. I'm not using MAMP o LAMP and I have installed apache and php manually. Apache is 2.2.26 and php is 5.4.20.
There are more rules in my .htaccess file, but the ones I'm concerned about are these two:
RewriteRule ^category/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?$ category.php?slug=$1&page=$2 [L]
RewriteRule ^category/([a-zA-Z0-9_-]+)/?$ category.php?slug=$1 [L]
Basically the variables are not being passed to the php file. Besides this, the rule below works perfectly fine! Even on my local setup I can't see any difference except the fact that I have two rules beginning with "^category/"
RewriteRule ^project/([a-zA-Z0-9_-]+)/?$ project.php?slug=$1 [L]
Any clue why this works online (ubuntu) but fails locally?
I'm going to guess that you have multiviews turned on. This causes mod_negotiation to fuzzy match requests to file-path resources. So when it sees /category/something and sees the file category.php, it sends the request right to the php file (in this case, ala PATHINFO) thus completely bypassing mod_rewrite.
Try turning multiviews off:
Options -Multiviews
Related
We are currently trying to switch our web server to apache 2.4 running with PHP via php-fpm and mod_proxy_fcgi in Docker environment.
We used to have URL rewrite rule as follows in Apache config and it worked well with previous "mod_php" setup:
RewriteRule ^/test$ /test.php [QSA]
However, once we switch to Apache 2.4 + PHP-FPM with following setup in Apache config, the php stops working for this URL (/test):
RewriteEngine On
RewriteRule ^/test$ /test.php [QSA]
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php:9000/var/www/html/$1
With this setting, the URL http:///test leads to a plain text on the screen showing the content of "test.php", which means the page was not being fed into PHP at all; however, if I change the rewrite rule flag from "QSA" to "R", PHP starts to work and everything is fine.
It seems "ProxyPassMatch" line is executed before RewriteRule when "R" is not there. So if that is the case, does anybody have solution to this problem? I'm sure there are a lot of web sites using clean URLs, which usually don't have "php" extension, for PHP pages...
Thanks in advance.
I think it has to do with the fact that QSA does not do 30x HTTP redirect as R does, so there is no second request (as in case with R modifier) and therefore no request with .php at the end and therefore this is not fed to PHP interpreter. As a quick solution I would consider modification of the ProxyPassMatch regexp to add the test and any other non-php ending URLs to be supplied to PHP
I used xampp in the past in order to develop websites on a local computer, but I recently found it less cumbersome to simply start a server using the PHP -S localserver:8000 where 8000 is the port number. I managed to get phpmyadmin working that way and access databases. So all was fine ... until I tried to re-use redirecting rules within a .htaccess file.
The rules work well on the my web provider's servers, but it doesn't work on localhost. I assume there's something to do in order to turn the re-write rules on but since I am not longer using xampp, I don't know if there's still something like Apache running in the background, etc. If someone has experience with this setup, I would like to know how or if this can be be done.
EDIT
The redirect is basic:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule lessons/(.*)$ page.php?url=$1
And to make the question more meaningful (addressing some of the comments below), I think Finwe answered my question rightly, that is: "this doesn't work with the PHP approach, .htaccess is specific to Apache".
My question wasn't about "what alternative solution do I have". The solution I would use is probably to go through a combination of AJAX/PHP to solve the limitation but that's surely not the most straightforward workaround.
PHP's internal server does not recognize .htaccess files. That is a privilege of using Apache server.
The redirects must be a part of your PHP application to retain them across all platforms.
With PHP internal server, you can run it with a PHP file parameter.
If a PHP file is given on the command line when the web server is started it is treated as a "router" script. The script is run at the start of each HTTP request. If this script returns FALSE, then the requested resource is returned as-is. Otherwise the script's output is returned to the browser.
PHP -S localserver:8000 router.php
The script could then replace the htaccess file checking and "routing" requests to lessons/.
For more complex applications I would suggest using a "real" webserver such as Apache or nginx as the built-in server has more limitations, such as hanging on external HTTP requests, as it is only single threaded.
This is what I do to get htaccess working properly on localhost. I create a virtual host for each app am building
<VirtualHost *:8000>
ServerName app.local
DocumentRoot "C:/path/htdocs/app"
<Directory "C:/path/htdocs/app">
Options +Indexes +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require local
</Directory>
</VirtualHost>
With this, I can now access my app from my browser using the local domain name app.local. I found out that htaccess works well following this which is apparently the same thing with online server you access with a domain name
Okay, so this problem has completely stumped me and the other devs I work with. Here is the rundown:
I have a local dev environment setup with Mac Apache2 pointed at /Users/myusername/Sites/
Within /Sites I have two folders, /site-1 and /site-2, both of which have virtual hosts pointed at them site-1.dev & site-2.dev. Both site-1 and site-2 are running local installs of PerchCMS.
Within /site-2 I have an .htaccess file which I am trying to set up a URL rewrite that takes the URL /detail/slug-here and translates it into /detail.php?s=slug-here
I have tried the following rewrites (at the suggestion of PerchCMS support) and both have failed to pass the s param:
RewriteRule ^detail/([a-zA-Z0-9-/]+)$ detail.php?s=$1 [L]
RewriteRule ^site-2/detail/([a-zA-Z0-9-/]+)$ /site-2/detail.php?s=$1 [L]
Additional info:
Yes mod_rewrite is enabled in apache... in the same .htaccess file it totally works if I do a simple rewrite like this...
RewriteRule dangerzone.html index.php
One odd behavior that I've noticed is that if I remove everything from .htaccess I can still pull up detail.php by pointing my browser at /detail/test-item-1...(yes I have restarted my server) so its behaving as if there is still some sort of rewrite in place and loading detail.php sans param just as it continues to do with the rewrite in place - is this a clue that there is something off somewhere else in my server config? Note, RewriteRule dangerzone.html index.php does NOT work once it is removed from .htaccess.
Have this code in your site root .htaccess (inside /site-2/):
Options -MultiViews
RewriteEngine On
RewriteRule ^detail/([a-zA-Z0-9/-]+)/?$ detail.php?s=$1 [L,QSA,NC]
Important is to turn off MultiViews options here. Option MultiViews is used by Apache's content negotiation module that runs before mod_rewrite and makes Apache server match extensions of files. So /file can be in URL but it will serve /file.php.
I have a website that requires mod-rewrite to function well, but it seems to not be functional on the Network Solutions shared server we're running on. Network Solutions promises it's installed but won't provide any further support without additional payment.
I placed a simple test at the following folder which contains two files. The first, ".htaccess" contains the following text:
RewriteEngine On
RewriteRule ^link([^/]*).html$ rewrite.php?link=$1 [L]
The second is the PHP script which tests it, available here:
http://www.oceanhousefloridakeys.com/testmr/rewrite.php
All I see is that mod-rewrite is installed (no error messages showing) but the rewriteRule is not working. Can anybody see why this script isn't working... is there anything I can do to get it running, or is Network Solutions not telling the whole truth?
It looks like your script resides inside a sub-directory. In that case it's the best solution to set the RewriteBase to the correct path (before any RewriteRule):
RewriteEngine On
RewriteBase /testmr/
RewriteRule ^link([^/]*).html$ rewrite.php?link=$1 [L]
Here's the contents of .htaccess:
Options -Indexes
RewriteEngine On
RewriteBase "/"
# Disallow direct access to PHP files.
RewriteRule ^(.*)\.php$ $1 [F,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(?<!common/dispatch\.php/)(.*)?$ common/dispatch.php/$1 [NS,L]
Essentially I have all my pages (PHP files) arranged as they would be for direct access without mod_rewrite but I also have dispatch.php in a directory called common, through to which I want all requests to be directed so that I can do some processing before the page script is executed.
It's basically the same idea as used by most frameworks, except I want the page hierarchy to be at the top level and the dispatch script to be kept out of the way with some other bits and pieces in its own subdirectory.
This script works fine on my development machine (which is running PHP as mod_php), but on the production machine it produces an error saying "No input file specified." if running under FCGI. Under normal CGI it works for the most part but if, for example, I go to /foo/bar (with trailing slash missing) and /foo/bar is a directory in the docroot, it sends me to /foo/bar/?/foo/bar. The rest of the script works fine but I don't really want my URIs getting mangled like this, and ideally I'd like to be able to use FCGI as well.
A potential fix for the problem with FCGI seems to be to put the matched $1 in the query string (i.e. after a ?), but this causes all sorts of other odd behaviour that I haven't been able to fix. Is there a straightforward way of fixing this?
Would it not be easier just to use the auto_prepend_file directive in php?