1

Trying to merge two different .htaccess blocks.

  1. for hiding *.php extension:
RewriteRule ^([^\.]+)$ $1.php [NC,L]
  1. for redirecting to specific web is string matched with MySQL row:
RewriteRule ^([a-zA-Z0-9_-]+)$ friendly_url.php?friendly_url=$1

If one works, other gets blocked, for example this way works friendly_url, but it doesn't hide PHP extension:

RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)$ friendly_url.php?friendly_url=$1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]

My php code contains simple query:

$sql = "SELECT * FROM url WHERE friendly_url ='$friendly_url'";
$result = mysqli_query($connection, $sql);

if (!mysqli_num_rows($result) > 0) {
    echo "page does not exist";
    die();
} else {
    echo "page exist";
}

My end goal is to check if file.php exist, if so redirect to example.com/file, then check if in mysql friendly_url exist, if so - redirect to example.com/$friendly_url else echo "page does not exist";

Both .htaccess blocks works, but only if one is deleted.

MrWhite
  • 43,179
  • 8
  • 60
  • 84
  • 1
    **Warning:** You are wide open to [SQL Injections](https://php.net/manual/en/security.database.sql-injection.php) and should use parameterized **prepared statements** instead of manually building your queries. They are provided by [PDO](https://php.net/manual/pdo.prepared-statements.php) or by [MySQLi](https://php.net/manual/mysqli.quickstart.prepared-statements.php). Never trust any kind of input! Even when your queries are executed only by trusted users, [you are still in risk of corrupting your data](http://bobby-tables.com/). [Escaping is not enough!](https://stackoverflow.com/q/32391315) – Dharman Mar 15 '22 at 14:54

1 Answers1

1
RewriteRule ^([a-zA-Z0-9_-]+)$ friendly_url.php?friendly_url=$1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]

Reverse the two rules and instead of checking that the request does not map to a file in the second rule, check that the corresponding .php exists before rewriting.

For example, try the following instead:

# Rewrite to ".php" file if it exists
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^.]+)$ $1.php [L]

# Otherwise root requests to "friendly.php" instead
RewriteRule ^([\w-]+)$ friendly_url.php?friendly_url=$1 [L]

The \w shorthand character class is the same as [a-zA-Z0-9_].

There is no need to backslash-escape literal dots in the regex character class.


My end goal is to check if file.php exist, if so redirect to example.com/file, then check if in mysql friendly_url exist, if so - redirect to example.com/$friendly_url else echo "page does not exist";

This is basically what the above rules now do. However, it's not possible to check if the MySQL friendly_url exists in .htaccess. Any URL that matches the pattern ^([\w-]+)$ (that doesn't exist as a .php file) will be rewritten to friendly_url.php. Only URLs that do not match that pattern and do not exist will then drop through to a 404.

MrWhite
  • 43,179
  • 8
  • 60
  • 84