URL rewriting with pure php and .htaccess

I am using php and mysql for one of my project. I have two pages as:
index.php
and packages.php

I am sending id and packagename from index.php using get method and package.php is retriving it and displaying the corresponding values.

Here is the way I am receiving the value in package.php

$getpackage = $_GET[“package”];

list($packageid, $packagename) = explode(":",$getpackage);
$url = strtolower(str_replace(' ', '-', $packageid)) . '-' . $packagename;

and here is my .htaccess file code

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^.]+)$ $1.php [NC]
RewriteRule ^package/([A-Za-z0-9_]+)/?$ package?$getpackage=$1 [QSA]

and here is the browser url output

http://localhost/abc/package?package=+1%3AHimachal+Main+

My requirement is abc/package/1/Himachal Main or …/1/Himachal-Main

I have tried many ways but i m not able to accomplish this.

Leads will be highly appreciated

Hi partap26 welcome to the forum

The rewriteRule regex looks off to me. But for a start, please post what this displays

$getpackage = $_GET["package"];
list($packageid, $packagename) = explode(":",$getpackage);
$url = strtolower(str_replace(' ', '-', $packageid)) . '-' . $packagename;
var_dump($url);

hi, I dont know where to check var_dump value but I tried it with echo $url in one of my label and the output is
1-Himachal Main

mean while I am learning for var_dump
Many Thanks

var_dump($url);
also displaying the same string as "string (15) “1-Himachal Main”

"

echo, print, print_r and var_dump have a lot of similarities.

this

1-Himachal Main

doesn’t look like

http://localhost/abc/package?package=+1%3AHimachal+Main+

the “%3A” is hex for a colon “:” and the “+” look to be spaces that have been urlencode-ed.

You didn’t post that part of the code?

Anyway, if you want 1/Himachal+Main or 1/Himachal%20Main I think the appending should be a slash not a hyphen, no? And no leading or trailing space character?

$url = strtolower(str_replace(' ', '-', trim($packageid))) . '/' . trim($packagename); 

Hi Mittineague, Many Thanks for reply…

I have resolved + and %3A is for “:” deliminator that I am using to seperate two passed values.
I am sending the values from index.php and the url is localhost/abc/index.php and some part of the code for index.php is as

 $id            = $row['packageid'];
                         $package_name  = $row['packagename'];
                         $packet        = $id.":".$package_name;
...
...

 echo     '<center><button type="submit" class="btn btn-primary btndetails" name="packagestring" value="'.$packet.'"  id="'.$id .'">View Details</button></center>';

Then I am retriving the value vua get method as

 include "script-php/common.php";
   $getpackage = $_GET["packagestring"];
    

and seperating the values using explode function and store into corresponding variables as:

 list($packageid, $packagename) = explode(":",$getpackage);
    $url = strtolower(str_replace('', '-', $packageid)).'-'.$packagename;

It must disply the url for localhost/abc/package/1-Himachal-Main
but i m getting as:

http://localhost/joys4ever/package.php?packagestring=1%3AHimachal+Main


Here is my .htaccess file with the below code:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ - [L]
RewriteRule ^package/([0-9a-zA-Z']+) package?$url=$1 [L]

I am worried about .htaccess file because I have only doubt on this
and I have checked in my local xampp server for the rewrite mod is enabled or not and it is enabled.

Please tell me where is the mistake now ???

If $packageid is always a single integer and $packagename might have spaces, it looks like the strtolower(str_replace( is around the wrong variable.

hi,
Sorry to say but as per my study about

str_replace(“replace”, “replace with”, “Hello replace”)

it will replace of hello replace with replace with .

the last parameter can be without space or with space. it does not matter.

any how, still the problem persists for me…

hi, Actually, its my mistake that i did not upload the latest code.
Below is the latest code

$url = $packageid . "/" .strtolower(str_replace(' ', '-', $packagename));

and the var_dump($url); is

"string(15) “1/himachal-main”

"

1 Like

I’m afraid I may have made things more confusing while trying to understand.

To be clear, please correct me if any of this is wrong.

  • There is PHP code that is generating what will be used as GET query strings. eg. the “some-name=some-value” part.
    htttp://example.com/some-folder/some-file.php?some-name=some-value
  • But you want HTTP Requests like
    http://example.com/some-folder/some-value
    to go to
    htttp://example.com/some-folder/some-file.php?some-name=some-value
    where “some-file.php” will use the GET “some-value” to determine what is output and displayed.
  • In this case “some-value” is an id and a name that look like folders in the browser address bar. eg.
    http://example.com/some-folder/id/name

If this is so, I think the “not a directory, not a file” lines are OK. What needs to be worked out is the rewriteRule that will match the HTTP Requests.

I think the “Making the Path Part of the Query String” at the bottom of this page is what you want
https://wiki.apache.org/httpd/RewriteQueryString

Maybe add a default to restrict malicious URLs

// PHP 7

$getpackage = $_GET['packagestring']] ?? '404-not-found';

// Not PHP 7
$getpackages = isset( $_GET['packagestring'] ) ? $_GET['packagestring'] : '404-not-found';


$packages = array(
'home',
'blog',
'aboutus',
'contact'
);

// needle, haystack
if ( in array( $packagestring,  $packages ) ) ):
   // No problem
else:
   // Beware
endif;

Edit:
Amended and unable to test on this tablet

Hahaha,
Many Thanks, Its interesting.

I am running the project in local mahcine using Xampp and I enabled rewrite module in .congfig file. OKay,

I have a project name abc(folder name) that contains project files with the below directory structure:

abc–
index.php
package.php
login.php

etc

css–
style.css
style1.css

etc

js–
some js files

img–

etc

When i load the project, index.php is the first page to be loaded and its working fine…
I have project id in index.php page and this is the way to pass to package.php

 while($row = $result->fetch_assoc()) {
                         $imgpath       = "img/packages/id-" .$row['packageid']."/1.jpg";
                         $night         = $row['packageduration'] - 1;
                         $id            = $row['packageid'];
                         $package_name  = $row['packagename'];
                         $packet        = $id.":".$package_name;
                         echo '<div class="form-group row">';
					 echo '<div class="offset-sm-12 col-sm-12">';
                                         
                                         echo     '<center><button type="submit" class="btn btn-primary btndetails" name="packagestring" value="'.$id.'"  id="'.$id .'">View Details</button></center>';
					 echo '</div>';
				       echo '</div>';
    }
              }

This is the way to get vlaues of index.php in package.php

session_start();
ob_start();
 include "script-php/common.php";
 
 if(!isset($_GET["packagestring"])){
     header('location:index.php');
 }elseif (isset($_GET["packagestring"])) {
      $getpackage = $_GET["packagestring"];
      echo $getpackage;
}

for index.php the url is:
localhost/abc/iindex

and for package.php the url is:
localhost/abc/package?packagestring=1

but i need localhost/abc/package/1 only

as packagestring is the global variable passed by index.php and retriving in package.php via $_GET[‘packagestring’];

here is the .htaccess code

Options +Indexes 
Options         +FollowSymLinks 
RewriteEngine   On 
RewriteCond     %{REQUEST_FILENAME}     !-f 
RewriteCond     %{REQUEST_FILENAME}     !-d 
RewriteRule ^package/([0-9a-zA-Z_-]+)/?$ package.php?packagestring=$1
RewriteRule ^([^\.]+)$ $1.php [NC,L]

First rewrite rule to convert the get value url into proper way
and second for hiding the extension(.php)

If i check manually with http://localhost/abc/package/1, my css,js,imgs does not load
But the thing is that why i need to enter it manually, it should automatically convert to localhost/abc/package/1 by .htaccess

Now come to your reply:
Frist point is correct some name means $_GET variable name that contains some-value
htttp://example.com/some-file.php?some-name=some-value (somefilename = package.php, some-name = packagestring, some-value = 1)

I want http://example.com/some-file/some-value (not some -folder)

Hi to all,
I have resolved the issue by making some changes in php function and .htaccess…

Many Thanks for your valuable support

1 Like

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