用最古老的 WordPress 系统,写最现代的 PHP 代码!
我们知道 WordPress 的函数在失败的时候,是不会抛出异常的,因为 WordPress 在 PHP 4 的时候就创建了,那时候 PHP 语法结构还没有 try
/catch
异常处理机制。
WP_Error 错误处理机制
取而代之,WordPress 在失败的时候,返回返回一个WP_Error对象,比如插入文章的函数 wp_insert_post
,如果文章标题,内容摘要都为空的时候,就会插入失败,会返回 WP_Error
对象。
WP_Error
对象错误对象和异常很类似,也有一个错误代码和错误信息,比如上面的错误,返回 WP_Error
对象的错误代码就是 empty_content
,错误信息是:内容,标题和摘要为空。
WordPress 还提供了 is_wp_error
函数,用于判断接受到数据是不是 WP_Error
对象,这样我们在写代码的时候,就需要自己判断返回值是不是 WP_Error
对象,然后进行额外处理,举个例子,WPJAM Basic 的快速复制扩展功能的代码:
function wpjam_duplicate_post($post_id){
// 获取旧文章信息,并插入新文章
$post_arr = get_post($post_id, ARRAY_A);
$new_post_id = wp_inssert_post($post_arr, $wp_error=true);
if(is_wp_error($new_post_id)){ // 如果失败,返回错误
return $new_post_id;
}
// 获取旧文章的分类信息,并将同样的分类信息设置到新的文章中
foreach(get_object_taxonomies($post_arr['post_type']) as $taxonomy){
$terms = wp_get_object_terms($post_id, $taxonomy, ['fields' => 'ids']);
$result = wp_set_object_terms($new_post_id, $terms, $taxonomy);
if(is_wp_error($result)){ // 如果失败,返回错误
return $result;
}
}
// 假如还有其他操作
$result = other_post_function($new_post_id, $args);
if(is_wp_error($result)){ // 如果失败,返回错误
return $result;
}
return $new_post_id; // 最后才返回复制成功的文章 ID
}
上面的代码我为了方便演示,做了一些简化,留下大致的骨架,可以看出快速复制文章有三个过程,注释里面已经写的非常清楚,下面简单说一下
- 获取旧文章信息,并插入新文章,如果
WP_Error
对象,则直接返回。 - 获取旧文章的分类信息,并将同样的分类信息设置到新的文章中,同样碰到
WP_Error
对象,则直接返回 - 最后假设还有其他操作,同样也要处理错误。
这样的代码给人感觉就是满屏的错误处理,非常难受。
使用 Try / Catch 异常处理机制
有没有办法优化我们的代码呢?可以把 WP_Error
对象转换成 PHP 异常继承类的对象,然后使用现代 PHP 的 Try / Catch 异常处理机制来优化。
首先创建用于处理 WP_Error
对象的异常处理类:
class WPJAM_Exception extends Exception{
private $wp_error = null;
public function __construct($message, $code=0, Throwable $previous=null){
if(is_wp_error($message)){
$this->wp_error = $message;
$message = $this->wp_error->get_error_message();
$code = $this->wp_error->get_error_code();
}else{
$this->wp_error = new WP_Error($code, $message);
}
parent::__construct($message, 0, $previous);
}
public function get_wp_error(){
return $this->wp_error;
}
}
创建一个高阶函数 wpjam_try
,自动将 WP_Error
对象转换成异常:
function wpjam_try($callback, ...$args){
try{
$result = call_user_func_array($callback, $args);
if(is_wp_error($result)){
throw new WPJAM_Exception($result);
}
return $result;
}catch(Exception $e){
throw $e;
}
}
最后我们就可以使用 wpjam_try
对上面复制文章这段代码进行改造了
function wpjam_duplicate_post($post_id){
try{
// 获取旧文章信息,并插入新文章
$post_arr = get_post($post_id, ARRAY_A);
$new_post_id = wpjam_try('wp_inssert_post', $post_arr, $wp_error=true);
// 获取旧文章的分类信息,并将同样的分类信息设置到新的文章中
foreach(get_object_taxonomies($post_arr['post_type']) as $taxonomy){
$terms = wp_get_object_terms($post_id, $taxonomy, ['fields' => 'ids']);
$result = wpjam_try('wp_set_object_terms', $new_post_id, $terms, $taxonomy);
}
// 假如还有其他操作
$result = wpjam_try('other_post_function', $new_post_id, $args);
return $new_post_id; // 最后才返回复制成功的文章 ID
}catch(WPJAM_Exception $e){
if($exception){
throw $e;
}else{
return $e->get_wp_error();
}
}
}
改造的过程分成三步:
- 把会返回
WP_Error
对象的函数,通过wpjam_try
调用。 - 去掉所有
is_wp_error
的判断,因为wpjam_try
会抛出异常。 - 将所有代码放到
try/catch
的结构中,最后只需要捕捉异常,再将异常转换成WP_Error
对象即可。
这样就可以在 WordPress 写代码的时候,避免满屏幕的错误处理,最后返回还是 WP_Error
对象,保证了对原来逻辑的兼容。
相关文章
- 看看php内存管理机制与垃圾回收机制
- PHP使用file_get_contents打开URL获得网页内容及函数超时控制的用法
- WordPress主题制作(七):制作基础模板Index.php
- Linux快速安装PHP的指南(linux一键安装php)
- Linux系统下安装PHP的指南(linux怎么安装php)
- 实现使用PHP实现的Redis乐观锁(redis乐观锁php)
- 强大的PHP环境,支持Redis全面提升效能(php支持redis)
- 深入探索:Linux 系统下 PHP 的适用与优势(Linux中php)
- PHP实现在Linux系统中进行文件操作(php写linux文件)
- PHP连接MySQL指南(php连mysql)
- PHP Redis实时监控系统的应用(php redis 监控)
- PHP连接MSSQL实现注册功能(php注册写入mssql)
- 据使用PHP和MSSQL技术记录丰富的数据信息(php mssql记录数)
- 基于PHP和MSSQL 的网站用户注册系统(php mssql 注册)
- 解决MySQL与PHP配置问题的实战技巧(mysql php 配置)
- 记录PHP之MySQL踩坑:如何防止重复记录(php mysql 重复)
- 一个很不错的PHP翻页类
- 创建数据库php代码用PHP写出自己的BLOG系统
- PHP下利用header()函数设置浏览器缓存的代码
- PHP和Mysqlweb应用开发核心技术第1部分Php基础-1开始了解php
- php教程插件机制在PHP中实现方案
- 利用PHP扩展vld查看PHPopcode操作步骤
- 深入php常用函数的使用汇总
- php实例分享之二维数组排序