Apache URL Re-writing not functioning properly

2019-02-21 22:42发布

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.

12条回答
叛逆
2楼-- · 2019-02-21 23:05

Change the link:

echo "<a href=\"news.php?news=$row[id]\"> ". substr($row['title'], 0,26)."</a>

to

echo "<a href=\"news/$row['title']\">".$row['title']."</a>"

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:

  1. This assumes that $row['title'] is unique across all other rows.
  2. 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.

查看更多
\"骚年 ilove
3楼-- · 2019-02-21 23:07

Looks like you've forgotten the slash in front of “news.php”.

查看更多
做个烂人
4楼-- · 2019-02-21 23:08

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.

查看更多
一夜七次
5楼-- · 2019-02-21 23:09

Place RewriteBase right after RewriteEngine On It will set up rewrite engine correctly before you start redirecting

查看更多
手持菜刀,她持情操
6楼-- · 2019-02-21 23:12

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]
查看更多
smile是对你的礼貌
7楼-- · 2019-02-21 23:12

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.

查看更多
登录 后发表回答