Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

PHP

Redirects not functioning with subfolder

I kept my files in a subfolder: /shirts4mike2/

my config file is working:

define("ROOT_PATH",$_SERVER["DOCUMENT_ROOT"] . "/shirts4mike2/");
define("BASE_URL","/shirts4mike2/");

I was only able to get the RewriteRules working if I removed the initial slash:

RewriteRule ^shirts/$ shirts/shirts.php
RewriteRule ^shirts/([0-9]+)/$ shirts/shirt.php?id=$1

but then none of these work with or without the initial slashes:

RewriteRule ^receipt.php$ /receipt/ [R]
RewriteRule ^contact.php$ /contact/ [R]
RewriteRule ^shirts.php$ /shirts/ [R]

When I have the initial slashes in I get /contact/ not found, when I remove the initial slash I get

/Applications/MAMP/htdocs/shirts4mike2/contact/ etc not found

Of course, if i move everything into htdocs and then change the config file to just / and then add the slashes in to the htaccess, it all works with initial slashes.

So my question is how would i get it to work with the subfolder?

3 Answers

Aaron Graham
Aaron Graham
18,033 Points

Ok. I think I see what's going on here. Your first two rules are almost correct. The problem with them is that they are using absolute paths rather than relative paths. It seems you have two options here. The first is to just use relative paths:

RewriteRule ^shirts/$ shirts/shirts.php
RewriteRule ^shirts/([0-9]+)/$ shirts/shirt.php?id=$1

Notice the missing slash at the beginning of the substitution path. Your other option is to convert them to proper absolute paths by adding /shirts4mike/ to the front of your substitution path.

RewriteRule ^shirts/$ /shirts4mike/shirts/shirts.php
RewriteRule ^shirts/([0-9]+)/$ /shirts4mike/shirts/shirt.php?id=$1

Your remaining rules do seem to be in the wrong order. Assuming you want http://localhost:8888/shirts4mike/receipt/ to go to /receipt/receipt.php, your rule should be like this (assuming you decide to use relative paths):

RewriteRule ^receipt/$ receipt/receipt.php

Again, I don't think you need the redirects. These are actual http redirects. In other words, I think what you want is if you type http://localhost:8888/shirts4mike/receipt/ into your browser, the server will serve the page at receipt/receipt.php while your browser address bar still reads http://localhost:8888/shirts4mike/receipt/. If you use redirects, typing in http://localhost:8888/shirts4mike/receipt/ will redirect your browser to http://localhost:8888/shirts4mike/receipt/receipt.php. The distinction is subtle, but I'm guessing you are mainly using these rules to clean up urls. If that is the case, it doesn't make much sense to redirect your browser to the full path.

Give that a try and see if it works.

hi - We did want receipt/receipt.php to go to /receipt/ it was specifically an exercise in having receipt.php and then moving it to its own folder via /receipt/index.php

here was the exercise video for that: http://teamtreehouse.com/library/enhancing-a-simple-php-application-2/cleaning-urls-with-rewrite-rules/redirecting-old-web-addresses

thanks for your help. Turns out there was some caching happening so even when I was changing .htaccess it wasn't refreshing right away.

After cycling through a few fake URLs, the actual redirects would only work if I had /shirts4mike/ entered in like:

RewriteRule ^shirts.php$ /shirts4mike/shirts/ [R=301]

I think it should be mentioned in these videos that you will have to add the hard coded directory here too, if you are not using the root.

Aaron Graham
Aaron Graham
18,033 Points

Christopher Bijalba - I think I see what you're saying. It has been a while since I went through that video. Glad you got this working! I learned a little about rewrite rules myself - thanks!

Thank you so much, Aaron. I was having the same problem, and you're answer to Christopher really helped me to understand how the rules work a lot better.

Does it work if you remove the trailing slash?

From where exactly? when I remove the trailing slash from config.php it errors because all throughout the site there were no / hardcoded because it is expecting it in the config.php.

I thought the idea behind config.php was to be able to use those constants throughout the files and if you moved directories it was as simple as adding it to config.php to update all files.

it seems like the issue is that .htaccess needs some sort of reference to my "real base directory" because it is looking for somewhere else.

Aaron Graham
Aaron Graham
18,033 Points

Let me start by saying that rewrite rules are not really my strong suit, and as such, my answer may be way off. With that out of the way, I'm not really sure I understand which rules you are having a problem with, but I think you might just have your rule definitions reversed, for example:

RewriteRule ^receipt.php$ /receipt/ [R]

Should maybe be:

RewriteRule ^receipt/$ some_subdirectory/receipt.php

This should direct the URL yourdomain.com/receipt/ to the file some_subdirectory/receipt.php. I think the way you have it, you are rewriting yourdomain.com/receipt.php to the directory /receipt/. Also, you might not even need the [R] redirects.

thanks for the reply. it does seem redundant, but the idea of that redirect is is the php file is requested, it redirects to the directory.

the previous rules -- swapping its order as you suggect -- takes a url that doesn't exist and uses the second portion as the "source to use"

the issue has something to do with htaccess using the "root directory" where with php we were able to modify or append it as needed.

i could insert the true path but not sure exactly how, in order to use the subdirectory

Aaron Graham
Aaron Graham
18,033 Points

I'm not sure I really understand what you are trying to do. Could you give an example? It would be helpful to know the exact url and file you are trying to connect. Knowing something about your directory structure would help too. For example, what is the relationship between .htaccess and the files you are trying to redirect to?

No problem, thanks for the help.e

When I

echo $_SERVER["DOCUMENT_ROOT"]; it returns /Applications/MAMP/htdocs

What I want to do is place my entire project in a folder within htdocs called shirts4mike.

<?php

    define("ROOT_PATH",$_SERVER["DOCUMENT_ROOT"] . "/shirts4mike/");
    define("BASE_URL","/shirts4mike/");

is my config.php. With this, this code works:

include(ROOT_PATH . 'inc/header.php');

I can see the proper headers and footers. However, with this being my .htaccess

RewriteEngine On
RewriteRule ^shirts/$ /shirts/shirts.php
RewriteRule ^shirts/([0-9]+)/$ /shirts/shirt.php?id=$1
RewriteRule ^receipt.php$ /receipt/ [R=301]
RewriteRule ^contact.php$ /contact/ [R=301]
RewriteRule ^shirts.php$ /shirts/ [R=301]
RewriteRule ^(shirts/[0-9]+)$ /$1/ [R=301]

RewriteCond %{QUERY_STRING} ^id=([0-9]+)$
RewriteRule ^shirt.php$ /shirts/%1/? [R=301]

I get this error when trying to go to http://localhost:8888/shirts4mike/shirts/

The requested URL /shirts/shirts.php was not found on this server.

As well as when I try to go to http://localhost:8888/shirts4mike/shirts.php, it does a redirect but to http://localhost:8888/shirts/ and thus cannot find the file:

The requested URL /shirts/ was not found on this server. http://localhost:8888/shirts/

It seems that the method used in config.php above to create a constant for my new root directory needs to happen in .htaccess ??? basically htaccess appears to still be referring to /Applications/MAMP/htdocs as the root, which is not the case.

One of the purposes of setting up the constant was so that the entire set of files could be moved to a real server which might not have the same root directory, yes?

my folder structure is

/htdocs
  /shirts4mike
    .htaccess
    favicon.ico
    index.php
    /contact
    /css
    /img
    /inc
    /receipt
    /search
    /shirts