Link to home
Create AccountLog in
Avatar of jporter80
jporter80Flag for United States of America

asked on

.htaccess friendly links help

I have a folder called "user"

in that folder i have an index.php that finds our the username and displays the page

also in the user folder i have a .htaccess file that rewrites the URL to a friendlly link like

mydomain.com/user/username

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /user/index.php?url=$1 [QSA,L]
</IfModule>

Open in new window


Now i want to go one level deeper with the friendly URL.

example:

mydomain.com/user/username/following

i put a "following" folder in my "user" folder but that doesnt work.  Any ideas how i should structure this and have my htaccess file?
Avatar of MatthewP
MatthewP
Flag of United Kingdom of Great Britain and Northern Ireland image

Not entirely sure what you're getting at, is username where you would have an actual username, in which case will something like this work?

RewriteRule user/(\w+)/following user/index.php?username=$1

Simply, whatever is in the url between user/ and /following you can pick up in $_REQUEST['username'] in index.php. Not sure if I've understood what you're doing though..
Avatar of jporter80

ASKER

I think you are correct.

i already have a user folder with a index.php that gets the username and then the .htaccess redirects to

/user/exampleuser

so now i want to make another going one level deeper.

/user/exampleuser/following

so your example:

RewriteRule user/(\w+)/following user/index.php?username=$1

should that go in the .htaccess file that is in the /user/ folder?
ASKER CERTIFIED SOLUTION
Avatar of MatthewP
MatthewP
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
here is my problem im thinking...

in my /user/ index.php im getting the username from the url

$username = trim(parse_url($_GET['url'], PHP_URL_PATH), '/');

is this smart?

i can get the redirect done just fine in my /user/ .htaccess file but if i put that code in my root .htaccess file, i dont get any data.

any suggestions?
Well .htaccess files aren't for running php code, although it is possible to link them to mysql databases to read rules from databases.

Getting a username from a url isn't secure it sounds like all someone has to do to pretend to be a different user is change the url? Presumably your user is logged in and there is a session variable or cookie identifying them - that is where you should be getting this data from.
no nothing insecure .. the links are made to be for private information.  its to the users public profile.  and that php code is in my index.php page code not my htaccess.

so i guess im still at a loss as to why my code wont work in my htaccess file at the root just like the code in my htaccess file in the /user/ folder.  because im understanding doing everything from the root .htaccess file would be best.

Oh right I see, so the username is a public profile and not the user which is logged in necessarily. That's different.

Are you saying that you are reading the url string to see which user profile or whatever you should be pulling up? That sounds ok because there is no other data available. Think about facebook, myspace etc, those urls are just facebook.com/username etc, theres no ids flying around or anything.

RewriteRule user/(\w+)/following user/index.php?username=$1

From this example discussed earlier, index.php has the username accessible in the $_GET['username'] variable so in that script I would do something like:
$username=my_custom_sanitize_function($_GET['username']); // check username is in the expected format - return 0 if it is not
if ($username){
     $sql="SELECT col1,col2,col3 FROM user_data_table WHERE username = " . mysql_real_escape_string($username)";
// ... rest of code .. //
} else {
echo "User does not exist";
}

Open in new window




in my /user/following/index.php file i call this query from an external php file:

if (isset($_GET['username'])) {
            $username = $_GET['username'];
}

else {
$username = trim(parse_url($_GET['url'], PHP_URL_PATH), '/');
}

if (empty($username)) {
      
      header("Location: /");
}

in my root htaccess file i have this:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.domain\.com$ [NC]
RewriteRule ^(.*)$ http://domain.com/$1 [R=301,L]
ErrorDocument 404 /errors/

RewriteRule user/(\w+)/following user/following/index.php?url=$1


when i go to: domain.com/user/exampleusername/following

i get a page with no data. no error or anything just my styled page.  So it must not be getting the username right.

Any suggestions? Thanks for your continued help
Just seen your last comment, I think I can see what's going on - read this first it may help explain and I'll read your new comment now..

There is no reason why you can't run the same thing in a directory up from the root but your string matching will be different.

If you are already in a directory called user, your string matching should not include the "user" part of the directory structure, the .htaccess rewriting starts from the directory the .htaccess file is in.

Eg. In your user directory
RewriteRule ^test.html$ some_other_page.html

will succesfully redirect mysite.com/user/test.html - the ^ which checks for the beginning of the string is a positive match as the mysite.com/user/ bit is stripped off - it starts from test.html

Similiarly:

RewriteRule user/(\w+)/following user/index.php?username=$1 // works in root directory
RewriteRule ^(\w+)/following index.php?username=$1 // works in user directory
 
I have just tested your code and it works fine apart from the rewritecond stuff which caused an internal server error.

That aside, this in the .htaccess file in the root:
RewriteEngine On
RewriteRule user/(\w+)/following user/following/index.php?url=$1

Open in new window

Then in user/following/index.php
<?php
print "hello from index in user/following!<br />";
print "Url is " . $_GET['url'];
?>

Open in new window

Then i go to mydomain.com/user/matt/following and I get this:

hello from index in user/following!
Url is matt

okay.. so i got rid of the htaccess files in my user folder and my /user/following/ folder (because im hoping do to do everything from my root htaccess file.

i want /user/index.php to rewrite to mydomain/user/testusername
and /user/following/index.php to rewrite to mydomain/user/testusername/following

my htaccess file looks like this

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.test.com$ [NC]
RewriteRule ^(.*)$ http://test.com/$1 [R=301,L]
ErrorDocument 404 /errors/

RewriteRule user/(\w+)/ user/index.php?url=$1
RewriteRule user/(\w+)/following user/following/index.php?url=$1

Open in new window


both my /user/index.php and my user/following/index.php call an external php query file from

/action/user/user-detail.php (user/index.php calls this)
/action/user/user-detail-follow.php (user/follow/index.php calls this)

in each external query file i have this code

// Permalink Query and User Query

if (isset($_GET['username'])) {
		$username = $_GET['username'];
}

else {
$username = trim(parse_url($_GET['url'], PHP_URL_PATH), '/');
}

if (empty($username)) {
	
	header("Location: /");
}

$user_details = mysql_query("SELECT * FROM di_user WHERE user_name = '$username'");

if (!$user_details) {
    header("Location: /errors/");
}

$num = mysql_num_rows($user_details);

if ($num = 0) {
	
	header("Location: /errors/");
}
else {
	
	$row = mysql_fetch_array($user_details);
}

$user_id = $row['user_id'];

Open in new window


and right now if i go to either

mydomain.com/user/testuser  or
mydomain.com/user/testuser/following

i get my custom 404 error page

hopefully this info is clear to what i need and my setup... what the crap am i doing wrong lol
so its still not getting the username correctly to query
 maybe
Can you temporarily remove

RewriteCond %{HTTP_HOST} ^www\.test.com$ [NC]
RewriteRule ^(.*)$ http://test.com/$1 [R=301,L]
ErrorDocument 404 /errors/

from your .htaccess and see if it works then?
i get

Not Found

The requested URL /user/username was not found on this server.  

im wondering if its not getting the username from the url properly now from this line of code in each action file query

$username = trim(parse_url($_GET['url'], PHP_URL_PATH), '/');


does the "/" need to be adjusted somehow in each file?

Possibly this then:

From your htaccess:


RewriteRule user/(\w+)/ user/index.php?url=$1
RewriteRule user/(\w+)/following user/following/index.php?url=$1

The first line is expecting a forward slash on the end of the string - is this correct as it won't work without it
The second line will never be reached as the first line will match it and off it will go!

Solution:
RewriteRule user/(\w+)/following(/?)$ user/following/index.php?url=$1
RewriteRule user/(\w+)(/?)$ user/index.php?url=$1



bingo!! that did it!! thank you thank you thank you!!!
Hurrah for that! No problem.

Even better:

RewriteRule ^user/(\w+)/following(/?)$ user/following/index.php?url=$1
RewriteRule ^user/(\w+)(/?)$ user/index.php?url=$1

Anchoring the beginnings of the string with ^ will stop things like mydomain.com/something_else/user/username matching, which if you ever decide to do something like mydomain.com/preferences/user/username and wonder why it's not getting there..

Cheers.
cheers thanks again!!
lol ... its me again.  running into another snag... everything works great with my new friendly links.. except it broke my paging system.

before i could page through my lists by throwing ?page= at the end of my page url

example: mydomain.com/following/index.php?username=test&page=2

now if i go: mydomain.com/testusername/following?page=2 it breaks or the page information doesnt change.

It seems my query page is not registering the $_GET['page'] value to query.

Does this sound right?

what should i add to this htaccess code to allow paging?

RewriteRule ^news/following(/?)$ news/following.php
or even better how can i make it say /page2/ at the end or my url?
i tried this

RewriteRule ^news/following/(\w+)(/?)$ news/following.php?link_page_type=test
RewriteRule ^news/following/(\d+)/(\w+)(/?)$ news/following.php?link_page_type=test&page=$1

but didnt work.

was hoping it would give me

testdomain.com/following/test/2 on page 2

nadda
RewriteRule ^news/following(/?)p?a?g?e?=?(\d+)?(/?) index.php?page=$2

There is probably a better way but I don't know it!

That is based on the /page2/ format by the way, with or without the trailing slash and should just give you the default user/following page if no page is added
i figured it out and got it working

thanks for the help!!