如何创建一个简单的PHP CMS以及生成SEO友好的URL
源码 & 更多资源
简单的PHP CMS教程
SEO(Search Engine Opeimization, 搜索引擎优化)对每个网站都是非常重要的。如果你不优化你的站点,搜索引擎就不会找到你的网站。因此就没有人访问网站。
本教程只解释SEO的一个方面,让网页有一个友好的URL。很多年前我们知道phpNuke和Joomla,但是他们都有一个相同的问题,那就是他们的网页链接看上去都很丑:"index.php?id=653&page_type=blog&lang=en"。这些链接看上去都差不多,非常不容易输入。像Google这样的搜索引擎也不喜欢这种类型的URL。
如今,新一代CMS出来了,有些是使用CodeIgniter框架制作,有些使用Moodle或者Drupal。但是这些CMS还是存在类似的SEO问题。Wordpress很快在这之后出来了。
这些CMS的一个缺陷就是,它们是为了一般用途的站点而制作的。例如,Wordpress最初是一个博客系统,现在提供插件来制作任何类型的网站。但对于这样的系统,你需要大量的类,代码,插件和维护。
另一件事是,您无法在获取源代码的情况下为客户销售GPL许可代码。 他们最终会听到你让他们为开源软件付费,他们可能不喜欢这样。
鉴于此,可能最好的解决方案是制作自己的CMS,轻量级。 您可以按照自己的意愿许可它,在编写它时就会非常清楚,并且拥有自定义数据库结构。
我们将面临的问题是"index.php?id=653&page_type=blog&lang=en"问题。因此,让我们看看如何制作一个CMS具有SEO友好的URL。
PHP SEO友好URL链接
SEO友好链接必须有页面标题,它们需要是可读的,他们必须摆脱index.php。例如“how-to-make-seo-friendly-links”或“make-a-class-for-php-classes-site”,如你所见,其中没有index.php,没有任何文件最终的名称扩展,它是非常可读的,你可以从链接获得标题。非常重要的一点是,必须动态生成这些链接。
那么让我们回到“index.php?id=653&page_type=blog&lang=en”,当我们解决它时,我们有“index.php”,它是CMS中处理所有请求的最主要PHP文件。
我们有文章的“id”参数,我们有一个“type”参数,本例中它的值是“blog”,但它可以是任何东西,product,article或blog。最后我们有一个“lang”参数,它适用于具有多种语言的网站,在本教程中,我将跳过“lang”参数。我们需要在“how-to-make-seo-friendly-links”链接中模仿相同的功能,所以我们这样做:
- 将所有URL请求重定向到一个位置进行处理。
- 检查链接表并获取我们需要的数据,id和type。
- 根据元素类型,我们调用合适的插件来处理和显示数据。
将所有请求用一个脚本处理
如果我们希望所有URL都由一个脚本处理,或者说由ndex.php文件处理,我们需要配置.htaccess文件。 我们需要在我们的Web服务器上安装Apache,它通过.htaccess文件提供配置控制。.htaccess文件必须使用RewriteEngine指令启用URL重写模块。然后只需添加规则即可将所有请求转至index.php。
RewriteEngine On
RewriteBase /cms/
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteCond %{REQUEST_FILENAME} !-f [NC]
RewriteRule ^(.*)$ index.php?pid=$1 [QSA,L]
仔细设置这些指令很重要。在上面的示例中,我将所有流量重定向到index.php,除非有人直接访问PHP或HTML文件,或者请求路径位于文件夹中的图像,CSS或JS。
使用[NC]标志会使RewriteRule以不区分大小写的方式匹配。 也就是说,它不关心字母在匹配的URI中是以大写形式还是小写形式出现。
开始编写index.php
现在我们将所有请求都由index.php处理,这里我们需要进行一般检查:谁来到这里以及他需要什么。 index.php就像一个流量管理器。 我们需要捕获即将到来的链接并使用我们之前生成的所有链接查询MySQL数据库中的特殊表,我们获取与链接URL关联的页面的id和type。 让我们先看看表结构:
CREATE TABLE IF NOT EXISTS `members` (
`memberID` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL DEFAULT '',
`password` varchar(60) NOT NULL DEFAULT '',
PRIMARY KEY (`memberID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
INSERT INTO `members` (`memberID`, `username`, `password`) VALUES
(1, 'admin', '$1$8I4.v32.$bV9MWNrNAFA1bdD/JS/FW1');
// Username - admin , Password - demo
下面让我们看看PHP代码:
<?php
error_reporting(E_ALL & ~E_NOTICE & ~E_USER_NOTICE);
define('pageclassconst', TRUE);
include_once 'admin/pages/pageClass.php';
$pageClass=new pagesClass();
$pageList=$pageClass->listPages();
$pid=$_GET[pid];
if($pid==""){
$pageDetails=$pageClass->particularPageSlug($pageList[0]['URL']);
}
else
{
$pageDetails=$pageClass->particularPageSlug($pid);
if($pageDetails[id]==""){
header("location:404.php");
}
}
?>
如您所见,首先我们得到了请求URL中的“$pid”。然后我们使用语句查询数据库以获取元素的type和id。如果该元素不存在,我们会将代码重定向到自定义的404页面。
如何获取SEO友好URL信息
获取我们元素的type和id之后,剩下的就简单了。我们需要发起另一个请求根据URL类型去获取元素细节。
因此,让我们假设我们的CMS中有两种类型的元素:products和blogs。 如果是blogs,我们会查询blogs表并要求blogs.php文件来处理该页面。 如果是products,我们查询products表并获取其详细信息,然后我们调用products.php来显示该页面。这些是products和blogs表:
CREATE TABLE IF NOT EXISTS `pages` (
`pageID` int(11) NOT NULL AUTO_INCREMENT,
`pageTitle` varchar(255) DEFAULT NULL,
`isRoot` int(11) NOT NULL DEFAULT '1',
`pageCont` text,
PRIMARY KEY (`pageID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
----------------------------------
CREATE TABLE IF NOT EXISTS `webpages` (
`id` int(9) NOT NULL AUTO_INCREMENT,
`Title` varchar(255) NOT NULL,
`URL` varchar(255) NOT NULL,
`Keywords` varchar(150) NOT NULL,
`Description` varchar(250) DEFAULT NULL,
`PageDetails` varchar(5000) DEFAULT NULL,
`PageName` varchar(90) DEFAULT NULL,
`PageType` int(3) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=17 ;
public function particularPageSlug($id) {
$list="select * from webpages where URL='$id'";
$result= $this->query($list);
$count= $result->num_rows;
if($count < 1){}else{
while($row= $result->fetch_array(3)){
return $row;
}
}
}
在管理界面中创建SEO链接
我们已经看到如何重定向URL请求到index.php并且根据URL类型决定显示product和blog类型信息。现在我们要看一下如何在管理界面创建这些链接并将它们添加到"urls"表。
当我们添加一个blog的时候,我们将所有数据插入到“blogs”表中,现在我们要获取blog id。我们需要在“urls”表中使用这个id。我们还需要title去创建链接。现在我们将使用create_link()函数:
<?php
public function addPage($data){
$message=new alertClass();
$data["PageDetails"]=$this->real_escape_string($data["PageDetails"]);
$data["URL"]=$this->slug($data["URL"]);
if($this->dulicatePage($data["URL"])<1){
$keys=array_keys($data);
$values=array_values($data);
date_default_timezone_set ("Asia/Kolkata");
$table="webpages";
$query='INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES ("'.implode('","', $values).'")';
$result= $this->query($query) or die($this->error);
if($result){
unset($_POST);
return $message->getAlert("Page is added ", "success");
}
else
{
return $message->getAlert("Error while adding page", "error");
}
}
else
{
return $message->getAlert("Already Exists", "error");
}
}
?>
如您所见,我们总是首先插入博客,然后获取它的插入ID,并获得标题。 然后我们使用create_link函数从标题创建一个新的URL,这样我们就可以在urls表中插入一个新行。
下面我们开始写slug()函数
<?php
private function slug($string){
$string = strtolower(trim($string));
$string = str_replace("'", '', $string);
$string = preg_replace('#[^a-z\-]+#', '-', $string);
$string = preg_replace('#_{2,}#', '_', $string);
$string = preg_replace('#_-_#', '-', $string);
$string = preg_replace('#(^_+|_+$)#D', '', $string);
return preg_replace('#(^-+|-+$)#D', '', $string);
}
public function dulicatePage($name){
$check="select * from webpages where URL='$name'";
$result= $this->query($check);
$count= $result->num_rows;
if($count < 1){return 0;}else{return $count;}
}
?>
slug()函数获取blog或product的title,并转换成小写。然后移除特殊字符以及将空白字符替换成“-”。
我们还需要检查我们得到的URL是否已经存在于“urls”表中。我们需要让所有的URL在表中都是唯一的。
我们使用dulicatePage()函数检查URL是否重复。然后我们递归的调用“slug”,直到我们获取唯一的URL。
示例代码是以一种简单的方式编写,方便您理解概念。它不应被视为真正的CMS中经过充分测试的东西。