简体   繁体   中英

php & .htaccess clean url problem

i wanna use clean url for my site but i have an big problem: i have urls like :

index.php?lang=en&mod=product&section=category
index.php?lang=en&mod=product&caption=fetch&id=45
index.php?lang=pe&mod=blog&section=category&id=560
index.php?lang=pe&mod=blog&section=category&id=564
index.php?lang=pe&mod=blog&section=category&id=567
index.php?lang=pe&mod=blog&section=category&id=571
index.php?lang=pe&mod=blog&id=556
index.php?lang=pe&mod=page&id=537
index.php?lang=pe&mod=blog&id=558&o_t=cDate_ASC
index.php?lang=pe&mod=product&caption=fetch&id=7804

As you see i have a problem that my varibale's order is diference toghether and my 3rd or 4th variable are not stable sometimes it's id or sometimes is caption. i want to set my template url to ( eg en/product/category ) but when i want to set it in .htaccess it's not clear that theird depth is "id" or is "caption" !

do i should put all variables in my url like this? :

index.php?lang=en&mod=product&section=category 

                  |
                  |
                  |
                  V

index.php?lang=en&mod=product&section=category&caption=&id=&o_t=&v_t=&offset=

EDIT:

So i use smarty as my template engine.i should change my link address in templates like my clean url ( eg en/product/category/324 ). my problem is when i set a link to en/product/34 or en/product/category/23 according to my .htaccess rewrite rules it's not clear that 3rd part is id or category in this case:

RewriteRule ^/(en|pe)/(product|blog|page)/(category)/([0-9]{1,})/$ index.php?lang=$1&mod=$2&section=$3&id=$4 

3rd variable is category an .htaccess define 3rd part as category but as you can see sometimes url has not category and instead of it has id ! My big problem is this

You'd need to make a few rewrite rules I think.

EG

RewriteRule ^/(en|pe)/(product|blog|page)/([0-9]{1,})/$ index.php?lang=$1&mod=$2&id=$3

Would rewrite index.php?lang=en&mod=page&id=22 to /en/page/22 (so long as ID was > 1 character)

RewriteRule ^/(en|pe)/(product|blog|page)/(category)/([0-9]{1,})/$ index.php?lang=$1&mod=$2&section=$3&id=$4

Would rewrite index.php?lang=en&mod=blog&section=category&id=22 to /en/blog/category/22

You may need to fiddle with the ^/ at the start depending on if you have a RewriteBase set or not.

EDIT:

Explanation:

  • ^ indicates the starting position of the URL from the base ie site.com/(whatever here is in the URL)
  • (en|pe) means that first value in that particular rule can be EITHER en OR pe. To add more is easy (en|pe|ru|jp) etc. Same goes for the product/blog/page part. I included (category) just incase you had other 'section' types that were not 'category'.
  • [0-9] is any numeric character 0 to 9. {1,} means 1+ character in length. If you want between 2 and 4, do {2,4} for example. Exactly 3 characters? {3}. It's useful when targetting specific things.

  • $ Means the end of the matched string. If you intend on having nothing after the id except a / (could even remove that /) then use that example as is. If you intend on having a title of a blog past afterward, you can do (.*)$ which means anything can be after the page id eg /en/blog/category/22/oheyoheyoheyohey would be the same as /en/blog/category/22/abcjhrefgwgrjurgh. If you pass the title as a parameter &title=this is the title, just do the same thing as I did in the example for ID except use [a-zA-Z0-9-+_.] to include alphanumeric characters, +, -, _, .

  • $1 is the order of the paranthesis arguments in the first argument of the rule. EG $1 refers to (en|pe), so lang can either be en or pe.



IF you want the rule to apply to multiple pages, and not just the index.php, make it: RewriteRule ^/([a-zA-Z])/(en|pe)/(product|blog|page)/([0-9]{1,})/$ $1.php?lang=$2&mod=$3&id=$4

So in that case, site.com/blah/en/product/22 would relate to site.com/blah.php?lang=en&mod=product&id=22

Why should you do so? I see no problems with your urls, normal user does not mind and those who inspet your site can read it all without problems...

You have to agree on some ordering of parameters, and use mulitple rewrite rules.

For the order lang > mod > section > caption > id > o_t > v_t > offset you want to have something like this:

RewriteRule ^/(\w+)$ index.php?lang=$1
RewriteRule ^/(\w+)/(\w+)$ index.php?lang=$1&mod=$2
RewriteRule ^/(\w+)/(\w+)/(\w+)$ index.php?lang=$1&mod=$2&section=$3
RewriteRule ^/(\w+)/(\w+)/(\w+)/(\w+)$ index.php?lang=$1&mod=$2&section=$3&caption=$4
RewriteRule ^/(\w+)/(\w+)/(\w+)/(\w+)/(\d+)$ index.php?lang=$1&mod=$2&section=$3&caption=$4&id=$5
...
and so on

Above, I assume lang, mod, section and caption are made up of alphabet characters (no digits or special chars), and the id is made of digits.

The real file index.php does not care about the order of variables in the query string, or if a value is missing, because it receives couple with name-value: the right association is ensured by the presence or absence of the full couple.

To be clear, for index.php is the same if the query string is " ?lang=en&mode=blog " or " ?mode=blog&lang=en " or if it is only " ?lang=en ", because the variables are managed inside the script by use of the $_GET associative array, independently by their order or presence inside the array.

What is important is that you plan a correct order of variables inside the new virtual URL's to rewrite because they contain only the variable content, while the variable name is taken from the position inside the virtual URL. That is (note this is pseudo-code):

  yourdomain/val1/val2/val3/...etc 

to be rewritten in:

  index.php?var1=val1&var2=val2&var3=val3&...etc

so in the new URL's you are going to plan, there cannot be missing values.

You can solve this problem by assigning fake values to the missing variables that will not be taken as valid by your script.

As example, if the mode variable is missing, you can put in that position a string that will not be considered valid by the script, so to be managed as if it was empty.

If you have an array of allowed values, you can just add a control *if (in_array())* instead of (or other than) if(empty()) .

When you build the links to other page, you can just add this control for a missing value: *if (empty(val3)) val3 = 'fake_value';*

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM