wordpress后端优化详解

 前言

很多时候我们在进行wordpress开发时优化是重中之重的一个部分,而后端程序优化的好坏与否更是直接决定了网站的访 问速度。本文的目的就是就是以通俗易懂的语言详细讲解wordpress后端程序优化的点点滴滴。如果你永远分不清字节码缓存和对象缓存之间的区别,或者 你总是在选择wordpress优化插件时在W3 Total Cache,WP Super Cache,Hyper Cache,DB Cache Reloaded Fix中犹豫不决不知道哪一个适合你,又或者你不知道或不清楚APC(Alternative PHP Cache) ,Xcache,Zend Opcache ,eaccelerator ,Redis,Memcached是什么和他们之间关系,那么就需要你仔细阅读下文,相信你心中的疑惑会在读完本文后得到满意解答。

PHP运行流程

只有深入了解才能加深理解,所以只有当我们了解了PHP的运行流程时才更能理解wordpress后端优化方法的优化原理和方式。那PHP的运行流程又是怎样的呢?

PHP运行流程

从图上我们可以知道用户查看一个PHP页面经历了以下的流程:

用 户浏览器向服务器发起请求 -> 服务器处理请求并运行PHP文件 -> zend引擎将PHP代码编译为字节码(也称opcode) -> zend虚拟机运行字节码 -> 服务器连接数据库并获取数据 -> 生成HTML并返回给用户浏览器 -> 用户查看页面

知道了PHP的运行流程后我会按照PHP运行流程顺序介绍在PHP运行的各个步骤上可以使用的优化方法。

WP Super Cache

WP Super Cache是 一个静态缓存插件。我们知道服务器接受用户请求后会调用PHP引擎运行PHP文件,WP Super Cache的作用就是它会把整个网页直接生成 HTML 文件,这样服务器就不用解析脚本并连接数据库,相当于直接浏览静态页面,大大节约了加载时间和服务器资源。但缺点就是任何动态的代码都不会运行会和一些 wordpress插件产生冲突。非常推荐一些运行在共享主机上的网站使用。

Hyper Cache

Hyper Cache和WP Super Cache一样是一个静态缓存插件。Hyper Cache 虽然会生成静态的页面(不是 HTML 网页,而是序列化后的二进制数据 .dat文件),但为了保证插件适用范围更广,Hyper Cache 仍然依赖于 WordPress 的插件机制,当有访问请求时,Hyper Cache 首先会检查是否生成了缓存,如果缓存存在,把二进制缓存数据反序列化并返回,否则生成缓存。非常推荐一些运行在共享主机上的网站使用。

字节码缓存

PHP 文件运行时zend引擎首先将会将PHP代码编译为字节码(也称opcode)一种服务器能看懂二进制文件,然后将这些字节码交由zend虚拟机执行。如 果文件没有修改,那么字节码也会保持不变, 这意味着编译是完成了,但是白白浪费了CPU资源。这就是引入字节码缓存的原因,通过把字节码保存在内存中来消除冗余的编译,重用它们完成后续的调用。字 节码缓存可以极大地提高应用的执行效率并节约服务器资源。 流行的字节码缓存方案有:APC(Alternative PHP Cache) ,Xcache,Zend Opcache(原Zend Optimizer+),WinCache,eaccelerator等。其中最优秀而且最给力的并且兼容度最高的是Zend Opcache,其次是eaccelerator(目前貌似已经被开发者放弃)。

对象缓存

对象缓存其实就是一种缓存系统,通过使用系统提供的API你可以将一些数据缓存起来(大部分系统是将数据存储在内存中)以便后续使用中快速读写使用这些数据。

而 我们都知道网页生成过程过程中最耗时的部分就是执行数据库查询,如果我们能将SQL请求的结果通过使用对象缓存系统缓存起来,在后续对这些相同的SQL请 求中,就可以直接使用缓存中的数据。这么做可以很大的降低数据库负载,提升运行速度,减少服务器的负载实现更快的访问。

很多流行的字节码缓存方案也允许你缓存自定义数据比如APC(Alternative PHP Cache) 、XCache和WinCache都提供API, 让你把数据缓存在他们的内存cache中。

流行的对象缓存方案有:APC(Alternative PHP Cache) ,Memcached,Redis,XCache APIs,WinCache Function,eaccelerator-0.9.5等。比较优秀的有:Redis,Memcached。

那估计又有人有要问了那wordpress对象缓存(WordPress Object Cache )和对象缓存有什么区别呢?

要 彻底明白和搞懂 wordpress对象缓存和对象缓存区别,首先要理解wordpress对象缓存,它是把需要缓存的内容按照 Key-Value 这样的模式进行缓存(和 No-SQL 的 key-value 的有点类似),当然它还支持按照 Group 来划分和避免缓存的内容冲突。所以最基础的 WordPress 缓存插件就是,把 WordPress 产生的 Key-Value 存起来,如果是使用 Memcached,就是存到内存,如果使用 Flie 就是存到硬盘中。

这下明白了吧,wordpress对象缓存其实就是在更高层次的一种对对象缓存系统的兼容性抽象。因为不同服务器可能会安装不同的对象缓存系统,开发者不可能为每一种对象缓存系统都书写不同代码。于是wordpress开发了wordpress对象缓存系统(WordPress Object Cache ),提供了一套标准API供wordpress自身和开发者缓存数据。所以说对象缓存系统是wordpress对象缓存系统基础。

要 使用wordpress对象缓存必须要先安装对象缓存系统,然后再安装相应的对象缓存系统插件以供wordpress对象缓存系统调用相应对象缓存系统的 API。插件的一般安装方法:先在wordpress中搜索相应wordpress对象缓存系统插件并下载,解压下载下来的插件压缩文件并把文件内 object-cache.php 文件复制到wp-content文件夹下,注意不是 wp-content/plugins/。WordPress会自动检查在wp-content目录下是否有object-cache.php 文件,如果有,直接调用它作为 WordPress 对象缓存机制。一般wordpress启用对象缓存后可以将SQL查询量降到5次/页面。很多虚拟主机主机商提供的PHP环境是自带对象缓存系统的,你可 以通过探针查看。若果没有,你也可也open a ticket给你的主机商要求安装对象缓存系统,一般的主机商都会帮助你安装的。

Batcache

WordPress 启用对象缓存之后,每次访问 WordPress 页面,都要从内存中获取多个缓存对象还是很耗时。而 Batcache 主要就是解决这个问题,它是基于 Memcached 的 WordPress 缓存插件,它的工作原理是:把当前整个页面作为一个对象缓存到内存中,这样再次访问 WordPress 页面的时候,直接获从内存中获取这个对象即可,速度极快。并且这个插件也是 WordPress.com 官方使用的加速插件之一。建议安装了 Memcached对象缓存系统的用户安装。

安装这个插件有点麻烦,不过只要按照以下步骤进行就可以:

  1. 安装好 Memcached
  2. 上传 advanced-cache.php 到 /wp-content/ 目录。
  3. 在 wp-config.php 添加以下代码激活 Batcache:
  4. define(‘WP_CACHE’, true);
  5. 然后尝试多次载入页面查看源代码,应该在 之前可以看到一些 Batcache 状态代码。(未登录状态)
  6. 可以修改 advanced-cache.php 开始的一些代码来调整选项。
  7. 可选的上传 batcache.php 到你的 /wp-content/plugins/ 目录。

DB Cache Reloaded Fix

DB Cache Reloaded Fix(目前貌似已经被开发者放弃,两年未更新)其实是一个和对象缓存系统效果一样插件,原理都是通过缓存数据库请求来减少数据库查询次数,提高数据库执行效率。

W3 Total Cache

W3 Total Cache估 计是最强大一款wordpress缓存插件,他的优化原理不仅仅局限于对象缓存,生成静态页面,而是包括我上面介绍的wordpress优化的一切(毫不 犹豫):Page Cache、Database Cahe、CDN、Minify、Object Cache、Browser Cache。你能想到的一切优化你都可以用W3 Total Cache做到。W3 Total Cache确实强大,不过好像并没有见到很多人推荐,因为W3 Total Cache的使用曲线过于陡峭,非常难设置。不过相信今天你看完这篇文章后就能很容易的驾驭W3 Total Cache这批汗血宝马,能够使用这把锋利的大宝剑优化你的网站。

HipHop Virtual Machine(HHVM)

HHVM是本篇文章重头戏,因为在国内以前介绍wordpress优化的文章中几乎未发现大家提及HHVM这个神器。HHVM比传统zend虚拟机+字节码缓存+对象缓存要快9倍,内存节约500%,cpu节约50%-300%。那HHVM又是什么呢?是什么让他如此神奇呢?

HHVM 是Facebook团队开发的一个执行 Hack 和PHP语言的开源虚拟机。HHVM采用的是just-in-time (JIT) 编译的方法来实现卓越的性能.。HHVM (HipHop Virtual Machine)会将PHP代码转换成高级别的字节码(通常称为中间语言)。然后在运行时通过即时(JIT)编译器将这些字节码转换为x64的机器码并运 行。

你没看错,我知道你和我当时看到介绍时的感受一样,Facebook从出生到现在一直还都运行在PHP上!Facebook为了应对不断增长用户数量开发了HHVM这款虚拟机(开发历史),而且这东西已经在国内某大型电商网站线上使用了1年多了,可以说HHVM是未来PHP发展的方向。所以说强烈推荐各位VPS用户安装HHVM,可以将你的网站性能提升一个数量级。安装也十分简单,只需一两步。HHVM主页上有不同系统的详细安装步骤这里不再赘述。

另这里摘录一下@ivmm童鞋关于缓存器使用的一些注意点(原文),希望能帮到各位童鞋。

 

效果说明

一 般的话字节码缓存应用用与单一的php文件不包括数据库的,而对象缓存则是应用与对php的数据库拓展之中。但是php的流行程序 都是需要数据库的所以你要优化程序的执行环境那么就要同时具备两种特性。所以单靠一类缓存特性是不能体现整体性能的,所以要两类综合考虑。综合考虑和对 php的兼容度以及对程序的兼容度那么最优秀的是:Xcache,Apc。经过前人和本人的多次测试,Xcache应用于VPS或者服务器性能由于 Apc;但是在虚拟主机的多用户环境中Apc由于Xcache。

缓存器共存

由于一些缓存器是不兼容两类缓存的,所以我们可能会需要多种缓存器一起共存来使用。但是缓存器共存有可能不仅不能很好的体现性能或者性能还不如单一缓存器更甚者可以报错!下列是推荐的 流行并且可靠的缓存器共存方案:Memcached(Redis)+Zend Opcache是对象缓存和字节码缓存的佳作,是最能体现性能的,目前大多数的大型网站是通过这类方案的。当然了你可以自己搭配只有对象缓存和只有字节码缓存的共存。

注意:

1.非单一类缓存器与单一类缓存器共存会降低性能。

如:Xcache+Zend Opcache就会有对象缓存能力不如单一Xcache而字节码缓存能力又不如Zend Opcache的情况。

2. Xcache和Apc不能完美共存

RT,不能完美共存,用多了会报错。

3.Xcache和Memache不能完美共存

RT,不支持部分软件。

4.性能比较:

Memcached(Redis)+Zend Opcache(eaccelerator-1.0dev)在大环境中性能由于单一Xcache或者Apc。

小环境中则相反。

注意点

1.eaccelerator为什么不被广泛支持了?还有价值么?

eaccelerator-0.9.5包括之前的版本中eac是支持字节码缓存和对象缓存的,但是到了0.9.6包括最新的1.0dev都是只有字节码缓存了的。所以你看Discuz都是不会显示支持eaccelerator-0.9.6版本的。

eaccelerator- 0.9.5的整体性能不如Xcache和Apc,eaccelerator-0.9.6或者1.0dev的字节码性能不如Zend Opcache,所以eaccelerator已经不怎么适用了的。而且eaccelerator-0.9.5不支持Php5.3及其更新的版本。

后记

好长时间没写文章,洋洋洒洒又是一篇满满都是干货的文章,wordpress后端优化角角落落差不多能写到的都写到了,业界良心,有没有!如果你发现任何有关于wordpress后端优化我没提到的或者你想知道的又或者任何问题、任何错误、任何话题想跟我吐槽,不要犹豫请在下面留言我会很高兴和你交流!

根据访问设备加载wordpress主题

估计很多wordpress开发者都有这样感受,在写主题时为了兼容一些老浏览器需要写很多怪异的HACK。或者很多用html5,css3一句话能解决的问题,为了兼容却要花很多功夫。有时又为了移动设备访问便捷又要做很多工作。其实现在有更好的解决办法,为不同的访问设备加载不同主题。肯定会有人这样疑问,我直接用bootstrap做一个响应式主题不就好了,兼容一切设备,anything is nothing,哪要那么麻烦。但你要知道,这世界上没有无懈可击的Web设计(名字来源于一本书标题,超棒的一本好书,强烈建议各位前端必看.我看的这本是第二版,好像第三版也有了不过好像是介绍html5和css3的,没看过也不好推荐,如果哪位看过了欢迎在下面留言介绍感受。),响应式主题不是万精油。有些特定设备需求其实并不一样,像移动设备就需要更大文字更大的按钮和更少的图片,过时浏览器其实并不需要绚丽外观等等。你可以根据不同设备做出相应有需要的修改,让更完美的界面在用户屏幕上绽放。不管怎么说掌握权在你,你需要根据自己项目需要决定使用响应式主题还是为每种设备写个主题。话不多说,上代码!

//根据访问设备切换wordpress主题
function switchtheme($theme){
global $is_IE;
if($is_IE){
preg_match('/MSIE\s(\d)\.0;/', $_SERVER['HTTP_USER_AGENT'], $matches);
$IEversion = $matches[1];
if($IEversion=6){
$theme='twentyten';
}
if($IEversion=7){
$theme='twentyeleven';
}
if($IEversion=8){
$theme='twentytwelve';
}
}
if(wp_is_mobile()) {
$theme='twentytwelve';
}
return $theme;
}
add_filter( 'template', 'switchtheme' );
add_filter( 'stylesheet', 'switchtheme' );

你可以根据上面的代码自行修改,在何种设备访问时加载什么主题。注意主题名字一定是主题文件夹名字,而不是后台管理界面你看到的主题名字。而且这次代码也不能直接扔进functions.php文件中而是要做成一个插件上传启用。不过还要注意一点,在这里我用了wp_is_mobile()这个wordpress自带函数来检测移动设备,不过这个很不准确,有很大可能不能正确判断移动设备。推荐使用鱼叔介绍的Mobile_Detect:移动设备(手机)检测的 PHP 类库 来精确检测移动设备。不仅仅用这个类检测移动设备,而且检测桌面浏览器版本,种类也是很方便很准确的。而且你可也在发挥下,稍稍改下代码,就能实现让用户自行选择使用桌面网站还是移动网站。

最后再介绍个小技巧,在测试主题时有时并不需要多个浏览器一个个测试,在Chrome控制台就可也很方便模拟不同分辨率和USER_AGENT。很方便测试网站在移动设备下体验。

chrome

 

wordpress发送验证邮件验证用户新邮箱

大家都知道wordpress在注册时不能填写密码,而是在注册后发送一份包含密码的邮件到你注册的邮箱。wordpress这样做的目的大概是为了确保用户邮箱真实性。但在注册后,用户在我的个人资料页面却可以轻易修改邮箱而不需要任何验证。即使用户填了假邮箱,管理员也没办法知道。这让wordpress在注册时验证邮箱等于白花了功夫,吃力不讨好。看了下源码,其实wordpress是包含了邮箱验证功能的,可以在用户修改邮箱后发送一封验证邮件到新邮箱。但只在wordpress MU下起作用,也不知道wordpress这样做目的何在。于是我提取并修改了部分代码,做成了一个插件,一键启用,马上让你的wordpress用上邮件验证。

verify-user-new-email

【翻译】WordPress查询简介

这篇文章是写给想要做高级查询和固定链接的插件开发者,同时也是写给想要更深入的了解WordPress或想要向WordPress核心添加功能或者修复WordPressBUG的开发人员,关于WordPress创建博客网页过程以及插件如何更改这个过程的概述。

更多的信息,你需要阅读WordPress源码和提及函数的文档。

WordPress执行以下的步骤,决定在网页上显示哪一篇文章或者哪一个页面,并且如何显示它们。

  1. 当访问者点击你的网站或者输入你网站中一个页面网址时 ,WordPress就开始运行一些核心文件 (wp-config.phpwp-settings.php, 等等.)如果你对文件载入顺序的详细信息感兴趣,你可以从index.php开始,查看每一个通过includes/requires导入的php文件。(或者阅读这篇优秀的介绍文章 humanshell.net)
  2. WordPress载入并初始化任何你启用的插件。(称作插件的 init动作)。
  3. 为了国际化的需求,WordPress载入”text domain”,同时载入当前主题的functions.php文件。
  4.  WordPress通过调用$wp->main() ($wp 是WP类的一个对象, 定义在 wp-includes/class-wp.php)运行 wp() 函数 (在wp-includes/functions.php), 这告诉WordPress:
    1. 使用WP->parse_request()将URL解析成查询规范(query specification) –后面有更详细的介绍。(YOUNG注:其实就是控制器的路由)
    2. 使用$wp_query->parse_query() ($wp_query 是 WP_Query类的一个对象, 定义在 wp-includes/query.php)设置所有is_ 条件判断标签 函数的返回值 。注意尽管函数的名称是那样的,但在这里WP_Query->parse_query 不会为我们做任何解析,,因为解析是通过 WP->parse_request()在之前解析好的。
    3. 将查询规范转换为MySQL数据库查询语句,通过使用数据库查询函数WP_Query->get_posts()得到文章。 将文章保存在 $wp_query 对象以供WordPress Loop使用。(YOUNG注:其实就是创建模型)
    4. 处理404 错误。
    5. 发送博客 HTTP头。
    6. 为WordPress Loop设置一些变量。
  5. WordPress通过模板层级结构载入并运行你的主题模板文件(基本上是执行模板文件的命令)。或者 WordPress运行feed文件(像 wp-rss2.php)。(YOUNG注:其实就是调用视图)
  6. 一般来说, 模板或feed文件通过运行 WordPress Loop来输出博客文章或者静态页面。
  7. 模板或feed文件也有可能使用WordPress内置函数,为存档,分类,或者文章输出固定连接。

关于 WP->parse_request()的详细介绍

如上所述, WP->parse_request() ( WP类的一部分在 wp-includes/classes.php) 会将URL解析成查询规范。下面是这个步骤的总结:

  1. 将GET请求从URL中整理出来 (例如URL中”?”后的任何内容)。同时也会去掉博客主页URL。
  2. 通过调用$wp_rewrite->wp_rewrite_rules()($wp_rewriteWP_Rewrite类的一个对象, 定义在 wp-includes/rewrite.php)得到当前有效的重写规则。重写规则基本上是一组WordPress固定链接匹配模式, 规定了当模式匹配时,应该做什么。例如, 默认情况下,有一个规则会匹配整理过的固定链接像category/abc, 它告诉我们去请求”abc” 分类的文章。主页同样也有一个重写规则(博客URL后什么内容也没有)。
  3. 按顺序查看每一个重写规则,直到找到与固定链接匹配的重写规则。如果没有发现匹配就发送404 错误。如果找到了匹配,,WordPress根据重写规则,提取信息。
  4. 得到当前允许的请求变量名称。对于每一个请求变量名称, WordPress检查是否有由固定链接解析得到, POST 提交, 或者GET提交的变量值, 如果有, WordPress 将变量及值保存在query specification数组 ($wp->query_vars, 类WP的一部分在wp-includes/classes.php).

插件可以更改什么

下面是一个关于插件可以怎样更改默认查询和固定链接的简介。更详细的介绍 (带有例子)你可以阅读自定义查询

  • 添加,更改, 或者删除重写规则, 来改变固定链接的解析方式这些不是通过过滤器或者动作完成的, 而是通过调用wp-includes/rewrite.php中的函数实现的, 像 add_rewrite_rule,add_rewrite_endpoint, 等等. 这样做需要些技巧,因为WP_Rewrite->wp_rewrite_rules() 通常只得到先前保存的重写规则(这些规则作为WordPress “rewrite_rules”设置选项的值保存在数据库里). 因此你想更改重写规则, 你需要调用$wp_rewrite->flush_rules()来让它们重置。你需要在你的插件activation/deactivation/uninstall动作时来更改重写规则,因为这些动作发生的足够早。请不要在每次请求时更改,这些更改只能在插件activation等类似动作时做.
  • 通过(query_vars 过滤器)增加或删除允许请求变量名称,来影响来自,POST, GET, 或者固定链接请求的哪些变量及值能被保存在query specification数组。
  • 在请求值保存之后更改query specification数组(request 过滤器或者 parse_request 动作; 如果你想使用条件判断标签函数, 使用 parse_query或者pre_get_posts 动作, 它们在is_ 变量设置好之后才运行).
  • 更改数据库查询语句, 在它在查询规范创建好之后,使用下面的过滤器:
    • posts_where
    • posts_join
    • posts_groupby
    • posts_orderby
    • posts_distinct
    • posts_fields
    • post_limits
    • posts_where_paged
    • posts_join_paged
    • posts_request
  • 更改数据库查询结果(the_posts过滤器)。
  • 废除默认模板文件选择(template_redirect动作)。

P.S.你也可以安装Rewrite Rules Inspector插件来查看网站重写规则,不看不知道一看吓一跳,原来wordpress有这么多重写规则

Rewrite Rules Inspector - Binaryoung — WordPress

【翻译】wordpress角色和权限终极指南

     前言:这是一篇非常好的关于wordpress角色与权限系统的文章(原文:Ultimate Guide to Roles and Capabilities),通过此文我们可以深入理解和学习wordpress的用户系统,此文讲解详细易懂,所以非常长,需要您的耐心。现将全文翻译如下:

由于在WordPress 2.0中引入角色和权限 系统, 用户级别的方法已被弃用。然而,令人失望的是,还有很多插件和主题仍然使用用户级别的方法控制用户查看设置页面和其他功能。本指南将告诉你如何在你的插件和主题中正确使用角色和权限系统。

 :本文非常长,因此,你应该将本文加入收藏夹,以便你可以随时回来学习或参考本文。

 

目录

  1. 什么是角色和权限?
  2. 权限和管理菜单
  3. 检查用户的权限
  4. 添加自定义用户角色
  5. 添加自定义用户权限
  6. WordPress的权限类

什么是角色和权限?

和其他CMS和Web应用程序一样,WordPress有一个内置的系统来验证一个特定的用户是否有足够的权限来进行某种行动。用户分为角色,每个角色都分配一定的权限。下面是WordPress默认角色的总结:

管理员 -拥有所有的管理权限

编辑 -发表文章,编辑文章,以及编辑其他人的文章,等等。

作者-发布和编辑自己的文章

投稿者 -撰写和编辑自己的文章,但不能发布

订阅者 -查看评论/添加评论/查看文章,等等。

该系统的角色和权限方法比用户级别灵活得多,因为您可以添加,删除或重新分配角色的权限。您甚至可以添加更多的角色,但不破坏系统内置角色。

权限和管理菜单

几乎每一个插件都需要在控制面板添加一个管理页面,让用户自定义插件选项。为了做到这一点,你需要添加自己的管理页面菜单 。这有一大堆WordPress函数,你可以这样做:

// 添加菜单
add_menu_page(page_title, menu_title, capability, handle, [function], [icon_url]);

// 添加子菜单
add_submenu_page(parent, page_title, menu_title, capability, file/handle, [function]);

//添加选项菜单子菜单
add_options_page(page_title, menu_title, capability, handle, [function]);

//添加管理菜单子菜单
add_management_page(page_title, menu_title, capability, handle, [function]);

//添加页面菜单子菜单
add_pages_page( page_title, menu_title, capability, handle, [function]);

//添加文章菜单子菜单
add_posts_page( page_title, menu_title, capability, handle, [function]);

//添加主题菜单子菜单
add_theme_page( page_title, menu_title, capability, handle, [function]);

正如你可以看到的,总有一个所需的参数,这些函数的capability 。这主要是指用户登录到控制面板,需要一定的权限才能看到菜单。您可以使用一个用户级别(已被废弃,不推荐),或一个字符串,表示某种权限(例如, edit_posts )。

许多插件仍然使用用户级别系统(用户的权限,从0到10的数字表示)。然而,这已被废弃,不应该再被使用。使用权限系统,您将不必担心有一天wordpress不再支持用户级别系统,如果你想添加和使用您的自定义权限,使用权限系统是必须之路。

如果你使用上面的函数在控制面板中添加菜单,只有当用户拥有指定的权限才可以看到菜单项,并访问与这些菜单相关联的页面。如果你的主题或者插件有一个管理页,这很重要的,你要限制用户访问该页面。例如,如果需添加一个主题选项页,您应该使用edit_themes权限添加菜单,而如果添加一个插件选项页,您应该使用edit_plugins 权限添加菜单。另一种方法是使用manage_options权限来限制访问插件和主题选项页。

请记住,有时博客管理员希望在其他几个用户中共享和划分工作。因此,使用权限系统,会使您的主题和插件更加个性化,人性化。

检查用户的权限

如果你的插件或主题允许用户更改博客的数据(添加新的内容或编辑现有的内容等),检查当前用户是否有足够的能力做出了一定的行动是非常重要的。current_user_can()函数可以让你轻松做到这一点:

if ( current_user_can( $capability ) ) {
    //做一些事如果用户拥$capability
}

此函数也可以接受一个可选的参数为postID,如果你想检查当前用户是否可以对特定文章进行某种操作:

// check whether the current can edit a post with the ID $post_id
current_user_can( 'edit_post', $post_id );

还有另外一个函数,您可以用它来检查某个文章的作者是否具有一定的权限:

if ( author_can( $post, $capability ) ) {
    // 做一些事如果文章$post的作者拥有$capability
}

第一个参数可以是一个文章对象,或一个文章的ID。虽然这个函数很少被使用,但知道它的存在是有帮助的。我从来没有使用过该函数,但如果你有一个有趣的使用该函数例子,请在评论让我知道!

添加自定义用户角色

有时有必要为你的插件系统添加新的角色。比方说,你要编写一个新的相册插件,用户可以注册上传照片到您的网站,但这些注册用户可以在您的网站上添加或修改任何其他类型的内容(如文章或页面)。做到这一点,最好的办法是添加一个新的自定义角色:

add_role( $role_name, $display_name, $capabilities );

// 例子:

add_role( 'photo_uploader', 'Photo Uploader', array( 'organize_gallery' ) );

这个函数的功能是添加一个新的角色并添加一组权限。上面的例子添加了一个被称为“photo_uploader”的角色,与显示名称和一个数组-包含该角色(上面的例子是, organize_gallery)的默认权限。

当您处理一个用户创建,编辑或上传相册的请求,你应该使用current_user_can()来检查当前用户是否有权限来采取这些行动。

if ( current_user_can( 'organize_gallery' ) ) {
    //做一些事
}

被赋予了这个角色的用户只可以organize_gallery ,但不能edit_postspublish_posts 。

要删除一个角色,你可以使用remove_role()函数

remove_role( 'photo_uploader' );

当他们决定卸载你的插件时,你应该有一个选项让你的插件的用户可以删除这些自定义角色。

但是,如果你想为现有用户添加权限该怎么办呢?

添加自定义用户权限

当你开发一个插件,允许用户进行操作并不仅仅是操纵文章内容这么简单,添加自定义用户权限是非常有用的。让我们回到我们的相册插件例子上。也就是说,如果你也想让现有的角色(管理员,编辑,作者,投稿者等)分配organize_gallery权限,你应该怎么做?

//得到"author"角色对象
$role = get_role( 'author' );

//为角色对象添加"organize_gallery"权限
$role->add_cap( 'organize_gallery' );

WordPress的权限类

我们已经讨论过了检查和添加权限,以及添加角色。这是管理WordPress用户权限最常用的函数。然而,由于这篇文章的标题包含“终极”二字,我想介绍这三个WordPress幕后工作的类,以及这些类提供的API,你可以在你的插件中使用这些类去进行高级权限管理。这三个类是:

  • WP_Roles
  • WP_Role
  • WP_User

这三个类的源代码您可以在wp-includes/capabilities.php中找到。源代码注释写得很详细,我敢肯定,你可以很容易理解,但我想总结一下,你可以怎样使用这些类。

WP_Roles类

这个类,正如它的名字所暗示的,是一般的角色管理。当你在你的插件中使用它,你可以不实例一个新的对象,而是使用WordPress中已创建的一个全局对象:

global $wp_roles;

   $wp_roles是一个全局对象,并且可以在你的函数的任何地方使用的对象,只要事先在你的函数中用global声明。

上面介绍过,你可以使用函数add_role()remove_role()添加和删除角色这些函数实际上被包装为$wp_roles->add_role() $wp_roles->remove_role 。因此,您可以使用$wp_roles对象添加和删除角色,例如:

global $wp_roles;

//添加新角色,和add_role()功能一样
$wp_roles->add_role( $role, $display_name, $capabilities )

//删除角色, 和remove_role()功能一样
$wp_roles->remove_role( $role );

同样,你也可以使用这种方法得到一个角色:

global $wp_roles;

//通过角色名称得到一个角色,和get_role()功能一样
$wp_roles->get_role( $role );

您还可以得到一个可用角色列表,含有角色的名称和角色的显示名称。当你想为用户提供一个接口,改变权限分配,这是非常有用的。

global $wp_roles;

//得到一个值列表包括 $role_name => $display_name
$roles = $wp_roles->get_names();

最后,您可以使用$wp_roles添加和删除权限,此对象几乎包括所有的角色和权限操作。

global $wp_roles;

//为角色$role添加权限$cap
$wp_roles->add_cap( $role, $cap );

//为角色$role删除权限$cap
$wp_roles->remove_cap( $role, $cap );

//例子
$wp_roles->add_cap( 'administrator', 'manage_galleries' );
$wp_roles->remove_cap( 'subscriber', 'view_galleries' );

WP_Role类

这是一个非常简单的类。它的功能就是添加和删除权限。

//得到角色对象
$role_object = get_role( $role_name );

//为角色对象添加权限$cap 
$role_object->add_cap( $capability_name );

//为角色对象删除权限$cap
$role_object->remove_cap( $capability_name );

WP_User类

这个类可以让你管理每个用户的角色和权限,这意味着你可以为一个特定的用户分配多个角色,或者为当前用户添加特定的权限,不论他目前是什么角色。

首先,你需要获取用户对象来操纵它的角色和权限:

//通过用户ID得到用户对象
$user = new WP_User( $id );

//或者通过用户名
$user = new WP_User( null, $name );

正如你所看到的,通过用户ID或用户名,你可以得到一个用户对象。对于第二种方法,第一个参数必须是空的(无论是null或是空字符串)。例子:

//通过ID得到管理员对象
$admin = new WP_User( 1 );

//通过用户名得到管理员对象
$admin = new WP_User( null, 'admin' );

一旦你得到用户对象,你可以为这个用户的添加另一个角色,而无需修改他目前的角色(这意味着用户可以有很多你想想为他分配的角色,):

$user->add_role( $role_name );

或者,您可以使用remove_role(),来为该用户删除某个角色:

$user->remove_role( $role_name );

您还可以为该用户设置一个角色,这意味着该用户将被删除当前所有的角色,并分配一个新的角色:

$user->set_role( $role_name );

对于操作权限,你可以有很多的方法来做你想做的做各种事情:

//检查该用户是否具有某种权限或角色名称
if ( $user->has_cap( $cap_name ) ) {
    //做一些事
}

//为用户添加权限
$user->add_cap( $cap_name );

//为用户删除权限
$user->remove_cap( $cap_name );

//删除用户所有权限
$user->remove_all_caps();

总结

以上就是所有有关角色和权限的知识。您可能不需要掌握所有这一切,但绝对有必要了解的是WordPress有一个强大的用户和角色管理系统,您可以随时使用它们来创建复杂的项目。此文章已经讲解了所有关于wordpress角色与权限的知识,但在未来的教程中,我将向您展示如何使用这方面的知识,为你的WordPress个人资料页面建立一个“客户登录”区域。

如果您有任何意见建议或问题,请在下面留言!

后记

通过此文我们可以了解到wordpress的用户系统,角色与权限功能非常强大。所以wordpress不再局限于是一款blog程序,,而是一款非常强大的cms建站程序(按wordpress的话说是一款信息发布平台程序)。我们完全可以使用wordpress角色与权限系统来构建任何复杂的网站,项目,像社交平台,论坛,公司网站,协作网站,各种网站(bbPress,BuddyPress已经做到了这一点。可以说wordpress当然无愧为世界第一cms,也是一款更像框架的建站程序。wordpress就是用插件这一办法构建这一富有无穷创造力的cms。

夸奖到此结束,开始吐槽。看过wordpress源码你才会明白那句话:看美女一定不能看背影,否则正脸会吓死你。用在wordpress身上就是:看wordpress不能只看表面,否则源码会吓死你。我勒个去,wordpress源码完全是一坨屎,根本没有面对像思想,根本没有mvc设计,逻辑部分和html代码混在一起,那一坨一坨完全让人呕心。诶,无语………

看看日历,寒假就这样过去了。我都干了什么?1.玩2.抄作业3.翻译piwik(强烈呼吁有piwik爱好者大家一起来翻译,我翻译到吐)4.看网易公开课5.折腾出个人主页+blog6.认识了鱼叔7.投稿给鱼叔成功8.玩9.还是玩10.还是还是玩(看来我开学考试是要废了!(┬_┬))

寒假折腾就到此为止,以此文作为完美句号。哈哈哈哈哈哈!!!!!

让wordpress真正支持jQuery插件lazyload

看到很多人在网上说jquery lazyload插件没效果,看了下插件主页说要把img地址写入data-original属性,loading图片地址写入URL属性就能实现真正lazyload。
wordpress这么强大,支持这个功能还不是小菜一碟。只要挂一个过滤器,用正则表达式重组一下img标签就行了。于是花了点时间写了个貌似很强大代码。你可以先看下示例。然后不多说,上代码。

1
2
3
4
5
6
7
add_filter ('the_content''lazyload');
function lazyload($content) {
if(!is_feed() && !is_robots()) {
$content=preg_replace('/<img(.+)src=['"]([^'"]+)['"](.*)>/i',"<img$1data-original="$2" src="http://jimpunk.net/Loading/wp-content/uploads/loading1.gif"$3>n<noscript>$0</noscript>",$content);
}
return $content;
}

把这段代码扔到你的fuctions.php中,再把http://jimpunk.net/Loading/wp-content/uploads/loading1.gif这个图片地址换成你要的loading图片地址。再按这篇潜行者m的文章配置下站点的jquery就搞定了。

神马自定义的img的其他属性能在转换后完整保留,支持本站外站图片,在feed中和搜索引擎抓取时不转换img标签(因为feed中肯定不会载入你的lazyload.js,如果还转换feed用户就会看不到照片。同理在搜索引擎抓取时还转换图片肯定抓取不到。),用<noscript></noscript>让禁止js的用户也能看到图片,优雅降级,平稳退步。总之一句话

赞哟