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

PHPABC WordPress 2,056 次浏览 , 没有评论

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

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

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) {}
 
}

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

/**
 * 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 文件中首先做这样的事情.

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

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

比如我们要判断是否需要显示首页通知
一般情况下. 我们的判断是:

// 取得设置
$opt = get_option('philnaopt');
 
// 判断是否有通知要显示
if (isset($opt['notice']) && $opt['notice']) {
	if (isset($opt['notice_content']) && $opt['notice_content']) {
		echo $opt['notice_content'];
	}
}

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

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

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

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

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

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

Go