Home > Technology, WordPress > 数组重载在 WordPress 主题或插件设置中的应用

数组重载在 WordPress 主题或插件设置中的应用

现在大部分的 WordPress 主题和插件都有后台设置页面, 为主题或插件添加自定义的一些功能. 这些设置会将被保存到数据库中. 然后在主题或插件中使用它们. 通常人们都是用 global 这样的关键字将他们的设置声明为一个全局变量. 或者在各个页面上都使用 get_options 这样的函数去取得设置. 然而我觉得那样处理并不好. 这里我写了个自认为较好的办法. 欢迎大家批评指正.

该方法用到了数组重载. 数组重载是将对象作为数组使用的一个过程. 为了实现这个你需要用到 ArrayAccess 接口.

以下是 ArrayAccess 接口代码清单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
interface ArrayAccess  {
 
	/**
	 * @param offset 确定给定偏移量是否存在于数组中
	 */
	abstract public function offsetExists ($offset) {}
 
	/**
	 * @param offset 取得给定偏移量上的数据
	 */
	abstract public function offsetGet ($offset) {}
 
	/**
	 * @param offset 设置或替换给定偏移量上的数据
	 * @param value 要设置或替换的数据
	 */
	abstract public function offsetSet ($offset, $value) {}
 
	/**
	 * @param offset 置空给定偏移量上的数据
	 */
	abstract public function offsetUnset ($offset) {}
 
}

具体的实现办法如如下代码所示: 在这个类中我们用到了单件(例)模式.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
 * Get options
 *
 * @author yinheli
 *
 */
class PhilNaGetOpt implements ArrayAccess {
 
	/**
	 * 所有设置
	 *
	 * @var array
	 */
	private $philnaOpt = array();
 
	/**
	 * 获取设置对象
	 *
	 * @var PhilNaGetOpt
	 */
	private static $_instance;
 
	/**
	 * 从数据库中取得设置
	 *
	 * @return null
	 */
	private function __construct() {
		if ($r = get_option('philnaopt')) {
			$this->philnaOpt = $r;
			unset($r);
		}
	}
 
	/**
	 * 不许克隆
	 */
	private function __clone() {}
 
	/**
	 * 获取 PhilNaGetOpt 单一实例
	 *
	 * @return PhilNaGetOpt
	 */
	public static function getInstance() {
		if (!(self::$_instance instanceof self)) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}
 
	/**
	 * 重新取得设置
	 *
	 * @return null
	 */
	public function reGet() {
		$this->__construct();
	}
 
	/**
	 * 给定的偏移量是否存在?
	 *
	 * @return bool
	 */
	public function offsetExists($key) {
		if (array_key_exists($key, $this->philnaOpt)) {
			return true;
		} else {
			return false;
		}
	}
 
	/**
	 * 返回给定偏移量上的数据
	 *
	 * @return null|mix
	 */
	public function offsetGet($key){
		if (array_key_exists($key, $this->philnaOpt)) {
			if (is_string($this->philnaOpt[$key])) {
				return stripslashes($this->philnaOpt[$key]);
			} else {
				return $this->philnaOpt[$key];
			}
		} else {
			return null;
		}
	}
 
	/**
	 * 设置给定偏移量上的数据
	 *
	 * @return bool|mix
	 */
	public function offsetSet($key, $val) {
		if (array_key_exists($key, $this->philnaOpt)) {
			$this->philnaOpt[$key] = $val;
			return $val;
		} else {
			return false;
		}
	}
 
	/**
	 * 置空给定偏移量上的数据
	 *
	 * @return bool
	 */
	public function offsetUnset($key) {
		if (array_key_exists($key, $this->philnaOpt)) {
			unset($this->philnaOpt[$key]);
			return true;
		} else {
			return false;
		}
	}
}

接下来我们我们只需要在代码的最开始时实例化刚刚的那个读取设置的类. 并将它存储到全局数组里. 例如在主题中. 我们可以在 functions.php 文件中首先做这样的事情.

1
$GLOBALS['philnaopt'] = PhilNaGetOpt::getInstance();

然后我们就不用理会其他的情况, 只需要在你需要的地方调用那个设置对象. 就像是使用数组一样. 而不用不考虑它是否存在着你需要的那个键值. 很多情况下它简化了我们的一些条件判断.

比如我们要判断是否需要显示首页通知

一般情况下. 我们的判断是:

1
2
3
4
5
6
7
8
9
// 取得设置
$opt = get_option('philnaopt');
 
// 判断是否有通知要显示
if (isset($opt['notice']) && $opt['notice']) {
	if (isset($opt['notice_content']) && $opt['notice_content']) {
		echo $opt['notice_content'];
	}
}

而是用新的办法后是这样的:

1
2
3
4
// 判断并显示通知
if ($GLOBALS['philnaopt']['notice'] && $GLOBALS['philnaopt']['notice_content']) {
	echo $GLOBALS['philnaopt']['notice_content'];
}

说明:
当然在很多人的代码中我经常看不到 isset() 这样的函数. 事实上, 如果在开启报告全部错误的情况下. 我们在判断一个数组中的值. 我们首先要判断是否存在相应的键值. 否则 PHP 会产生一个 NOTICE 级别的错误. 加isset()这样的判断在我看来是一种比较规范的写法.

使用数组重载来调用设置有一个最大好处是简化判断. 当然更主要的是它规范了代码, 避免了使用 global 这样不优雅的代码.

注意: 这个 PHP 特性只能使用在 PHP 版本 5.1.0 及其以上. 如果你使用古老的版本. 那只能作罢了.

  1. welee Jan 22nd, 2010 @ 15:34 | #1

    这个太深奥了,我一般是用 get_options 来处理,而且是参考 mg12 的 iNove 主题得来的… :cry:

  2. edikud Jan 22nd, 2010 @ 19:05 | #2

    同是… ;-)

  3. ﹎sκyˊ☆ Jan 23rd, 2010 @ 10:09 | #3

    :cry: 想把这主题转到Typecho 可包里文件过于繁多 搞不了…..

  4. 吖Bee Jan 23rd, 2010 @ 16:31 | #4

    yinheil的果如是比较深奥…

  5. 设&计是空 Jan 25th, 2010 @ 13:48 | #5

    博主的top效果很另类啊,我忍不住top了N次。

  6. 设&计是空 Jan 25th, 2010 @ 13:49 | #6

    原来只有首页有那个效果啊~

  7. 忘记月亮 Jan 26th, 2010 @ 16:50 | #7

    学习了

  8. yinheli Jan 29th, 2010 @ 13:42 | #8

    @welee , @edikud
    我只是想偷懒. 不想每个都去验证一下数组是否存在那个键值.

    @﹎sκyˊ☆
    哈. 用 firebug 把外观搞过去得了. Typecho 的代码很规范呀. 有空我也研究一下. 就是好像用的人太少了.

    @吖Bee
    可能是我讲的不过通俗吧.

  9. ﹎sκyˊ☆ Jan 29th, 2010 @ 13:57 | #9

    @yinheli
    过会看下吧 转吧 Typecho在于推广!

  10. 吖Bee Jan 29th, 2010 @ 18:12 | #10

    我也想试试Typecho…更简洁

  11. 球犯 Jan 29th, 2010 @ 18:42 | #11

    你好,很喜欢你的博客主题,请问下首页显摘要怎么实现呢?谢谢 ;-)

  12. yinheli Jan 30th, 2010 @ 14:32 | #12

    @球犯
    用 WP 原生的 more tag 或者用插件

  13. Terry Jan 30th, 2010 @ 16:09 | #13

    你好,用了你的philna2主题,我换了个表情,但是无法插入到评论框里面,还有个问题就是,侧边栏我不想显示自己的评论,该怎么修改~~~谢谢~~~ :lol:

  14. yinheli Jan 31st, 2010 @ 09:34 | #14

    @Terry
    应该是你自己写的 js 造成的问题.

  15. Terry Jan 31st, 2010 @ 12:19 | #15

    @yinheli
    侧边栏已经解决了,表情还是有点问题~~~

  16. yinheli Jan 31st, 2010 @ 12:58 | #16

    @Terry
    你检查一下. 看看是不是页脚的 innerHTML 造成的.

    看到问题了! 你用了 Sweet Titles 的 js . 它将表情链接里面的 title属性 去掉了取而代之为一个 tip 属性. 而插件入表情是通过 title 内容实现的. 现在没有了. 自然无法插入.

  17. Terry Jan 31st, 2010 @ 13:02 | #17

    @yinheli
    因为我在用phina2之前,是装的custom smiles插件,后来发现主题自带了,就把插件卸载了,是不是comment ID的问题啊~~~

  18. 球犯 Feb 2nd, 2010 @ 22:53 | #18

    你好!想请问下PhilNa2 主题的一个问题..
    就是关于评论 我博客的注册用户 每次需要登陆才能发表评论 不然就显示不能用该用户名或邮箱提交..我想请问下这样修改一下可以可以解决这问题呢 他们每次都要登陆评论好麻烦 额 ..谢谢呵

  19. yinheli Feb 2nd, 2010 @ 23:05 | #19

    @球犯
    对于 3.1.0 版本修改 app 目录下的 comment.php 最后一行. 将 add_action 注释掉. 即不要挂载 philnaCheckEmailAndName 这个函数.

    要求管理人员登录再评论是为了防止有人冒用他人身份所做的措施. 如果觉得多余请采取上述办法去掉.

  20. 球犯 Feb 2nd, 2010 @ 23:49 | #20

    @yinheli
    抱歉..我对这方面一点也不懂..能直接删除最后一行吗 :?:

  21. Terry Feb 4th, 2010 @ 00:27 | #21

    @yinheli
    那只有禁用sweet title才行么?

  22. 世纪之光 Feb 4th, 2010 @ 01:16 | #22

    用上你这款主题,发现评论分页导航有问题,随便向上翻一页不是加载不出评论就是加载到莫名其妙不是这篇文章的评论。

  23. Feb 5th, 2010 @ 11:00 | #23

    哇塞。。完全看不懂~~~~那个评论框右边的俺已经在这里留言多少次了这个功能是怎么实现的啊?~~~~~~~ :shock: :shock:

  24. Young Feb 5th, 2010 @ 15:36 | #24

    看不懂, 努力学习中…

  25. 吖Bee Feb 8th, 2010 @ 20:28 | #25

    希望Philna2能有镶嵌评论样式~~

Submitting Comment, Give me a second...
Comment pages 1 2

Leave a comment

Allowed tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">
Trackbacks & Pingbacks ( 0 )
  1. No trackbacks yet.