I have recently taken on a project to convert an old shopping cart site (custom developed) to a modern SEO friendly site
我最近进行了一个项目,将一个旧的购物车站点(自定义开发)转换为一个现代SEO友好站点
here is my problem the current site utilizes URL's like the below
这是我的问题,目前的网站利用URL如下
http://www.domain.com/page.php?id=XX
i would like to convert there pre existing database of pages (products and categories) to a URL that would look similar to the below
我想在那里将现有的页面(产品和类别)数据库转换为类似于下面的URL
http://www.domain.com/confectionery-&-snacks/lollies/cola-zombie-chews
if the user was to delete cola-zombie-chews the url would look like the below and load the page lollies and so forth if lollies was removed it would load the page confectionery & snacks
如果用户删除cola-zombi -chews, url将如下所示,并加载页面lollies等,如果删除lollies,它将加载页面糖果和零食
http://www.domain.com/confectionery-&-snacks/lollies/
there current database setup looks similar to the below
当前的数据库设置类似于下面
ID | TYPE | NAME
--------+-----------+------------
1 | category | confectionery & snacks
2 | category | lollies
3 | product | cola zombie chews
another issue is the URL could be 4 categories deep for example see below
另一个问题是URL可能有四种深度,例如如下所示
http://www.domain.com/frozen-foods/seasonal/christmas/meat/smoked-salmon-1kg
what type of rewrite rule will i need for this and what type of code would i need to check the url exists in the database
我需要什么类型的重写规则,以及我需要什么类型的代码来检查数据库中的url
i have thought about adding another colum in the database for slug and copying the name and removing the whitespace and replacing with -
我曾想过在数据库中添加另一个colum用于slug,并复制名称,删除空格并替换为-
3 个解决方案
#1
2
I think @Vrac did a good answer +1 :). And @AntoineB has a point too. So I wanted to add a slightly different way and more detailed on the url creation part.
我认为@Vrac给出了一个很好的答案+1:)。@AntoineB也有自己的观点。所以我想添加一个稍微不同的方式,更详细的url创建部分。
You want to use search engine friendly URLs, well you need 2 things:
你想使用搜索引擎友好的url,你需要两样东西:
-
Replace all the urls page.php?id=XX everywhere in the site by the ones you want. So at this point a click on the new URL will return a 404.
替换所有url页面。php?id=XX在站点上的任意位置。所以此时,单击新URL将返回404。
-
All the new urls should make sense to your php - that is the job of
.htaccess
+ php router.所有新的url都应该对php有意义——这是.htaccess + php路由器的工作。
for step #1,
步骤# 1,
On each product page I guess you have access to which product is in which category. If the database schema is such as what you gave the architecture is not sufficient to decide which category is in which. So you need a 4th column parent
that will store the id of a parent category of each category or product. And whether it is a category or object, they all have a category as parent or null for the root.
在每个产品页面上,我猜你可以访问哪个产品属于哪个类别。如果数据库模式与您提供的体系结构类似,则不足以确定哪个类别属于哪个类别。因此,您需要第4列父类,它将存储每个类别或产品的父类别的id。无论它是一个类别还是一个对象,它们都有一个类别作为根的父类别或null。
In php in the page that generates URL for category or product you need to fetch from database all the categories associated to the current item and climb up the tree from the last nested node (the current item) to the root.
在为类别或产品生成URL的页面中的php中,您需要从数据库中获取与当前项相关的所有类别,并从最后一个嵌套节点(当前项)爬升到根节点。
So you will have a loop as the simplified code bellow.
因此,您将有一个循环作为简化的代码波纹。
Tip:
提示:
- If small amount of items, fetch all at once from db to save database queries and then loop on your results (in an array) - call it case a;
- 如果条目数量很少,则立即从db中获取所有条目,以保存数据库查询,然后对结果进行循环(在数组中)——称之为case a;
- Otherwise start from querying only the current item from its id and get its parent, then in the loop do another query to get the new parent again - call it case b;
- 否则,从只从其id查询当前项并获取其父项开始,然后在循环中执行另一个查询以再次获取新父项——称为case b;
So you get the parent of the parent and so on until parent is null.
你得到父结点的父结点,直到父结点为空。
<?php
$itemTree = [];
$allDBItems = mysql_query('SELECT * FROM items');
while($parent)
{
// getParent() is a function that loops on $allDBItems - in case a - and break loop on found $currItemInLoop['id'] === $myItem['parent']
// or - in case b - query the db like mysql_query("SELECT * FROM items WHERE id = $myItem[parent]");
$parent = getParent();
if ($parent) $itemTree[] = $parent;
}
$itemUrl = implode('/', array_reverse($itemTree));
yay, you have the url generated!
你已经生成了url !
for step #2
步骤# 2
in .htaccess
redirect all the urls to page.php
with no exception as follow (I hope you can have a better name than page.php
or at least index.php
that makes sense as root script).
在。htaccess中,将所有url重定向到页面。php也不例外(我希望您能有一个比page更好的名字。php或至少是索引。作为根脚本的php)。
RewriteRule ^(.*)$ index.php?path=$1 [NC,L,QSA]
Almost like @Vrac wrote.
就像@Vrac写道。
Then in index.php
do as @Vrac wrote:
然后在索引。php do as @Vrac写道:
$path = $_GET('path');
$patharray = explode('/',$path);
//do processing based on contents of patharray
$category = $patharray[0];
$product = $patharray[1];
//etcetera, etcetera...
//serve up content based on the path that was requested
You have it complete! :)
你已经完成了!:)
#2
1
I understand from your description that there are two problems: 1) converting requests from existing links to "pretty urls" and 2) processing "pretty urls" going forward. Since you need to do a database lookup to map requests from existing links to the new url, .htaccess won't help much with problem #1. I'm assuming there are already a bunch of links out in the world that point to page.phpid=xx
In your page.php
you could do the database lookup then send the redirect, something like (pseudo-code-ish):
我从你的描述中了解到有两个问题:1)将现有链接中的请求转换为“漂亮的url”,2)处理“漂亮的url”。由于需要进行数据库查找,以便将现有链接中的请求映射到新的url,所以.htaccess对于问题#1没有多大帮助。我假设世界上已经有很多指向页面的链接。页面phpid = xx。php您可以进行数据库查找,然后发送重定向,类似(伪代码):
(you'll have to "flatten" your table into a single string with a crosstab query, that's a separate issue I won't deal with here, say for the sake of argument you've done it and wind up with a single string as url)
(必须使用交叉表查询将表“压平”为单个字符串,这是我在这里不讨论的另一个问题,假设您已经完成了这个操作,并以单个字符串作为url结束)
$id = $_GET('id');
select concat(category,product, etcetera, etcetera) as url from mypagestable where id = $id;
//redirect the browser to the pretty url
header("Location: $url",TRUE,301);
//stop processing here, browser will get the new url and request that instead
exit;
Now a request will come in from the browser for the new "url", in htaccess you can put this:
现在一个请求将从浏览器中输入新的“url”,在htaccess中,你可以把这个:
RewriteCond %{REQUEST_URI} !^page\.php
RewriteRule ^(.*)$ mynewurlprocessor.php?path=$1 [NC,L,QSA]
This will ignore any requests to page.php, because you are already dealing with those requests in page.php you don't want to mess with them. mynewurlprocessor.php gets the path requested as a querystring parameter, so in mynewurlprocessor.php you do something like:
这将忽略对页面的任何请求。php,因为您已经在页面中处理了这些请求。你不想把它们弄得一团糟。mynewurlprocessor。php获取请求的路径作为querystring参数,因此在mynewurlprocessor中。php您可以做以下事情:
$path = $_GET('path');
$patharray = explode('/',$path);
//do processing based on contents of patharray
$category = $patharray[0];
$product = $patharray[1];
//etcetera, etcetera...
//serve up content based on the path that was requested
Because, as you say, the content is dynamic and database-driven, best to keep all that logic in php and only use htaccess to provide your php scripts with the data they need to serve the right content. Having another column for "slug" is a good idea. Your question is quite broad, I'm just giving you a high-level view of how I would design it. If you have questions about the mechanics of turning your table id-type-name
structure into a flat string or how to turn the "pretty" request into a database query on the other end, I suggest you make new, more specific questions for those.
因为,正如您所说的,内容是动态的和数据库驱动的,最好保持php中的所有逻辑,并且只使用htaccess为您的php脚本提供所需的数据以提供正确的内容。再写一篇关于“鼻涕虫”的专栏文章是个好主意。你的问题很宽泛,我只是给你一个我如何设计它的高级视图。如果您对如何将表id-type-name结构转换为扁平字符串或如何将“漂亮”请求转换为另一端的数据库查询有疑问,我建议您针对这些问题提出新的、更具体的问题。
#3
0
In your .htaccess
file please paste this code:
在。htaccess文件中,请粘贴以下代码:
RewriteBase /
RewriteRule ^([a-zA-Z0-9=^_-]+)$ home.php?sname=$1
RewriteRule ^([a-zA-Z0-9=^_-]+)/$ home.php?sname=$1
RewriteRule ^([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)$ home.php?sname=$1&dname=$2
RewriteRule ^([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/$ home.php?sname=$1&dname=$2
RewriteRule ^([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)$ home.php?sname=$1&dname=$2&catname=$3
RewriteRule ^([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/$ home.php?sname=$1&dname=$2&catname=$3
RewriteRule ^([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)$ home.php?sname=$1&dname=$2&catname=$3&subcat=$4
RewriteRule ^([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/$ home.php?sname=$1&dname=$2&catname=$3&subcat=$4
and url access like this:
url访问如下:
http://www.domain.com/confectionery-&-snacks/lollies/cola-zombie-chews/abc
http://www.domain.com/confectionery-&-snacks/lollies/cola-zombie-chews/abc
$sname= confectionery-&-snacks
$dname= lollies
$catname= cola-zombie-chews
$subcat= abc
I hope you understand it.
我希望你能理解。
Ask me again if you're facing any problems.
如果你遇到什么问题,再问我一次。
#1
2
I think @Vrac did a good answer +1 :). And @AntoineB has a point too. So I wanted to add a slightly different way and more detailed on the url creation part.
我认为@Vrac给出了一个很好的答案+1:)。@AntoineB也有自己的观点。所以我想添加一个稍微不同的方式,更详细的url创建部分。
You want to use search engine friendly URLs, well you need 2 things:
你想使用搜索引擎友好的url,你需要两样东西:
-
Replace all the urls page.php?id=XX everywhere in the site by the ones you want. So at this point a click on the new URL will return a 404.
替换所有url页面。php?id=XX在站点上的任意位置。所以此时,单击新URL将返回404。
-
All the new urls should make sense to your php - that is the job of
.htaccess
+ php router.所有新的url都应该对php有意义——这是.htaccess + php路由器的工作。
for step #1,
步骤# 1,
On each product page I guess you have access to which product is in which category. If the database schema is such as what you gave the architecture is not sufficient to decide which category is in which. So you need a 4th column parent
that will store the id of a parent category of each category or product. And whether it is a category or object, they all have a category as parent or null for the root.
在每个产品页面上,我猜你可以访问哪个产品属于哪个类别。如果数据库模式与您提供的体系结构类似,则不足以确定哪个类别属于哪个类别。因此,您需要第4列父类,它将存储每个类别或产品的父类别的id。无论它是一个类别还是一个对象,它们都有一个类别作为根的父类别或null。
In php in the page that generates URL for category or product you need to fetch from database all the categories associated to the current item and climb up the tree from the last nested node (the current item) to the root.
在为类别或产品生成URL的页面中的php中,您需要从数据库中获取与当前项相关的所有类别,并从最后一个嵌套节点(当前项)爬升到根节点。
So you will have a loop as the simplified code bellow.
因此,您将有一个循环作为简化的代码波纹。
Tip:
提示:
- If small amount of items, fetch all at once from db to save database queries and then loop on your results (in an array) - call it case a;
- 如果条目数量很少,则立即从db中获取所有条目,以保存数据库查询,然后对结果进行循环(在数组中)——称之为case a;
- Otherwise start from querying only the current item from its id and get its parent, then in the loop do another query to get the new parent again - call it case b;
- 否则,从只从其id查询当前项并获取其父项开始,然后在循环中执行另一个查询以再次获取新父项——称为case b;
So you get the parent of the parent and so on until parent is null.
你得到父结点的父结点,直到父结点为空。
<?php
$itemTree = [];
$allDBItems = mysql_query('SELECT * FROM items');
while($parent)
{
// getParent() is a function that loops on $allDBItems - in case a - and break loop on found $currItemInLoop['id'] === $myItem['parent']
// or - in case b - query the db like mysql_query("SELECT * FROM items WHERE id = $myItem[parent]");
$parent = getParent();
if ($parent) $itemTree[] = $parent;
}
$itemUrl = implode('/', array_reverse($itemTree));
yay, you have the url generated!
你已经生成了url !
for step #2
步骤# 2
in .htaccess
redirect all the urls to page.php
with no exception as follow (I hope you can have a better name than page.php
or at least index.php
that makes sense as root script).
在。htaccess中,将所有url重定向到页面。php也不例外(我希望您能有一个比page更好的名字。php或至少是索引。作为根脚本的php)。
RewriteRule ^(.*)$ index.php?path=$1 [NC,L,QSA]
Almost like @Vrac wrote.
就像@Vrac写道。
Then in index.php
do as @Vrac wrote:
然后在索引。php do as @Vrac写道:
$path = $_GET('path');
$patharray = explode('/',$path);
//do processing based on contents of patharray
$category = $patharray[0];
$product = $patharray[1];
//etcetera, etcetera...
//serve up content based on the path that was requested
You have it complete! :)
你已经完成了!:)
#2
1
I understand from your description that there are two problems: 1) converting requests from existing links to "pretty urls" and 2) processing "pretty urls" going forward. Since you need to do a database lookup to map requests from existing links to the new url, .htaccess won't help much with problem #1. I'm assuming there are already a bunch of links out in the world that point to page.phpid=xx
In your page.php
you could do the database lookup then send the redirect, something like (pseudo-code-ish):
我从你的描述中了解到有两个问题:1)将现有链接中的请求转换为“漂亮的url”,2)处理“漂亮的url”。由于需要进行数据库查找,以便将现有链接中的请求映射到新的url,所以.htaccess对于问题#1没有多大帮助。我假设世界上已经有很多指向页面的链接。页面phpid = xx。php您可以进行数据库查找,然后发送重定向,类似(伪代码):
(you'll have to "flatten" your table into a single string with a crosstab query, that's a separate issue I won't deal with here, say for the sake of argument you've done it and wind up with a single string as url)
(必须使用交叉表查询将表“压平”为单个字符串,这是我在这里不讨论的另一个问题,假设您已经完成了这个操作,并以单个字符串作为url结束)
$id = $_GET('id');
select concat(category,product, etcetera, etcetera) as url from mypagestable where id = $id;
//redirect the browser to the pretty url
header("Location: $url",TRUE,301);
//stop processing here, browser will get the new url and request that instead
exit;
Now a request will come in from the browser for the new "url", in htaccess you can put this:
现在一个请求将从浏览器中输入新的“url”,在htaccess中,你可以把这个:
RewriteCond %{REQUEST_URI} !^page\.php
RewriteRule ^(.*)$ mynewurlprocessor.php?path=$1 [NC,L,QSA]
This will ignore any requests to page.php, because you are already dealing with those requests in page.php you don't want to mess with them. mynewurlprocessor.php gets the path requested as a querystring parameter, so in mynewurlprocessor.php you do something like:
这将忽略对页面的任何请求。php,因为您已经在页面中处理了这些请求。你不想把它们弄得一团糟。mynewurlprocessor。php获取请求的路径作为querystring参数,因此在mynewurlprocessor中。php您可以做以下事情:
$path = $_GET('path');
$patharray = explode('/',$path);
//do processing based on contents of patharray
$category = $patharray[0];
$product = $patharray[1];
//etcetera, etcetera...
//serve up content based on the path that was requested
Because, as you say, the content is dynamic and database-driven, best to keep all that logic in php and only use htaccess to provide your php scripts with the data they need to serve the right content. Having another column for "slug" is a good idea. Your question is quite broad, I'm just giving you a high-level view of how I would design it. If you have questions about the mechanics of turning your table id-type-name
structure into a flat string or how to turn the "pretty" request into a database query on the other end, I suggest you make new, more specific questions for those.
因为,正如您所说的,内容是动态的和数据库驱动的,最好保持php中的所有逻辑,并且只使用htaccess为您的php脚本提供所需的数据以提供正确的内容。再写一篇关于“鼻涕虫”的专栏文章是个好主意。你的问题很宽泛,我只是给你一个我如何设计它的高级视图。如果您对如何将表id-type-name结构转换为扁平字符串或如何将“漂亮”请求转换为另一端的数据库查询有疑问,我建议您针对这些问题提出新的、更具体的问题。
#3
0
In your .htaccess
file please paste this code:
在。htaccess文件中,请粘贴以下代码:
RewriteBase /
RewriteRule ^([a-zA-Z0-9=^_-]+)$ home.php?sname=$1
RewriteRule ^([a-zA-Z0-9=^_-]+)/$ home.php?sname=$1
RewriteRule ^([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)$ home.php?sname=$1&dname=$2
RewriteRule ^([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/$ home.php?sname=$1&dname=$2
RewriteRule ^([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)$ home.php?sname=$1&dname=$2&catname=$3
RewriteRule ^([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/$ home.php?sname=$1&dname=$2&catname=$3
RewriteRule ^([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)$ home.php?sname=$1&dname=$2&catname=$3&subcat=$4
RewriteRule ^([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/([a-zA-Z0-9=^_-]+)/$ home.php?sname=$1&dname=$2&catname=$3&subcat=$4
and url access like this:
url访问如下:
http://www.domain.com/confectionery-&-snacks/lollies/cola-zombie-chews/abc
http://www.domain.com/confectionery-&-snacks/lollies/cola-zombie-chews/abc
$sname= confectionery-&-snacks
$dname= lollies
$catname= cola-zombie-chews
$subcat= abc
I hope you understand it.
我希望你能理解。
Ask me again if you're facing any problems.
如果你遇到什么问题,再问我一次。