如何创建一个简单的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”链接中模仿相同的功能,所以我们这样做:

  1. 将所有URL请求重定向到一个位置进行处理。
  2. 检查链接表并获取我们需要的数据,id和type。
  3. 根据元素类型,我们调用合适的插件来处理和显示数据。

将所有请求用一个脚本处理

如果我们希望所有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中经过充分测试的东西。

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容