Murad
Murad

Reputation: 167

PHP url is not working with slash on it

I have got this htaccess code

RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule Topics/([^/]+)$ topics.php?topic_name=$1 [L,QSA]    

So all my URLs are presented like this
Topics/Eminem

But when i have / in my topic name then URL returns "Not found".
For example AC/DC becomes Topics/AC%2FDC but url refuses accepting it.

Upvotes: 1

Views: 520

Answers (4)

MrWhite
MrWhite

Reputation: 45914

But when i have / in my topic name then URL returns "Not found".

You actually have 2 main problems here, only the first is addressed by the current answers:

  1. Your RewriteRule pattern (ie. ([^/]+)) does not allow slashes (/) in this part of the URL, so AC/DC will never be matched. As stated in the other answers, you need to modify this pattern to something like (.+). (Although, ideally, you should be as restrictive as possible.) NB: The pattern matches the %-decoded URL, so you need a regex that matches AC/DC, not AC%2FDC.

  2. Apache will, by default, block any URLs that contain an encoded slash in the path part of the URL ie. %2F. In this situation, it will automatically return a system generated 404 Not Found before mod_rewrite gets to have a go. This is a security feature. And is most probably the result you are seeing here. If you need encoded slashes in the URL then you'll need to explicitly enable this with AllowEncodedSlashes On in the Apache server config (this can't be enabled in .htaccess).

    Note that, as mentioned, this is an Apache generated 404 message. If you have a custom 404 defined, then you should notice a difference.

Reference:
https://httpd.apache.org/docs/2.4/mod/core.html#allowencodedslashes

RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule Topics/([^/]+)$ topics.php?topic_name=$1 [L,QSA]

UPDATE: These rules conflict. The first rule will likely "win" for most of your URLs. You need to be more specific in the RewriteRule pattern. For instance, a URL like Topics/AC%2FDC will also match the first rule, so the second rule is never processed.

Upvotes: 0

arkascha
arkascha

Reputation: 42935

Your pattern explicitly prevents the acceptance of a further slash in the request URL, the [^/] describes a character set that may contain anything but a slash. You can modify it such that it accepts and rewrites an arbitrary character set:

RewriteEngine on
RewriteRule ^/?Topics/(.+)/?$ topics.php?topic_name=$1 [L,QSA] 

However keep in mind that this now rewrites all incoming requests starting with /Topic/.

I also modified the pattern slightly so that it is a bit more robust and will work likewise in the http servers host configuration and in dynamic configuration files (".htaccess")...


And a general hint: you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).


UPDATE:

You added another existing rewrite rule that certainly will interfere here. Actually I would expect it to create an endless rewrite loop... I would recommend to add two conditions to that additional rule limiting the application of that rule to only those requests that do not immediately hit an existing file and that do reference an existing file with added .php extension. That probably is what you want:

RewriteEngine on

RewriteRule ^/?Topics/(.+)/?$ topics.php?topic_name=$1 [L,QSA] 

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([^\.]+)$ $1.php [NC,L]

Upvotes: 2

dlaxar
dlaxar

Reputation: 549

In the regex Topics/([^/]+)$ the [^/]+ part means "everything that is more than one character up to a '/' symbol". So when you try to match Topics/AC/DC the [^/]+ part will only match AC. And since you added a $ sign to the end (which means "this is the end of the input") the string won't match.

For more information see this demo: https://regex101.com/r/GJTDik/1

Upvotes: 1

Álvaro González
Álvaro González

Reputation: 146540

You are filtering out slashes and complaining that slashes do not match. If you want to capture everything, just do so:

RewriteRule Topics/(.+)$ topics.php?topic_name=$1 [L,QSA]

Upvotes: 1

Related Questions