I'm into rewriting a url in different ways. I mean I want to know how to use mod_rewrite so I can do the following:
1- convert a .php to html for a speific url
i.e: from www.mydomain.com/news.php to www.mydomain.com/news.html
I found some interesting codes, but not sure which one works without any errors...
some of what I found:
RewriteEngine on
RewriteRule ^(\d+)/(\w+).html$ index.php?id=$1&title=$2
2- convert any sub url of that news.php file to
news.php?do=news&id=24455
so the topics or threads show like this without slashes /
I find the 2nd question a lot difficult, but sure there must be a solution for that.
any idea how to get both questions done for a specific url like what I stated above...!!
Thanks
convert a .php to html for a speific url i.e: from www.mydomain.com/news.php to www.mydomain.com/news.html
RewriteRule ^news\.html$ /news.php
Guess for the second (assuming you want to rewrite /news/foo.html urls):
RewriteRule ^news/(.*)\.html$ /news.php?id=$1
I am trying to use apache-rewrite rule to convert the below URL:
http://localhost/foo/bar/news.php?id=24
Into this format:
http://localhost/foo/bar/news/foo-bar
The number 24 is an id of a random row from a MySQL table, which also contains title and content fields.
MariaDB [blog]> select * from articles;
+----+---------+----------+
| id | title | content |
+----+---------+----------+
| 1 | foo-bar | bla bla |
+----+---------+----------+
1 row in set (0.00 sec)
I have the following rule inside my .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
^news/([A_Za_z0_9_]+)$ DIRECTORY/AID/news.php?id=$1 [QSA,L]
I also have a php code that generates a link like this:
$link = "<a href='news.php?id={$row['id']}'></a>";
echo $link;
However, I can't get the rewrite rule to change the path as the desired end result.
The substitution (Real) URL has a number -Code- to identify the link (According to your description): http://localhost/DIRECTORY/AID/news.php?news=42
That code is 42 in this case, but the URL you want displayed doesn't have it. Without that number, we'll get error 404 always. It's like entering only: http://localhost/DIRECTORY/AID/news.php?news=
Have to modify the URL you want displayed by adding the code after "/", for example. Could be a hyphen, etc., but the regex has to be modified accordingly.
Here is an example entering: http://localhost/news/42/ to go to http://localhost/DIRECTORY/AID/news.php?news=42:
RewriteEngine On
RewriteRule ^news/([0-9]+)/?$ DIRECTORY/AID/news.php?news=$1 [NC,L]
That's all you need. To test this example, insert this only code in news.php at http://localhost/DIRECTORY/AID/
<?php
if ( $_GET[ 'news' ] == '42' ) {
echo "HERE I AM<br /><br />";
}
?>
UPDATED according to OP description. Any name can be used instead of This_is_news:
RewriteEngine On
RewriteRule ^news/([0-9a-zA-Z-_]+)/?$ DIRECTORY/AID/news.php?news=$1 [NC,L]
First of all, you would need to change the href in the html, to give the new url format
function news_preview() {
$query = "SELECT * FROM news ORDER BY id DESC LIMIT 5 ";
$result = mysql_query($query) or die(mysql_error());
while($row=mysql_fetch_array($result))
{
echo " ". substr($row['title'], 0,26)."...<br/>".; }
}
The will generate urls like http://localhost/news/24
Note that I removed the /DIRECTORY/AID from the url, as the htaccess suggest you want that to be url, as opposed to what you stated in the text.
But now the get to the http://localhost/news/this_is_article_title type of url. Because there is no correlation between this_is_article_title and the id 24, the only way to achieve this is by either adding the id to the url too, or to have the php lookup the news-article with this title in the database.
This last solution however has some problems, as the you can't just us the title in a url. You have to escape characters. Also you'll have to add a index for the title row in the DB for better performance.
So I'll go with the first solution. We will generate urls like this
http://localhost/news/24/this_is_article_title
First the php part
function news_preview() {
$query = "SELECT * FROM news ORDER BY id DESC LIMIT 5 ";
$result = mysql_query($query) or die(mysql_error());
while($row=mysql_fetch_array($result))
{
$url = "/news/$row[id]/".preg_replace('/[^a-zA-Z0-9-_]/', '_', $row['title']);
echo " ". substr($row['title'], 0,26)."...<br/>".; }
}
Next comes the htaccess part.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^news/([0-9]+)/([A-Za-z0-9_-]+)$ DIRECTORY/AID/news.php?id=$1 [QSA,L]
That should do it I think.
Place RewriteBase right after RewriteEngine On
It will set up rewrite engine correctly before you start redirecting
Unfortunately I'm unable to answer your question in PHP or Apache (although I am using a hand-rolled REST converter to create URL addresses on my current project), but from what I understand, you want your user to type out http://localhost/DIRECTORY/AID/article.php?a_id=24 and the address bar should end up like http://localhost/DIRECTORY/AID/news/this_is_article_title.
I'm not entirely sure what benefits this provides for you, and please bear in mind my solution will NOT allow your end-user to type the RESTful URL and end up at the page with the QueryString address. You'd need some extra legwork to do this, and even more legwork to keep it in sync with the DB (I'd recommend a script that deseminates the RESTFUL URL, queries the DB for the topic then returns the ID or page content ... but that's an different Stack Overflow question for another day.
SOLUTION
My proposed solution requires HTML5 doctype and a very light sprinkling of Javascript.
history.replaceState(null, "history title here", "news/this_is_article_title");
What this does is it changes the URL in the address bar without triggering a page redirect, reload or anything else. This javascript can be dynamically written with your PHP so as the page is served, the address is updated. The higher up in the document it is, the faster the change.
Here's a jsFiddle link: http://jsfiddle.net/uT3RP/1/
Unfortunately they run the code in an iframe so it doesn't control the main address bar, so I included an alert displaying what the address bar location would say, for proof. It's not the most elegant of solutions. I wouldn't even recommend doing what you're doing without the failsafes of making sure the URL displayed can be used to get to the same page. Disclaimer aside ... your problem is solved with 1 line of js and a doctype change (if you aren't using HTML5).
You can stop flogging poor ol' htaccess and get on with your project :)
This is a problem about URL-Rewrite and String-to-Id Algorithm.
Above all, please remember that what ever your url changes by rewrite module, the url in the browser bar always contains the post param like id or string(about your news).
Now to the question. Our purpose is just to rewrite the Url:
http://localhost/DIRECTORY/AID/news/this_is_article_title
to:
http://localhost/DIRECTORY/AID/news.php?a_id=24
With the rewrite module, we can only rewrite it to:
http://localhost/DIRECTORY/AID/news.php?title=this_is_article_title
and here is the htaccess part, alrealdy tested on a htaccess-online-tester
RewriteRule ^DIRECTORY/AID/news/([A-Za-z0-9_]+)$ DIRECTORY/AID/news.php?title=$1 [QSA,L]
The remaining work is build a algorithm for mapping the title to the news which rewrite module cannot help us(especially you manually rewrite the url one by one). We can use php code below:
<?php
//write url reflect to news title.
function build_news_url_by_title(){
$query = "SELECT * FROM news ORDER BY id DESC LIMIT 5";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)){
echo "".substr($row['title'], 0,26)."";
}
}
function get_news_by_title($title){
$real_title = strtr($title, "_", " ");
$query = "SELECT * FROM news WHERE title LIKE %".$real_title."% LIMIT 1";
return mysql_query($query) or die(mysql_error());
}
$title = $_POST['title'];
$news = get_news_by_title($title);
//some code return the news
...
So the url:
http://localhost/DIRECTORY/AID/news/this_is_article_title
can give us the news also.
Finally, from the steps above, if we type url
http://localhost/DIRECTORY/AID/news/this_is_article_title
in the browser bar, it can be also give us the news. And it has none bussiness about the stupid ID. And Though, there maybe some bugs with the code above, do not put it on your product server.
Can you see if this works?
RewriteEngine On
RewriteBase /DIRECTORY/AID/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
^news/([A-Za-z0-9_]+)$ news.php?id=$1 [QSA,L]
EDIT : Fixed the regex character class definitions.
You are missing the title of the URL. If you wish to show that in URL, then you must include it in the link as well, like this:
<a href="news.php?news_id=$id&title=$url_tile">
This seems to be a complicated problem because you do not know where it really is doing wrong.
I would suggest you divide what you want to do into small parts and make each of them work properly before you join them together. For example:
1. Make sure .htaccess file is readable and can do some simple thing, preventing directory indexing for instance.
2. Make sure you can redirect something with simple html code.
3. Make sure you can run Felipe's example code successfully. From here you can get good picture of what is going on.
And as a side note:
It is more common to rewrite like this:
http://localhost/DIRECTORY/AID/news.php?a_id=24 TO -->
http://localhost/DIRECTORY/AID/news/24_this_is_article_title
Notice the id 24 is still carried over to the rewritten url. That will make pattern matching simpler and avoid unnecessary processing of title duplication.
Change the link:
echo " ". substr($row['title'], 0,26)."
to
echo "".$row['title'].""
That way, the link will go to news/$row['title'] instead of news.php?id=.... And now in the page DIRECOTORY/AID/news.php, you should get the id and check if it is a number OR text, and in case of text match it up with the $row['title'] and then load the page accordingly.
Notes:
This assumes that $row['title'] is unique across all other rows.
The title does not contain non HTML content, in which case you will have to URL Escape those characters.
If the title is not going to be unique then you should probably do news/{id}/{title} and then in rewrite it to DIRECTORY/AID/news.php?id={id}&title={title} and then you can base it off of the ID instead of the title.
Hope that helps.
If you feel your .htaccess file is not working as intended then this is a server configuration issue and most likely to do with the AllowOverride directive under the Apache configuration.
In your http.conf file find the section which looks something as follows:
<Directory>
Options FollowSymLinks
AllowOverride None
</Directory>
Change the AllowOverride directive to allow All.
<Directory>
Options FollowSymLinks
AllowOverride All
</Directory>
The next thing is to ensure that the mod_rewrite module is enabled for your XAMPP install. Search for the following line:
#LoadModule rewrite_module modules/mod_rewrite.so
Remove the # so it looks like so:
LoadModule rewrite_module modules/mod_rewrite.so
Restart the Apache service after saving all your changes.
Also ensure you are using the RewriteBase directive in your .htaccess configuration as follows:
RewriteEngine On
RewriteBase /DIRECTORY/AID/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
^news/([A-Za-z0-9_]+)(/)?$ news.php?title=$1 [QSA,L]
The next thing is to ensure your links are pointing to the Rewrite URL. Your echo line should be something like the following:
echo " " . substr($row['title'], 0, 26) . "...<br />";
Now since you can only retrieve titles with this URL rewrite method we need to configure your PHP script accordingly to retrieve the content based on the title. If you still want to use "id" only for retrieving the record then your Rewrite URL should contain the "id" in it in some form. Typical examples of this form are:
news/the_news_title_123
news/123_the_news_title
news/123/the_news_title
I cannot comment so I have to answer.
Reading all answers and your question, it is not clear what you want. At least for me. You say, for example:
http://localhost/DIRECTORY/AID/article.php?a_id=24 to
http://localhost/DIRECTORY/AID/article/this_is_article_title
But I guess that's not quite right, unless you want
http://localhost/DIRECTORY/AID/article.php?a_id=24
to be the URL entered in the browser address bar and if so, what would be the purpose of the redirection? Finally, any visitor would have to type precisely what you don't want them to type.
My guess is that you want the friendly URL to be entered:
http://localhost/DIRECTORY/AID/article/this_is_article_title , so the question should be the other way around:
http://localhost/DIRECTORY/AID/article/this_is_article_title TO
http://localhost/DIRECTORY/AID/article.php?a_id=24
The next thing that does not seem to be clear, is what's displayed in the browser bar? The only answer is: The entered URL. No way it can show anything different.
In short: If you want http://localhost/DIRECTORY/AID/article/this_is_article_title to show in the addres bar, that's what you have to enter. The real URL, the SUBSTITUTION (http://localhost/DIRECTORY/AID/article.php?a_id=24), is never shown and is never typed. That's what redirection is for.
On the other hand, it is not clear either how the ID numbers provided by news.php are expected to be converted to strings like article/this_is_article_title. ¿Where are those strings, how many ID numbers are, what kind of algorithm or formula should be used to achieve that conversion, which of those IDs are 'root" as you mentioned in a comment and how can they be identified, etc.? You should elaborate more on this point because it seems improvised and incoherent with your previous comments.
I might be wrong, of course. I am just guessing to try to help with your question.
Please, geniuses, don't downvote this answer, read it. I am not trying to answer the question and I am really far from being a genius.
Looks like you've forgotten the slash in front of “news.php”.
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.
I'm trying to understand how to properly use mod_rewrite. I have posts in my database that have a title and date. Right now I'm using mysite.com/post.php?id=3 to retrieve my post data and populate the page. I would like to have it like this: mysite.com/2011/03/27/my-title-like-so/. I'm guessing I'll have to query my database for something other than the id, but i dont know. Can anyone help? Perhaps I'm over looking something very simple. So far I have it showing up like this: mysite.com/post/2/ , but that doesn't help very much :P
Thanks!
A common practice is to include both the ID and the title/date in the URL. That way it looks nice to search engines and you can still retrieve it efficiently by ID. As an example, look at the URL for this stackoverflow question.
http://stackoverflow.com/questions/5451267/not-sure-how-to-get-mod-rewrite-to-write-to-a-certain-format
Just a guess but that number in the URL is probably a generated ID. So you use the ID and just ignore the rest of the URL, e.g.:
RewriteRule /questions/(\d+) question.php?id=$1
If you do not wish to include the ID in the URL, then I would suggest the following approach.
In your "posts" table, include a "url" (or "friendly" or something) field that contains the url you wish your post to be accessed by. When you insert the post, simply strip all non-word characters and replace them with a '-'.
Then, when the URL comes into your system, you can just map this url directly to the "url" field.
So, using your example, your URL would be http://mysite.com/2011/03/27/my-title-like-so/
The "url" field would contain 'my-title-like-so'.
You could use a simple rewrite rule such as the following:
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f # if requesting file that doesn't exist, use the rule below
RewriteCond %{REQUEST_FILENAME} !-d # if requesting a directory that doesn't exist, use the rule below
RewriteRule ^(.*)$ index.php?myvar=$1 [L,QSA]
This would put the contents of the URL after the domain:
http://mysite.com/[catches everything here]
And would store it in the $_GET global as 'myvar'
Then you can do any processing on that url in php:
$url_string = my_sanitising_code($_GET['myvar']);
$url_array = explode('/', $url_string);
Now you have an array of all the parts of the URL and you can do whatever you wish with them.
You must capture the values that are passed to the engine to extract the data you want. So:
RewriteRule ^([0-9]{4})/([0-9]{2})/([0-9]{2})/(.*)$ fetch.php?year=$1&month=$2&day=$3&title=$4 [L]
should match your format.
Then the http://mysite.com/fetch.php can use the $_GETs values to fetch the database and display the good things.
I'm developping a website using php and the "template.inc" class.
The problem is that I want to create a mini-cms that allows the admin to create an "html" page with these mysql attributes:
Table Name : Page
-----------------
id :auto-icremented)
name :varchar
In the architecture, if he created the page number "5", the url is
"ww.mywebsite.com/index.php?id=5".
But, this isn't very esthectic so, as I'm very bad at url rewriting even if i read many tutorials, i want to type the name+"html" to access to the page.
If we take the example of the
"www.mywebsite.com/index.php?id=5"
if the admin created a page with the following values:
id : 5
name : 'home'
i want that the user can type
"www.mywebsite.com/home.html"
and with no redirection as i want that this last url must still appear and become the official url.
Thanks for your answer,
i know how to rewrite www.mywebsite.com/index.php?id=5 to www.mywebsite.com/5.html ... but the problem is that i want, first, to get the "name" vale before and in my example, the name value is "home" (5 =>'home').
How can i access to my database with the url rewriting engine?
Thank you very much,
regards.
Use the .htaccess file from a standard Wordpress install to redirect everything to one PHP file. Something like this...
<IfModule mod_rewrite.c>
RewriteEngine On
# Base is the URL path of the home directory
RewriteBase /
RewriteRule ^$ /index.php [L]
# Skip real files and directories
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* /index.php [L]
</IfModule>
Then use $_SERVER['REQUEST_URI'] to figure out what the user was looking for. Modify the .* if you want to make the rule more specific, like .*\.html.
Zakaria,
After using Renesis's rewrite rule, $_SERVER['REQUEST_URI'] will be equal to 'home.html'.
Try something like:
<?php
// clean
$page = mysql_real_escape_string($_SERVER['REQUEST_URI']);
// make query
$query = sprintf("select Page.* from Page where name = '%s'", $page);
// find page ID
if($result = mysql_query($query)){
$page = mysql_fetch_assoc($result);
echo "<pre>", print_r($page, true), "</pre>";
}
?>
Possible output
Array (
[id] => 5
[name] => 'home.html'
)
Use Apache URL Rewriting for this. there are many many examples on this site alone of this. You could also try the official Apache rewriting docs.
You will need to make sure your database enforces uniqueness on name, or you will have problems.
Edit
Have your index.php take a name= parameter instead of a id parameter. You will need to make sure your db has the name field indexed so you don't do a table scan for every page request.