Solved

.htaccess friendly links help

Posted on 2011-02-14
24
844 Views
Last Modified: 2012-05-11
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?
0
Comment
Question by:jporter80
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 13
  • 11
24 Comments
 
LVL 6

Expert Comment

by:MatthewP
ID: 34891635
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..
0
 

Author Comment

by:jporter80
ID: 34893383
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?
0
 
LVL 6

Accepted Solution

by:
MatthewP earned 500 total points
ID: 34894560
That's in your.htaccess file in the root directory. The directory structure that your friendly url shows doesn't need to have anything to do with the actual directory structure, it's all one string and dependent on your rewrite rule you can point that string anywhere in your directory structure.

It's very common to use the directory separator as a variable separator, you can then pull the variables out of this in your rewrite rule and send them to the true url. Consider this url for example:

index.php?action=show_news&news_id=8&template=9

In this example you pass in three variables - show_news, news_id and template. Your friendly url could look like this:

domain.com/news/8/9/Title-Of-News-Item-In-Url

and your rewrite rule could be:

RewriteRule /news/(\d+)/(\d+)/(\w+).html index.php?action=show_news&news_id=$1&template=$2

Note that the title can be anything, all the script cares about is the /news/ bit, and the two numbers which the script can do what it pleases with.

What you will need to watch for is that if you link to a file on a relative url it will remain relative to the directory that is displaying. So if from /news/8/9/title.html you link to user.html, the web server will still think you're in /news/8/9 - you'll need to specify an absolute path for all your links including css and images, or do a rewrite rule for all your css and javascript file requests too.


0
What Is Transaction Monitoring and who needs it?

Synthetic Transaction Monitoring that you need for the day to day, which ensures your business website keeps running optimally, and that there is no downtime to impact your customer experience.

 

Author Comment

by:jporter80
ID: 34929579
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?
0
 
LVL 6

Expert Comment

by:MatthewP
ID: 34929639
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.
0
 

Author Comment

by:jporter80
ID: 34929661
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.

0
 
LVL 6

Expert Comment

by:MatthewP
ID: 34929774
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




0
 

Author Comment

by:jporter80
ID: 34929841
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
0
 
LVL 6

Expert Comment

by:MatthewP
ID: 34929881
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
 
0
 
LVL 6

Expert Comment

by:MatthewP
ID: 34930005
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

0
 

Author Comment

by:jporter80
ID: 34930116
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
0
 

Author Comment

by:jporter80
ID: 34930123
so its still not getting the username correctly to query
 maybe
0
 
LVL 6

Expert Comment

by:MatthewP
ID: 34930153
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?
0
 

Author Comment

by:jporter80
ID: 34930184
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?

0
 
LVL 6

Expert Comment

by:MatthewP
ID: 34930214
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



0
 

Author Comment

by:jporter80
ID: 34930229
bingo!! that did it!! thank you thank you thank you!!!
0
 
LVL 6

Expert Comment

by:MatthewP
ID: 34930262
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.
0
 

Author Comment

by:jporter80
ID: 34930273
cheers thanks again!!
0
 

Author Comment

by:jporter80
ID: 34931415
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
0
 

Author Comment

by:jporter80
ID: 34931418
or even better how can i make it say /page2/ at the end or my url?
0
 

Author Comment

by:jporter80
ID: 34931441
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
0
 
LVL 6

Expert Comment

by:MatthewP
ID: 34931469
RewriteRule ^news/following(/?)p?a?g?e?=?(\d+)?(/?) index.php?page=$2

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

0
 
LVL 6

Expert Comment

by:MatthewP
ID: 34931492
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
0
 

Author Comment

by:jporter80
ID: 34931683
i figured it out and got it working

thanks for the help!!
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is intended for those who are new to PHP error handling (https://www.experts-exchange.com/articles/11769/And-by-the-way-I-am-New-to-PHP.html).  It addresses one of the most common problems that plague beginning PHP develop…
Many old projects have bad code, but the budget doesn't exist to rewrite the codebase. You can update this code to be safer by introducing contemporary input validation, sanitation, and safer database queries.
The viewer will learn how to dynamically set the form action using jQuery.
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question