I am trying different combinations using .htaccess to create friendly urls however none are working.
I have a php file called users.php like so:
<?php
use A\B\App\Url;
require_once("../../vendor/autoload.php");
$action = Url::getParam('action');
switch($action) {
case "add":
require_once('user/add.php');
break;
case "edit":
require_once('user/edit.php');
break;
case "delete":
require_once('user/delete.php');
break;
default:
require_once('user/list.php');
}
and based on the action parameter it sends you to a folder called user and a page like add or edit so the url is like so:
Url 1: http://project.blu/users?action=edit
Url 2 (with id parameter): http://project.blu/users?action=edit&id=1
I want to achieve these desired urls:
Url 1: http://project.blu/users/edit
Url 2 (with id parameter): http://project.blu/users/edit/1
I have tried this code but it does not do the trick and I am assuming because the switch statement needs to see the action parameter in order to know which page to display:
Url 1 tried solution:
RewriteRule ^users/([-\w]+)$ users.php?action=$1 [NC,L]
Url 2 tried solution:
RewriteRule ^users/([-\w]+)$/(\d+)$ users.php?action=$1&id=$2 [NC,L]
neither have worked out for me.
Note: I have other rules in place that remove the .php from the url and those work fine so for example this url http://project.blu/users
I can view the page no problem.
Here my full .htaccess file:
Options +FollowSymLinks -MultiViews
RewriteEngine on
# if URL has /pages/ then remove and redirect
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^Pages/(.+)$ /$1 [L,R=301,NC]
# landing page for app subdomain to show index.php
RewriteRule ^$ Pages/index.php [L]
# check & rewrite if a matching .php file exists in pages/ subdirectory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
# skip all files and directories from rewrite rules below
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^users/([\w-]+)/?$ users.php?action=$1 [NC,L,QSA]
RewriteRule ^users/([\w-]+)/(\d+)/?$ users.php?action=$1&id=$2 [NC,L,QSA]
# Redirecting to the error page when nothing is found
ErrorDocument 404 /error
I also have another .htaccess in the root of my folder with this content:
Options +FollowSymLinks -MultiViews
RewriteEngine on
# send all the traffic to /Pages/
RewriteRule .* src/Pages/$0 [L]
and this is an image of my folder structure:
Site root .htaccess:
Options +FollowSymLinks -MultiViews
RewriteEngine on
# send all the traffic to /src/
RewriteRule .* src/$0 [L]
You can use these rules in your src/.htaccess
:
Options -MultiViews
RewriteEngine On
# landing page for app subdomain to show index.php
RewriteRule ^$ Pages/index.php [L]
# skip all files and directories from rewrite rules below
RewriteCond %{ENV:REDIRECT_STATUS} 200 [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# route dummy URLs to their php files inside Pages/ folder
RewriteRule ^(users|locations)/([\w-]+)/?$ Pages/$1.php?action=$2 [NC,L,QSA]
RewriteRule ^(users|locations)/([\w-]+)/(\d+)/?$ Pages/$1.php?action=$2&id=$3 [NC,L,QSA]
# check & rewrite if a matching .php file exists in Pages folder
RewriteCond %{DOCUMENT_ROOT}/src/Pages/$1.php -f
RewriteRule ^(.+?)/?$ Pages/$1.php [L]
It is important to disable MultiViews
or content negotiation services of Apache.
Option MultiViews
(see http://httpd.apache.org/docs/2.4/content-negotiation.html) is used by Apache's content negotiation module
that runs before mod_rewrite
and makes Apache server match extensions of files. So if /file
is the URL then Apache will serve /file.html
.