用最古老的 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 对象,保证了对原来逻辑的兼容。

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至81118366@qq.com举报,一经查实,本站将立刻删除。发布者:简知小编,转载请注明出处:https://www.jianzixun.com/66192.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫

相关推荐

软文友链广告合作联系站长qq81118366