Wildcard subdomains and friendly URLs - php

This is what I would like to do with htaccess (or whatever you suggest):
I want to allow users to publish pages,photos,videos,... and give them each a subdomain of their choice (ex: john.mysite.com).
Here's how a URL can be -really Tumblr like (it would be great if it'd work like Tumblr :)-
john.mysite.com/photos
john.mysite.com/photos/album/123456789
john.mysite.com/news/123456789
john.mysite.com/news/category/123456789
Using htaccess I can make whatevertheusernameis.mysite.com be served by mysite.com/user.php
Then in user.php I can see who the user is analyzing HTTP_HOST (getting 'whatevertheusernameis' and checking my DB) and I can know what to show (photos,videos,news,pages,...) reading REQUEST_URI.
I would like certain URL to work as follow:
john.mysite.com/ajax/ajax.php -> mysite.com/ajax/ajax.php
john.mysite.com/images/img.png -> mysite.com/images/img.png
but if, for example, I'm in john.mysite.com/photos/album/123456789/ this will be served as john.mysite.com/photos/album/123456789/ajax/ajax.php that, of course, won't work...
Can anyone please help me? Thanks.

What you have to do is add a condition before all your other rewrites:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ...
Those directives will tell Apache to always serve actual files (f), directories (d) and symbolic links (l) and use the sub-domain to identify the location of the user data (photos, etc).

Related

Network Solutions hosting URL looks weird for Apache server

I was trying to prettify URLs for dynamically generated pages on my website, so that when a user visited the virtual URL topicview/interesting-user-friendly-text he would really be seeing, under the hood, topicview.php?topicid=123
I added the necessary code to my .htaccess file to replace the topicview/interesting-text part of the URL with topicview.php?topicname=interesting-test, but the Regex kept misfiring.
So, I changed the Regex to return the entire URL so I could see why it wasn't working with this code:
#Allow for topicview/topic-name URLs
RewriteRule (.+)$ topicview.php?topicname=$1 [L]
I then visited topicview/user-friendly-text. I'm not sure if this is unique to Network Solutions hosting, however, when I examined the topicname GET paramter, I got this string in return:
data/1/2/323/232/823238/user/999999/htdocs/topicview.php
This URL was not displayed in the topicname GET parameter, just a regular file, like index.php or topicview.php, if I just visit the URL index.php or topicview.php
Why is the URL internally represented like this to the Apache server, and how can I rewrite my mod_rewrite code to get a more user friendly virtual URL for the topicview.php?topicid=1 pages?
thanks
For the friendly URL try this in your .htaccess file
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?topicview/([^/.*]+)/?$ topicview.php?topicname=$1 [L,QSA]
The pattern matched in a RewriteRule is normally the similar to the REQUEST_URI but the behaviour you describe suggests it is matching against the REQUEST_FILENAME or something similar which is the file path including the full document root.
This would suggest your RewriteRule is not in your .htaccess file but instead in your or rules in the Apache config files, correct?
Instead you should try getting the value you want using a RewriteCond so you can guarantee you are matching against the REQUEST_URI, for example:
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteRule . topicview.php?topicname=%1 [L]
Note the %1 rather than $1 which allows you to use values captured in the RewriteCond.

RewriteRule different pages per user

I am deciding to create separate profile links for each user who registers on the website. I am using the .htaccess file RewriteRule to achieve this. The url I want to achieve should look something like www.domain.com/username. (I don't want www.domain.com/users/username)
Now the problem is, if I add a rule like RewriteRule ^(.*)$ /users.php?username=$1
it will matchup all URL addresses for www.domain.com, which may direct to any path. Even if I would like to visit www.domain.com/about page, it will be redirected to
www.domain.com/users.php?username=about, which I don't want. (Even if the requests was www.domain.com/products/abc)
I could apply filters in my users.php to filter such usernames, or if a username is not found in database, redirect to the page, but this means I have to change filters every time I decide to add a new page in my directory (in this case, any). Also, all traffic will be directed through 1 page, which may cause a performance problem.
Please suggest a way to achieve this, as There are websites that work like this. A possible RewriteRule or PHP code to achieve this.
You can use this rule in your root .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(\w+)/?$ /users.php?username=$1 [L,QSA]
I always use just simple rewrite as below:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)(.*)/?$ index.php
All traffic is redirected to index.php and using php I can run specific controllers depending on url. You should also think about. Almost all frameworks use such rule.
Then in your PHP file you should examine
$_SERVER['REQUEST_URI']
variable to route request to specific controllers

How to create a directory with a single file in it?

I'll be signing businesses up to advertise on my website, and I want them to have a direct URL for their customers to go to.
Like, instead of www.website.com/page.php?id=324234234,
I want to have www.website.com/businessname
Is there a simple way to do this? I've searched and seen a whole bunch of different things people are trying to do but I haven't seen anything that's the same as what I want to do.
I'm using a VPS, and I want to make sure that I don't open up permissions so that anyone can get in there and mess things up.
Also, these users will not be signing themselves up. I will be doing that.
The simplest way to get my end result is what I'm looking for. Thanks!
Basic URL rewriting could work.
Add to your .htaccess file
RewriteEngine on
RewriteRule ^(.*)$ page.php?businessname=$1 [L]
Then use PHP to rewrite the businessname to the ID of the company / find the data.
Of course .htaccess rewrite rules is a complete science if you need more complex rewriting...
Re-iterating what jtheman said with a little more explanation:
Create a file named .htaccess with the contents:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ page.php?businessname=$1 [L]
You need, of course, the ability to have directory level .htaccess enabled - you're using a VPS so you should be able to do this if it is not already enabled.
So let me explain what each line will do.
RewriteEngine on
Turns on the ability to URL re-write
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Tells Apache not to re-direct files that exist in the directory already
RewriteRule ^(.*)$ page.php?businessname=$1 [L]
This is where the magic happens.
^(.*)$ this part is like a regular expression match. It will tell Apache to collect any URLs that have any characters within them and redirect them to page.php?businessname=(.*)
So, if you post:
www.website.com/stackover
It will really be sending: www.website.com/page.php?businessname=stackover
Then you can just use $_GET[businessname] to dynamically update the page.
Hope this helps!

Mod_Rewrite Query with Root Domain

I'm trying to do a query on some information if someone types, for example:
http://domain.com/abracadabra
If someone enters in this address, I want it to go to:
search.php?query=abracadabra
I've done rewrites with queries before, but not from the root.
Any help would be great!
Would it be possible to check if the string being searched is numerical and send it to a different PHP page? Maybe link to a directory with a new .htaccess?
Doing it from the root is no different than doing it anywhere else. The below will turn every request for a resource (that doesn't exist in the file system) to search.php.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ search.php?query=$1 [L,QSA]

Create vanity URLs in a LAMP configuration

What is the best way to create user vanity URLs under a LAMP configuration?
For example, a user profile page could be accessed as follows:
http://www.website.com/profile.php?id=1
Now, if a user enters a "vanity URL" for their profile I would want the the vanity URL to load the page above.
For example, if a user selects "i.am.a.user" as their vanity URL and their user id in the database is 1 then http://www.website.com/profile.php?id=1 would be accessible by that URL and http://www.website.com/i.am.a.user .
I'm aware of mod rewrites in .htaccess but not sure how that would work here.
As I mentioned my site is in PHP, MySQL, Linux and Apache.
Thanks.
Say your other pages had specific URLs that you could check against, the following should help.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9-_]*)$ /profile.php?user=$1 [L]
This helps to maintain current URLs, while allowing for the user shortcut URLs. Also, the RewriteRule will only match URLs that don't contain a /, which will help protect against non-intended redirects. So,
/i-am-a-user -> MATCHES
/i_am_a_user -> MATCHES
/i-!am-a-user -> NOT MATCHED
/i.am.a.user -> NOT MATCHED
/i.am.a.user/ -> NOT MATCHED
/some/page/ -> NOT MATCHED
/doesnotexist.php -> NOT MATCHED
/doesnotexist.html -> NOT MATCHED
Hope that helps.
EDIT
I've updated the rules above so that actual files/directories aren't redirected as well as making sure that any .php or .html file is not sent to profile.php either.
Rewrite for site.com/user/USERNAME:
In your root web directory, place a .htaccess file:
RewriteEngine on
RewriteRule ^user/(.+)$ profile.php?name=$1 [L]
This routes all requests that starts with "user" to profile.php and pass the URI to $_GET['name']. This method is preferred if you have a lot of files / directories / other rewrites.
Rewrite for site.com/USERNAME:
RewriteEngine on
# if directory or file exists, ignore
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ profile.php?name=$1 [L]
This routes to profile.php ONLY if the requesting file or directory does not exists, AND when the request URI is not empty (ie, www.site.com)
PHP backend
Now in profile.php, you can have something like this:
if (!empty($_GET['name'])
$user = ... // get user by username
else
$user = ... // get user by id
First setup your .htaccess file to send all requests for files and directories that don't exist to a single php file:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) router.php [NC,L]
Then inside your router.php, look at $_SERVER['REQUEST_URI'] to get the username that you can then use in your query to get the data about the user.
This assumes that all URLs that are not user profile pages exist as physical files on your server.
If that's not the case, you can do some logic in router.php to decide what to do on each request. Do a google search for url routing in php and you'll get plenty of examples.
Well, you could solve this using an apache RewriteMap as well of course. The RewriteMap can be a plain text file (that you update regularly based on what your users enter), or alternatively you could point it to a script (Perl, PHP, whatever suits you) to do the rewriting for you.
For a quick summary on how to set this up using PHP refer to Using a MySQL database to control mod_rewrite via PHP.

Categories