Need Help with URL Rewriting and Query Strings

I am playing around with having a front controller in a personal project, so my directory structure is like ‘localhost/business/index.php?p=about’ or ‘localhost/business/index.php?p=display_client’. I successfully used mod_rewrite to get ‘localhost/business/about’ and ‘localhost/business/display_client’ as follows:

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /business/
RewriteRule ^(home|client_list|display_client)/?$      index.php?p=$1 [L]
</IfModule>

My problem now is that I have moved on to querying a specific client so that sometimes the URL will be ‘localhost/business/display_client?id=23’ .

There are two issues here:

  1. I can’t access the client id number here. When I use var_dump on $_GET I end up with
array(1) {
  ["p"]=>
  string(14) "display_client"
}

which means there is no $_GET[‘id’]

  1. I do not know how to change ‘localhost/business/display_client?id=23’ to ‘localhost/business/display_client/23’, which is what I would really love to have.

Try displaying var_dump( $_SERVER );

Do you want to see all of it, or is this part sufficient? It is telling me exactly what I found before, but I don’t know how to fix the problem:

   ["REQUEST_METHOD"]=>
  string(3) "GET"
  ["QUERY_STRING"]=>
  string(16) "p=display_client"
  ["REQUEST_URI"]=>
  string(30) "/business/display_client?id=25"
  ["SCRIPT_NAME"]=>
  string(19) "/business/index.php"
  ["PHP_SELF"]=>
  string(19) "/business/index.php"

Would I need two rewrite rules - one for ‘localhost/business/index.php/p=display_client’ and ‘localhost/business/display_client/id=23’ ?

Try including this temporary “_menu.php” file in every index.php

<?php 

$ls = [
    'business?id=23&path=base',
    'business/?id=23&path=base',
    'business/home?id=23&path=home',
    'business/display_client?id=23&path=display_client',
    'business/client_list?id=23&path=client_list',
];
foreach($ls as $l):
    echo '<br>' .'<a href="http://localhost/' .$l .'">' .$l .'</a>';
endforeach;
echo '<hr>';
echo '<pre style="color:#000; baclground-color:#ddd;">';
    $xs = parse_str($_SERVER['QUERY_STRING'], $xx);
    echo '<br>parse_str($_SERVER["QUERY_STRING"], $xx); ===> ';
    print_r($xx);
    echo '<br>';

    $qry = $_SERVER['QUERY_STRING'];
    echo '<br>' .strstr($qry,'=', true);
    echo '<br>' .strstr($qry,'=', false);
    echo '<br>';
	print_r( $_SERVER );    
echo '</pre>';


### Output ``` parse_str($_SERVER["QUERY_STRING"], $xx); ===> Array ( [id] => 23 [path] => base )

parse_str($_SERVER[“QUERY_STRING”], $xx); ===> Array
(
[id] => 23
[path] => client_list
)

parse_str($_SERVER[“QUERY_STRING”], $xx); ===> Array
(
[id] => 23
[path] => display_client
)

parse_str($_SERVER[“QUERY_STRING”], $xx); ===> Array
(
[id] => 23
[path] => home
)

Sorry I took so long to respond - busy weekend. I did what you suggested, but I really don’t understand what to do with this. This is my first foray into something like this.

My end goal is to change http://localhost/business/display_client.php to http://localhost/business/display_client and http://localhost/business/display_client.php?id=23 to http://localhost/business/display_client/23

The magic search words are “htaccess pretty urls” :slight_smile:
File: .htaccess

# PRETTY URLs
Options +FollowSymLinks    
RewriteEngine On   
RewriteCond %{REQUEST_FILENAME} !-f          
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L] 

The above restricts problematic characters and correctly formats all URLs.
Allowed Characters:

Try this index.php:

<?php 
echo file: __FILE__;
echo '<br>';
require './_menu.php';

// Script required to redirect to the correct path and to pass parameters;
  if( count($params) === 0):
    echo 'no need to use header("Location: params[0]"); ';

  else:
    switch( $params[0] ):
      case 'home':
       $newPath = 'home'; 
      break;

      case 'business':
       $newPath = 'business'; 
      break;

      case 'display_client':
       $newPath = 'display_client'; 
      break;

      case 'client_list':
       $newPath = 'client_list'; 
      break;
    endswitch;
  endif;
  if( isset($newPath) ):
    chdir($newPath);
    require 'index.php';
  endif;

# FALL THROUGH TO index.php -> content



File: _menu.php

<?php 
echo '<h3>file: </b> _menu.php</h3>';

$ls = [
    'business?id=23&path=base',<br>

    'business/?id=23&path=base',
    'business/xhome?id=23&path=home',
    'business/xdisplay_client?id=23&path=display_client',
    'business/xclient_list?id=23&path=client_list',
    'business/xid/23',
    'business/xid/23',
    'business/xhome/id/23',
    'business/xdisplay_client',
    'business/xdisplay_client/id',
    'business/xdisplay_client/id/23',
    'business/xclient_list',
    'business/xclient_list/id',
    'business/xclient_list/id/23',
];
foreach($ls as $l):
    echo '<br>' .'<a href="http://localhost/' .$l .'">' .$l .'</a>';
endforeach;
echo '<hr>';

//====================================
function splitUrl( $url, $title = '')
{
    echo '<pre style="width:88%; margin:1em auto; padding: 1em; color:#000; background-color:#fee;">';
        $old = ['//','=', '&', '?'];
        $new = ['/', '/', '/', '/'];
        $tmp = str_replace($old,  $new, $url);

        #echo '$URL: ', $tmp;

        $paramAll = explode('/', $tmp);
        # echo '<br>' .print_r($params);
        $params = [];
        foreach($paramAll as $param):
            if( ''===$param):
              # do nothing  
            else:    
               $params[] = $param; 
            endif;   
         endforeach;    
        #echo '<br>_menu.php -> $params: '; 
        #print_r($params);
        #var_dump($params);
    echo '</pre>';

return $params;
}# 

$params = splitUrl ($_SERVER['REQUEST_URI'], 'REQUEST_URI');
# splitUrl ($_SERVER['QUERY_STRING'] , 'QUERY_STRING');

Using a PHP FrameWork is far easier :slight_smile:

Thank you. I will try that out.

Using a PHP FrameWork is far easier :slight_smile:

I know that. :slight_smile: I use frameworks for client projects (CodeIgniter and Laravel), but for some of my fun personal projects, I like to do things with vanilla PHP for the learning aspect. I find if I only use the frameworks, I forget a lot of things because I am not using them, or I don’t learn certain aspects because they are taken care of for me by the frameworks.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.