Rewrite urls for a php switch statement

Viewed 352

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:

enter image description here

1 Answers

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.

Related