Answers:
我认为不可能在这里给出确切的答案,因为这样的选择是个人喜好。
考虑以下是我的方法,我不认为这是正确的方法。
我可以肯定地说的是,您应该避免第三个选择:
只需返回null / false
在不同方面这是不好的:
if (! is_null($thing))...
)强制执行条件检查,使代码更难阅读我经常使用OOP编写插件代码,而发生错误时,我的对象方法经常抛出异常。
这样做,我:
但是,在WordPress插件中引发异常意味着没有任何东西可以捕获它们,最终导致致命错误,这绝对是不希望的,特别是在生产中。
为避免此问题,我通常在主插件文件中有一个“主例程”,将其包装在try
/ catch
块中。这使我有机会在生产中捕获异常并防止致命错误。
一个类的粗略示例:
# myplugin/src/Foo.php
namespace MyPlugin;
class Foo {
/**
* @return bool
*/
public function doSomething() {
if ( ! get_option('my_plugin_everything_ok') ) {
throw new SomethingWentWrongException('Something went wrong.');
}
// stuff here...
return true;
}
}
并从主插件文件中使用它:
# myplugin/main-plugin-file.php
namespace MyPlugin;
function initialize() {
try {
$foo = new Foo();
$foo->doSomething();
} catch(SomethingWentWrongException $e) {
// on debug is better to notice when bad things happen
if (defined('WP_DEBUG') && WP_DEBUG) {
throw $e;
}
// on production just fire an action, making exception accessible e.g. for logging
do_action('my_plugin_error_shit_happened', $e);
}
}
add_action('wp_loaded', 'MyPlugin\\initialize');
当然,在现实世界中,您可能会抛出并捕获不同种类的异常,并根据异常的行为有所不同,但这应该为您提供指导。
我经常使用的另一个选项(您没有提到)是返回包含标志的对象,以验证是否没有错误发生,但保持返回类型的一致性。
这是一个类似这样的对象的粗略示例:
namespace MyPlugin;
class Options {
private $options = [];
private $ok = false;
public function __construct($key)
{
$options = is_string($key) ? get_option($key) : false;
if (is_array($options) && $options) {
$this->options = $options;
$this->ok = true;
}
}
public function isOk()
{
return $this->ok;
}
}
现在,您可以在插件的任何位置执行以下操作:
/**
* @return MyPlugin\Options
*/
function my_plugin_get_options() {
return new MyPlugin\Options('my_plugin_options');
}
$options = my_plugin_get_options();
if ($options->isOk()) {
// do stuff
}
请注意,my_plugin_get_options()
上面的方法总是返回Options
类的实例,这样您就可以始终传递返回值,甚至可以将其注入使用type-hint的其他对象,现在担心类型不同。
如果函数已返回null
/ false
发生错误,则在传递该函数之前,您必须检查返回的值是否有效。
同时,您可以清楚地了解选项实例是否存在问题。
如果错误是可以使用默认值或任何合适的方式容易恢复的东西,那么这是一个很好的解决方案。