Is it possible to combine these two .htaccess files? - php

I have to completely replace an existing website. The current site is completely spagetti code with some rewrite rules to mimic friendly urls.
There are some mission critical issues that can't be resolved with the current architecture and database structure, so for a time both code bases need to live side by side.
This is the current .htaccess
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^([^/]+)/$ $1.html
RewriteRule ^([^/]+)/$ $1.php
RewriteRule ^([^/]+)/([^/]+)/$ $1.php?q=$2
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/$ $1.php?q=$2&r=$3
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ $1.php?q=$2&r=$3&s=$4
I'm replacing it with a zend framework site, but it routes everything through the index.php file for the routing
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f [NC,OR]
RewriteCond %{REQUEST_FILENAME} -d [NC]
RewriteRule .* - [L]
RewriteRule .* index.php
Does anyone have any idea how I can combine the two until the original can be completely replaced?

If you can map your old URLs to Zend Url someway, then it would be rather easy. Let's say you had
http://foo.bar.com/something.php?q=arg1&r=arg2
then if you have this functionality working in Zend code, then you must also have valid URL there, like
http://foo.bar.com/something/q/arg1/r/arg2
If so, all you need is to rewrite that old URLs to Zend URL and instead of doing internal redirection, do HTTP redirection, i.e. (out of my head, not tested):
RewriteCond %{QUERY_STRING} ^q=(.*)&r=(.*)^
RewriteRule ^something\.php$ /something/q/%1/r/%2? [R=301,L]
Mind the trailing "?" which tells mod_rewrite NOT to attach original query string to rewritten one (otherwise you would end with /something/q/%1/r/%2?q=X&r=y. Note we do regular 301 HTTP redirection here.

They're not going to merge very easily, it's a matter of which one you want to have precedence. You could add a few more conditions to make sure everything doesn't get routed as a $1.php file, then add the zend rules to the end.
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^([^/]+)/$ $1.html
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^([^/]+)/$ $1.php
RewriteCond %{REQUEST_URI} ^([^/]+)/
RewriteCond %{DOCUMENT_ROOT}/%1.php -f
RewriteRule ^([^/]+)/([^/]+)/$ $1.php?q=$2
RewriteCond %{REQUEST_URI} ^([^/]+)/
RewriteCond %{DOCUMENT_ROOT}/%1.php -f
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/$ $1.php?q=$2&r=$3
RewriteCond %{REQUEST_URI} ^([^/]+)/
RewriteCond %{DOCUMENT_ROOT}/%1.php -f
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ $1.php?q=$2&r=$3&s=$4
# other rules
RewriteCond %{REQUEST_FILENAME} -f [NC,OR]
RewriteCond %{REQUEST_FILENAME} -d [NC]
RewriteRule .* - [L]
RewriteRule .* index.php

Related

RewriteCond subdirectory is not working

I am trying to do RewriteRule for subdirectory and I could not do it.
This is the code:
RewriteCond %{REQUEST_URI} !^/subfolder
RewriteCond %{DOCUMENT_ROOT}/subfolder%{REQUEST_URI} !-f
I use the following code with the above as well to remove the .php extension and add a trailing slash at the end.
RewriteRule ^([^/]+)/$ $1.php
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]
I can access any page except index.php
I need someone to help me fix this issue so I can access the pages/files in the subdirectory.
Thank you
You need to explicitly check if the php file exists before you add the .php extension. And remember that rewrite conditions only apply to the immediately following rule, so you need to duplicate them if they need to apply to multiple rules. Also, you want all your redirects to happen before any routing or rewrites:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^/]+)/$ $1.php [L]
RewriteCond %{DOCUMENT_ROOT}/$1/$2.php -f
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php
# whatever subfolder rewrites you need can go here

how to remove php extension from the files in root

Hello i want to convert php urls into SEO urls every thing is working fine at my end but the files in the root doesn't work here is the code which i am using in htaccess
RewriteEngine On
RewriteRule ^([a-zA-Z0-9-/]+)$ show_staff.php?url=$1
RewriteRule ^([a-zA-Z0-9-/]+)/$ show_staff.php?url=$1
RewriteRule ^([a-zA-Z0-9-/]+)$ show_users.php?url=$1
RewriteRule ^([a-zA-Z0-9-/]+)/$ show_users.php?url=$1
but if i add these lines right after the above lines the files which are in root doenst work without .php extention here is what i want to add here i want to mention without or with using below code the above code works fine for me
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* $0.php [L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)index\.php($|\ |\?)
It looks like your stuff is all in the wrong order. Some things:
If you don't have an L flag for a rewrite, the rules after will continue to process the rewritten request. So you want to use the L flag.
Rewrite conditions only apply to the immediately following rule, so you've got a condition that's just dangling somewhere and not being used.
The show_users.php rules will never work the way you've set things up, the regex pattern is the same, so no matter what, your requests will always go to show_staff.php.
Your rules aren't in the right order, two things need to happen if I'm guessing what you're trying to do. You need to match against a request with a php extension and externally redirect the browser, then you need to internally rewrite that request back to the URI with a php extension.
So something like:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} \ /+([^/]+)\.php
RewriteRule ^ /%1 [L,R]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f
ReweriteRule ^ %{REQUEST_URI}.php [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([a-zA-Z0-9-/]+)/?$ show_staff.php?url=$1 [L]
You can use this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteBase /
## hide .php extension
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1%2 [R=302,L,NE]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f [NC]
RewriteRule ^(.+?)/?$ $1.php [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9/-]+)$ show_staff.php?url=$1 [L,QSA]

htaccess rewrite rules, or a PHP issue?

I am writing a small web app mainly used just by myself so I'm not interested in fancy frameworks and page templating etc.
I need to be able to rewrite these urls:
/?page=parks
/?page=park&id=1
into
/parks
/park/1
Now, I have got very close with the following rules:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^([^/]*)$ /?page=$1 [L]
RewriteRule ^([^/]+)/([^/]+)$ /?page=$1&id=$2 [L]
and this works for most of the pages I have, but if I do the URL /settings it breaks. If I echo $_GET['page'] I get "inc". I have no idea why. Is this a PHP issue, or are my rules wrong?
You don't need RewriteCond %{REQUEST_FILENAME}\.php -f condition for this.
You can use:
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^([^/]+)/?$ /?page=$1 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/?$ /?page=$1&id=$2 [L,QSA]

Apache mod_rewrite not redirecting to PHP, but redirecting to other URLs

i have a code in my .htaccess file.. It redirect every .php to non php. I want it to only direct one php file and dont redirect the rest.. forexample i want abc.php to be abc but bcd.php stays as bcd.php.. How can i modify this script to get this result? thanks.
RewriteEngine on
#Redirect non-php to php and stop futher processing
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
#redirect .php to non-php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*)\.php$ $1 [R=301,L]
This code should work for you:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+(abc)\.php[?\s] [NC]
RewriteRule ^ %1 [R=301,L]
#Redirect non-php to php and stop futher processing
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
Important to use %{THE_REQUEST} here which represents original HTTP request as received by Apache to avoid looping. %{THE_REQUEST} doesn't get rewritten with various rewrite rules as opposed to the case with URI pattern used for RewriteRule.
Put the rule with exception and L flag before the general RewriteRule:
RewriteEngine on
#redirect abc.php to abc
RewriteRule ^abc\.php$ abc [R=301,L]
#Redirect non-php to php and stop futher processing
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteCond %{REQUEST_URI} ! abc$
RewriteRule ^(.*)$ $1.php [L]

Cascading resource selection using mod_rewrite

I'm looking into setting up an application where there is a core and a project namespace, where core is the default fallback to the project customisation. to this end id like to be able to cascade various resources like css, javascript etc. for the purposes of the excersize, ive simplified this as
./.htaccess
./first/firstonly.txt
./first/both.txt
./second/secondonly.txt
./second/both.txt
expected behaviour would be a request would check for existence in first before looking in second, and finally throwing 404.
for baseurl/firstonly.txt would hit ./first/firstonly.txt (200),
whereas baseurl/secondonly.txt would try ./first/secondonly.txt (404) then ./second/secondonly.txt (200).
baseurl/both.txt would hit ./first/both.txt (200) and go no further.
baseurl/nonexistant.txt (404) would run through the cascades and return 404.
I'm fairly competant with mod_rewrite, so dont feel the need to talk basics here. What would be the most efficient (sane) way of implementing this? Speed concerns aside, as most of the time things will be found on the first hit.
Try these rules:
RewriteEngine on
RewriteRule ^(first|second)/ - [L]
RewriteCond %{DOCUMENT_ROOT}/first/$0 -f
RewriteRule ^[^/]+$ first/$0 [L]
RewriteCond %{DOCUMENT_ROOT}/second/$0 -f
RewriteRule ^[^/]+$ second/$0 [L]
Some other potential solutions
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^first
RewriteCond %{REQUEST_URI} !^second
RewriteRule ^([^/]+\.?[^/])*$ first/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^second
RewriteRule ^first/([^/]+\.?[^/])*$ second/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^(first|second).*$
RewriteRule .* /404.html [L]
or
RewriteCond %{REQUEST_URI} 404.html
RewriteRule .* - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^first
RewriteCond %{REQUEST_URI} !^second
RewriteRule ^([^/]+\.?[^/])*$ first/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^second
RewriteRule ^first/([^/]+\.?[^/])*$ second/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^(first|second).*$
RewriteRule .* /404.html [L]
In my personal testing im noticing that the -f check is accurate only against a full pathname, which makes things tricky if you're not in the document root. Could this be addressed by rewriting to the file, and then doing the -f on the request_uri?
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule ^Public/(.*)$ Application/Public/$1 [L]
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
RewriteRule ^(css|scripts|images|assets|flash)/(.*)$ Public/$1/$2 [L]
This is the final working solution (outside the sandbox example above).

Categories