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. underone Feb 9th, 2010 @ 13:28 | #26

    找你有事,mail联系我下

  2. 吖Bee Feb 10th, 2010 @ 10:53 | #27

    我换域名啦! iqbee.me~~~有空改一下~thanks

  3. 达子 Feb 12th, 2010 @ 11:59 | #28

    呆子呆子…!哈哈。.

  4. tooba Feb 12th, 2010 @ 23:21 | #29

    看到技术的文章,总是让我很惭愧啊。
    先问声 过年好吧

  5. dot Feb 22nd, 2010 @ 01:05 | #30

    留一记号改天研究

  6. bolo Feb 24th, 2010 @ 12:44 | #31

    在调用上的区别就是新方法把读取到的设置为全局变量,在不同的模板里就不需要重复读取了吧?

  7. 莫矮水北 Mar 23rd, 2010 @ 18:09 | #32

    学医出身,不得不说,哥们你太牛逼了….

  8. sweetnest Apr 1st, 2010 @ 10:34 | #33

    留爪!

  9. 盈盈 Apr 1st, 2010 @ 10:44 | #34

    挺不错的

  10. 皓辰 Apr 5th, 2010 @ 15:34 | #35

    好迷茫……

  11. 乐扣乐扣 Apr 9th, 2010 @ 21:03 | #36

    不知道干什么用。。 :???:

  12. heroicYang Apr 12th, 2010 @ 21:54 | #37

    高手的站点,发现博主不添加链接了,所以留个名,订阅一下。小弟才开博,所以需要像大家学习。

  13. jializ Apr 14th, 2010 @ 13:30 | #38

    技术强人 :smile:

  14. 随风飘 Apr 15th, 2010 @ 14:06 | #39

    能交个友吗??我很喜欢这博客!

  15. 涛涛博客 Apr 17th, 2010 @ 05:50 | #40

    楼主厉害啊,正在用你的飞信插件呢!!感谢啊!

  16. YY Apr 18th, 2010 @ 21:08 | #41

    为什么打开有的文章后,在页面左上角会出现类似这样的文字连接提示:“阅读全文——共183字” /> ”

  17. ShunYea Apr 19th, 2010 @ 09:33 | #42

    您好,使用了您的主题,非常喜欢,但是还看到你的代码高亮,请问您使用的是哪个插件?谢谢。

  18. hallo Apr 20th, 2010 @ 17:23 | #43

    我也不知道干什么用

  19. 永恒之塔基地 Apr 21st, 2010 @ 05:02 | #44

    找好久了,今天终于有收获
    收藏学习~

  20. Aklis Apr 30th, 2010 @ 18:21 | #45

    吾是看中了你的Philna主题 通过下面的链接而来的

    因本人刚开始学PHP 进来一看 懵了

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.