I've been looking for an answer but I just can't find one. I'm not looking for a way for a user on my site to be able to quickly get to their page, and quite frankly, the same question keeps popping up, "How to Create a Facebook Profile URL" or, "How to use ".htaccess". I'm just looking for a simple bit of PHP that can create basic vanity URL's so I can quickly access different pages on my site and make it look more neat.
Put this in .htaccess to send all requests to index.php (this is called a front controller)
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^.*$ ./index.php
Then put this in your index.php
<?php
// get the request
$request = $_SERVER['REQUEST_URI'];
// split the path by '/'
$params = split("/", $request);
You now can request a page like: http://foo.com/one/two/three
Your $params variable will now look like:
$params = array('', 'one', 'two', 'three');
You can now use those parameters to call functions or redirect to pages or whatever you want.
This is a very simplified example but it should give you the basic idea.
PHP doesn't support vanity URLs at all, you need to configure your webserver to use them.
.htdocs are configuration files for apache, however, your case may be:
Apache hasn't been configured to process these.
Your server isn't apache httpd.
Related
I'm building a URL shortening web app using PHP. I am able to generate shorter URLs successfully. But I'm not able to redirect the users when they visit the shortened URL.
If the user enters https://example.com/aBc1X, I'd like to capture the aBc1X. I'll then query the database to find the original URL and then redirect.
My question is, how can I extract the aBc1X from the above URL?
P.S. I'll use either Apache or Nginx.
Two things to do for you.
First you have to redirect all traffic to one file which will be your router file. You can do this by placing a few rules in .htaccess file. I will put there some generic rules to start with (this one come from Wordpress):
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^redirect\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /redirect.php [L]
</IfModule>
They tell that everywhere url points to which isn't file or directory will run file redirect.php. You may want to tweak that settings to your needs.
Then in redirect.php you can capture url by looking inside $_SERVER['REQUEST_URI'].
For url http://example.com/any-url-i-want you would have
$_SERVER['REQUEST_URI'] == '/any-url-i-want.
Now the only thing you need is to find the url in database, and do a redirect.
I guess you can handle string operations at this point, either by using parse_url, regular expressions, or simple string cutting.
You want to use;
$_SERVER['REQUEST_URI'];
That will return what you're looking for.
You can see the documentation here
To parse the url
$url = "https://example.com/aBc1X";
$path = ltrim(parse_url($url, PHP_URL_PATH), '/');
Then $path will be aBc1X as desired. Note that any query following a ? will be omitted in this solution. For more details have a look at the documentation of the parse_url function.
How can I make www.mydomain.com/folder/?id=123 ---> www.mydomain.com/folder/xCkLbgGge
I want my DB query page to get it's own URL, like I've seen on twitter etc etc.
This is known as a "slug" wordpress made this term popular. Anyway though.
Ultimately what you need to do is have an .htaccess file that catches all your incoming traffic then reforms it at the server level to work with your PHP in the sense, you will still keep the ?id=123 logic intact, but to the client side '/folder/FHJKD/' will be the viewable result.
here is an example of an .htaccess file I use a similar logic on.. (so does wordpress for that matter).
RewriteEngine On
#strips the www out of the domain if there
RewriteCond %{HTTP_HOST} ^www\.domain\.com$
#applies logic that changes the domain from http://mydomain.com/post/my-article
#to resemble http://mydomain.com/?id=post/my-article
RewriteRule ^(.*)$ http://domain.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?id=$1 [QSA,L]
what this will do is take everything after domain.com/ and pass it as a variable to index.php the variable in this example would be 'id' from this you have to device a logic that best suits your sites needs.
example
<?php
//the URL for the example here: http://mydomain.com/?id=post/my-article
if($_GET['id'])
{
$myParams = explode('/', $_GET['id']);
echo '<pre>';
print_r($myParams);
echo '</pre>';
}
?>
now the logic for this would have to go much deeper, this is only pure example at a basic level, but overall and especially cause your working with a database I assume, your gonna wanna make sure the $myParams is clean of malicious code, that can inject into your PHP or Database.
The output of the above $myParams via print_r() would be:
Array(
[0] => post
[1] => my-article
)
To work with it you would need to do at the very least
echo $myParams[0].'<br />';
or you could do it like this cause most browsers will add a final /
<?php
//the URL for the example here: http://mydomain.com/?id=post/my-article
if($_GET['id'])
{
//breaks the variable apart, removes any empty array values and reorders the index
$myParams = array_values(array_filter(explode('/', $_GET['id'])));
if(count($myParams > 1)
{
$sql = "SELECT * FROM post_table WHERE slug = '".mysql_real_escape_string($myParams[1])."'";
$result = mysql_query($sql);
}
}
?>
Now this admitedly is a very crude example, you would want to work some logic in there to prevent mysql injection, and then you will apply the query like you would how you are now in pulling your articles out using just id=123.
Alternatively you could also go a completely different route, and explore the wonders of MVC (Model View Control). Something like CodeIgniter is a nice easy MVC framework to get started on. But thats up to you.
This can be achieved with mod_rewrite e.g. via the .htaccess file.
In your .htacess, you need add RewriteEngine on.
After that, you will need to do some regexs to make this little beast work. I'm assuming ?id is folder.php?id=123.
For example the folder piece: RewriteRule ^folder/([a-zA-Z0-9_-]+)/([0-9]+).html$ folder.php?id=$123
I am working on creating page links from DB like the following example.
Current page:
www.example.com/page.php?pid=7
In the DB it is saved as title "contact-us" under category "Company Info"
I want it to be like:
www.example.com/company-info/contact-us.html
I have tried different solution and answers but did not got any luck. I am not sure, where will be the PHP part and which rules to write for .htaccess files.
In apache (or .hataccess) do something like this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /proxy.php?_url=$1 [QSA,L]
So in a nutshell, if the resource being requested doens't exist, redirect it to a proxy.php file. From there $_REQUEST['_url'] will be the url the user was requesting.
Then create proxy.php in your home directory and add whatever logic you'd like to load the correct content.
If you use this from .htaccess, then you may need to add RewriteBase / to your config.
If you want to find this page by url, you will probably do this through php and .htaccess. Make a .htaccess that calls page.php for each and every request. You don't need the pid=7, because, well, how should the .htaccess know it is 7, right? :)
In page.php, you take the original url and split it on the slashes, so you get the category (company-info) and the page itself (contact-us.html). Then, you can look these up in the database. This is in a nutshell how many software works, including Wikipedia (MediaWiki) and CodeIgnitor.
Mind that 'company-info' isn't the same as 'Company Info'. You'll have to specify the url-version in the database to be able to use it for look-up.
so my index.php can be this:
<?php
$restOfURL = ''; //idk how to get this
print $restOfURL; //this should print 'FOO', 'VAR3', or any string after the domain.
?>
You want to use,
<?php
$restOfURL = $_SERVER['REQUEST_URI'];
// If you want to remove the slash at the beginning you can use ltrim()
$restOfURL = ltrim($restOfURL, "/");
?>
You can find more of the predefined server variables in the PHP documentation.
Update
Based on your comment to the question, I guess you're using something like mod_rewrite to rewrite the FOO, etc and route everything to just one file (index.php). In that case I would expect the rest of the URL to already be passed to the index.php file. However, if not, you can use mod_rewrite to pass the rest of the URL as a GET variable, and then just use that GET variable in your index.php file.
So if you enable mod_rewrite and then add something like this to your .htaccess file,
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [L,QSA]
Then the rest of the URL will be available to you in your index.php file from the $_GET['url'] variable.
Reading $_SERVER['REQUEST_URI'], as everybody has pointed out, can tell you what the URL looks like, but it doesn't really work the way you want it unless you have a way to point requests for me.com/VALUE1 and me.com/VALUE2 to the script that will do the processing. (Otherwise your server will return a 404 error unless you have a script for each value you want, in which case the script already knows the value...)
Assuming you're using apache, you want to use mod_rewrite. You'll have to install and enable the module and then add some directives to your .htaccess, httpd.conf or virtual host config. This allows you make a request for me.com/XXX map internally to me.com/index.php?var=XXX, so you can read the value from $_GET['var'].
$var = ltrim( $_SERVER['REQUEST_URI'], '/' )
http://www.php.net/manual/en/reserved.variables.server.php
Just by looking at the examples, i think you are looking for the apache mod_rewrite.
You can apply a RewriteRule via an htaccess file, for example:
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^([\w]+)$ /checkin.php?string=$1 [L]
For example this url http://foo.com/aka2 will be process by checkin.php script and will have "aka2" passed as $_GET['string'].
Make no mistake, the URL will still be visible in the browser as http://foo.com/aka2 but the server will actually process http://foo.com/checkin.php?string=aka
mod_rewrite documentation
$_SERVER['REQUEST_URI']
Why bother with all the fancy mod_rewrite/query_string business? There's already $_SERVER['PATH_INFO'] available for just such data.
What's the best way to implement a URL interpreter / dispatcher, such as found in Django and RoR, in PHP?
It should be able to interpret a query string as follows:
/users/show/4 maps to
area = Users
action = show
Id = 4
/contents/list/20/10 maps to
area = Contents
action = list
Start = 20
Count = 10
/toggle/projects/10/active maps to
action = toggle
area = Projects
id = 10
field = active
Where the query string can be a specified GET / POST variable, or a string passed to the interpreter.
Edit: I'd prefer an implementation that does not use mod_rewrite.
Edit: This question is not about clean urls, but about interpreting a URL. Drupal uses mod_rewrite to redirect requests such as http://host/node/5 to http://host/?q=node/5. It then interprets the value of $_REQUEST['q']. I'm interested in the interpreting part.
If appropriate, you can use one that already exists in an MVC framework.
Check out projects such as -- in no particular order -- Zend Framework, CakePHP, Symfony, Code Ignitor, Kohana, Solar and Akelos.
have a look at the cakephp implementation as an example:
https://trac.cakephp.org/browser/trunk/cake/1.2.x.x/cake/dispatcher.php
https://trac.cakephp.org/browser/trunk/cake/1.2.x.x/cake/libs/router.php
You could also do something with mod_rewrite:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*)$ $1 [L]
RewriteRule ^([a-z]{2})/(.*)$ $2?lang=$1 [QSA,L]
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>
This would catch urls like /en/foo /de/foo and pass them to index.php with GET parameters 'lang' amd 'url'. Something similar can be done for 'projects', 'actions' etc
Why specifically would you prefer not to use mod_rewrite? RoR uses mod_rewrite. I'm not sure how Django does this, but mod_php defaults to mapping URLs to files, so unless you create a system that writes a separate PHPfile for every possible URL (a maintenance nightmare), you'll need to use mod_rewrite for clean URLs.
What you are describing in your question should actually be the URL mapper part. For that, you could use a PEAR package called Net_URL_Mapper. For some information on how to use that class, have a look at this unit test.
The way that I do this is very simple.
I use wordpress' .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
What this .htaccess does is when something returns a 404, it sends the user to index.php.
In the above, /index.php is the "interpreter" for the URL.
In index.php, I have something along the lines of:
$req = $_SERVER['REQUEST_URI'];
$req = explode("/",$req);
The second line splits up the URL into sections based on "/". You can have
$area = $req['0'];
$action= $req['1'];
$id = $req['2'];
What I end up doing is:
function get_page($offset) {//offset is the chunk of URL we want to look at
$req = $_SERVER['REQUEST_URI'];
$req = explode("/",$req);
$page = $req[$offset];
return $page;
}
$area = get_page(0);
$action = get_page(1);
$id = get_page(2);
Hope this helps!
Just to second #Cheekysoft's suggestion, check out the Zend_Controller component of the Zend Framework. It is an implementation of the Front Controller pattern that can be used independently of the rest of the framework (assuming you would rather not use a complete MVC framework).
And obviously, CakePHP is the most similar to the RoR style.
I'm doing a PHP framework that does just what you are describing - taking what Django is doing, and bringing it to PHP, and here's how I'm solving this at the moment:
To get the nice and clean RESTful URLs that Django have (http://example.com/do/this/and/that/), you are unfortunately required to have mod_rewrite. But everything isn't as glum as it would seem, because you can achieve almost the same thing with a URI that contains the script's filename (http://example.com/index.php/do/this/and/that/). My mod_rewrite just forwards all calls to that format, so it's almost as usable as without the mod_rewrite trick.
To be truthful, I'm currently doing the latter method by GET (http://example.com/index.php?do/this/and/that/), and fixing stuff in case there are some genuine GET variables passed around. But my initial research says that using the direct slash after the filename should be even easier. You can dig it out with a certain $_SERVER superglobal index and doesn't require any Apache configuration. Can't remember the exact index off-hand, but you can trivially do a phpinfo() testpage to see how stuff look like under the hood.
Hope this helps.