URL rewriting - PHP & MySQL: Novice to Ninja

Dear All,
in Boston PHP Meetup currently we are currently using this book PHP and MYSQL6 edition which Kevin Yank and TOM Butler co-author and I am the assistant organizer.
1). I want to ask, how w can be talking to the authors if we have any area that is not clear to us?
2) I am having problem with this code $route = ltrim(strtok($_SERVER['REQUEST_URI'], '?'), '/'); on page 376 of the e-book. I am using Xampp which uses apache server and my index.php is not inside the root directory is in
sir, instead that this code ($_SERVER['REQUEST_URI'], '?') should just add index.php to the end of my url, it always add the who url to the initial one like this
http://localhost/phpmysqlnoviceninja6th/Chapter09/public/phpmysqlnoviceninja6th/chapter09/public/ .
please, what do I do for code to just add the index.php to the url?
I need the solution ASAP to continue enjoying the book.

1 Like

I don’t know, but if you have PHP-related queries you can post them on here and people will try to help, whether they’re authors or not. Plenty of people will have read the book and maybe encountered the same issues. But post the code you’re asking for help with, not just a page number, so that people who don’t have the book to hand, or don’t have the same edition, may still help.


I have added book and support tags toy your post.
@TomB is sometimes active in the forums to offer help.

Hi olaoyesunday,

I am having problem with this code $route = ltrim(strtok($_SERVER[‘REQUEST_URI’], ‘?’), ‘/’); on page 376 of the e-book. I am using Xampp which uses apache server and my index.php is not inside the root directory is in

The line of code you quoted takes the URL e.g. and extracts the parts between the domain name and the question mark (if there is one, otherwise the end of the URL.

The URL i mentioned would set the $route variable to /jokes/edit which is then used for routing to a controller action.

To use index.php in a different subdirectory such as yours, the $route variable will contain the string /phpmysqlnoviceninja6th/Chapter09/public/joke/list.

You’ll need to remove /phpmysqlnoviceninja6th/Chapter09/public from the string. The simplest way is to add the line

$route = str_replace('/phpmysqlnoviceninja6th/Chapter09/public', '', $route)

There is likely a better way of working out what the extra part of the URL is from various $_SERVER variables. However, I recommend against hosting websites like this from a single URL. You’re better off setting up virtual hosts on your apache installation so that you can have , for example http://phpnoviceninja.localhost/.


Thanks Sam47 for linking me with TomB.
Dear TomB,
thanks for your prompt reply and explanation. I tried using string replacement but it still not work. do I need to do anything to my apache server. I checked my apache serve and it supported mod rewriting I even installed wordpress on it check it htaccess file it shows that it supported mod rewriting. I typed $route = str_replace(‘/phpmysqlnoviceninja6th/Chapter09/public’,‘’, $route); after $route = ltrim(strtok($_SERVER[‘REQUEST_URI’], ‘?’), ‘/’);
then entering this url “localhost/phpmysqlnoviceninja6th/Chapter09/public/” it is still showing “http://localhost/phpmysqlnoviceninja6th/Chapter09/public/phpmysqlnoviceninja6th/chapter09/public/” instead of it adding an index.php to it. is there anything I have to do to my apache configurations?

You’ll need to create the relevant .htaccess file with rewrite rules. The rules for this file are included on the book (apologies, I’m at work at the moment and don’t have the book to hand, but it’s mentioned on the page that talks about url rewriting)

Thanks TomB For your reply. Initially I did not want to bother you again with this issue but as I have said in my first mail that we are currently using your book at Boston PHP meetup in PHP PRECOLATE SEASON 10 https://www.meetup.com/bostonphp/messages/boards/thread/51274527. we supposed to be at Chapter 13 by now and majority of my people have stop responding to the assignments due to this problem because majority of us are using xampp on our Laptops. .htaccess you wrote for apache is this
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [NC,L,QSA]

it prevents page from displaying, it normally shows Server error! please, what can we adjust in this .htaccess file?

The code is correct, you’d have to examine the server logs to see what the cause of the issue is. I’m afraid I’m not sure how you’d go about that using xampp, I haven’t run a web server on windows for years. Is mod_rewrite enabled in httpd.conf?

I’d recommend using vagrant/virtualbox as a development environment anyway ( see https://www.sitepoint.com/re-introducing-vagrant-right-way-start-php/). If people can’t boot the VM you probably just need to enable VT-x in the computer’s BIOS, it can be named differently depending on the make of the PC. “Virtualization technology” “Intel Virtualization”, etc but it all means the same thing.

1 Like

I have the same problems described above with my students. Basically we stuck on p.375 - 376 using xampp on Ubuntu v.14+ and on Windows 10. The file .htaccess with the content above causes that the directory which .htaccess is in disappears from the view by browser. The full URL to that directory in the browser shows Server error on windows and Ubuntu. Tom, do you have any idea how to make chapter 9 and 10 working.

Just a note. In windows I think you can’t create directly a file starting with dot (.htaccess) but you can change the .htaccess file name read by apache in apache config with the following directive:

AccessFileName htaccess.txt

And reboot apache.

Sure you can. Windows doesn’t care how you name your files, if you want to it to start with a dot that’s fine.

I would recommend against this, as that can be viewed by anyone visiting your site, whereas access to files that start with a dot are rejected by default in Apache.

Yes, I wouldn’t recommend that on live site either. I used that on local win machine and .htaccess on live site (rhel).

This is what I get when I try to create a file starting with dot in my win10 instance:

You can’t in Windows Explorer. If you try, you get an error “You must type a file name”.



On Ubuntu can you paste the output of:

tail -n 200  /var/log/apache2/error.log

Make sure the .htaccess file contains only the code:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [NC,L,QSA]

Things may have changed, but last I knew it could be done by enabling “show hidden files” and opening the text editor “as Admin”. And there have been times I’ve needed to stop the server to not get a “in use” error.

Hi, Tom.

(I have had to rework this post as it contained virtual host settings which, while only generic, the forum took to be “links” and therefore would not let me post… so this is the non-link version… Basically, I have removed the two periods/full stops from wwwframeworklocal that should be either side of the word framework. Hope this still makes sense.)

I hope you’re still around in the forum. I’m really pleased I found it as, like others here, I’m banging my head against a brick wall (well… a stud partition, but it still hurts :slight_smile: ).

Before I moan, can I say that the concept of your book: to end up with a reusable PHP framework, is outstanding. Hence my perseverance to get the code working. Well done!

Like olaoyesunday, I am failing to arrive at the correct text for the routes after coding up to page 378 of the book.

I have set up the following:

  • a “.htaccess” file containing:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [NC,L,QSA]
  • a virtual host, wwwframeworklocal, containig the following:
<VirtualHost *:80>
ServerAdmin admin@framework.local
ServerName wwwframeworklocal
DocumentRoot /var/www/wwwframeworklocal
ErrorLog ${APACHE_LOG_DIR}/wwwframeworklocal_error.log
CustomLog ${APACHE_LOG_DIR}/wwwframeworklocal_access.log combined

I am using Debian and the default apache document root is /var/www/html and virtual hosts must ref /var/www/.

  • an /etc/hosts file containing:          wwwframeworkcom
  • I have enabled mod_rewrite module in Apache and restarted the server.

In my IDE (Netbeans), I have a folder, “wwwframeworklocal” as the website root. In here, I have folders for classes, includes and templates, and I have the index.php and jokes.css and .htaccess files. So, a slight difference to you in that the index.php, jokes.css and .htaccess files are not in the “public” directory. I prefer to have these in the root if the website. I have, however, altered the few links to things like templates/* from /…/templates… to /templates… and these links work well.

The whole site worked beautifully just before I did the URL Rewrite changes, i.e. when I was using $route = $_GET[‘route’] ?? ‘joke/home’;

So I know there are no problems with the fact that I haven’t used a “public” directory: all links are working fine.

OK. So that’s where I am. Here’s what I’m getting:

Forget the IDE for now… just using Chrome web browser, if I enter as my URL the following: “www.framework.local”, eureka, I get the website, success! So, my /etc/hosts is good, the virtual host is good, the .htaccess is good.

If I hover over the three links, I get the following as target urls:
Home: wwwframeworklocal
Joke List: wwwframeworklocal/joke/listall
Add a new joke: wwwframeworklocal/joke/edit
(note: the IDE wouldn’t let me use “list” as the name of the function in JokeController.php. I had to change this to something else. I chose “listall” and ensured I changed that everywhere in the code. Again, this worked fine when the code was at the $route = $_GET[‘route’] ?? ‘joke/home’; stage so nothing wrong with this.

Right. You say the new url rewriting “$route…” line in index.php should leave you with:
the full URL starting after the domain name and ending either before the first question mark or at the end of the whole url if there is no question mark.

Now, whether or not we have used a “public” directory, we all seem to have placed all of the code inside a folder of some kind/name, phpmysqlnoviceninja6th/Chapter09 from olaoyesunday above or wwwframeworklocal for me. We do this so we can develop more than one website in our IDEs. It’s no good placing the code in the apache root as then, what do we do with a second website? Put that in the apache root as well and mix all the websites’ files together? No. Each website is in a folder of its own inside the Apache root. Hence the virtual host. In your book, after you’ve told us about the .htaccess file, you tell us to go to and the new $route line will leave us with a value of “joke/list”. I get that. But what value is the IP address. My Apache, like most I would imagine is running at If I just use this in my URL, I end up looking in the default doc root: /var/www/html. I don’t end up in a virtual host location. I dont end up looking at the index.php file which you have told us to put in the “public” directory. If we set up our website, even in the default doc root, you have asked us to put an index.php file in “public”. So doing what you ask…… isn’t going to work.

So… against all common sense (I think), I deduce from your IP approach that I need all my files in the default doc root with no “public” folder so that “” with no filename will default to index.php. Great this works. I get the site as expected. Looking at the 3 navigation links, hovering, I get:


Clicking home refreshes the page and the site is still there. Clicking either of the other two results in:

Not Found
The requested URL /joke/listall was not found on this server.

Apache/2.4.25 (Debian) Server at Port 80

So … ???

Please Tom, I paid £25.00 for the book. I have invested a little over a month of my life getting to page 378. I am very much looking forward to realising the concept of the book: to end up with a generic framework. Then… my stud partition needs repair.

I think (I could be wrong…) what is happening here is that, if we follow the book to the letter and install the whole Vagrant/VitualBox/Homestead thing, the code will probably work because of environment settings in the VM. But we don’t all want to do that. I have some experience in working with servers and I can install and configure apache, php, mariadb well. I want to just use the default Debian set up. Part of the reason for this is that my web host uses Debian and it’s default LAMP set up so I want my development code to work in production.

I thought I was buying and investing time in a book called “PHP & Mysql: Novice to Ninja”. I didn’t think I was buying a book called “PHP & Mysql: Novice to Ninja, if you code in Vagrant/VirtualBox/Homestead or it won’t work”.

Tom, please may I respectfully request you do this:
$title = “PHP & Mysql: Novice to Ninja, if you code in Vagrant/VirtualBox/Homestead or it won’t work”
$title = str_replace(‘if you code in Vagrant/VirtualBox/Homestead or it won’t work’, ‘’, $title)

During the book, you’re constantly making code generic. Marvellous. But if none of it works outside of the single environment you have used, it’s not generic at all is it.

There are reviews on the SitePoint website for your book saying the code doesn’t work and the book is full of typos. There’s too much truth in those reviews. There are course deliverers on this forum whose students are leaving their courses.

I don’t think this is good.

Help us out Tom, quickly if you can. I am very happy to help you with any questions you have about a generic set up such as mine.

You should be able to get around that by formatting code and URLs as code.
For in-line code put one back-tick at the beginning and end.
For blocks of code put three back-ticks on a line of their own before and after the block.
Or highlight and click the </> button on the editor toolbar.

1 Like


Cheers. That’s helpful. I’ll remember that for next time. :grinning:


1 Like

Hi Mike,

If you are using a virtualhost, you’ll need to use that everywhere. You don’t need to set up a virtualhost to use URL rewriting but if you have you’ll need to us that consistently. So if your website is on http://www.framework.local/ you’ll need to visit e.g. http://www.framework.local/joke/edit and not

Ignoring every single line of PHP code from the book you should be able to create this .htacces file

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [NC,L,QSA]

And this index.php:

echo 'You are viewing ' . $_SERVER['REQUEST_URI']; 

And visit http://localhost/foo/bar (or whatever your URLis/foo/bar)and see the message “You are viewing /foo/bar” any URL you visit on the website should load index.php and display the path on the server you are viewing.

If that isn’t working, please paste the output of the sever’s error log as mentioned above.

Every line of code works on PHP 7+. As you have pointed out there are some pieces of code which won’t work on PHP 5.6 because it’s outdated. URL rewriting is a different topic than PHP as it’s server specific. As I mentioned in the installation chapter, the simplest way to get up and running is using the Homestead Improved vagrant box: Everything is configured for you so will just work. If you choose to use a different web server, you will need to do some configuration yourself and have an understanding of server configuration which is beyond the scope of the book.

1 Like