Я думаю, что здесь невозможно дать однозначный ответ, потому что такой выбор является личным предпочтением.
Считайте, что то, что следует, - это мой подход, и я не думаю, что он правильный .
Что я могу сказать наверняка, так это то, что вам следует избегать третьего варианта:
Просто верните ноль / ложь
Это плохо под другим аспектом:
- возвращаемое согласие типа
- затрудняет юнит-тестирование функций
- принудительная проверка типа return (
if (! is_null($thing))...
) затрудняет чтение кода
Я чаще, чем часто, использую ООП для кодирования плагинов, и мои методы объекта часто выдают исключение, когда что-то идет не так.
Делая это, я:
- выполнить возвращение типа соответствия
- сделать код простым для модульного тестирования
- не требуется условная проверка возвращаемого типа
Однако, бросающая исключения в плагине WordPress, означает , что ничего не будет ловить их, в конечном итоге к фатальной ошибке, абсолютно не желательно, EXPECIALLY в производстве.
Чтобы избежать этой проблемы, у меня обычно есть «основная подпрограмма», расположенная в основном файле плагина, которую я заключаю в try
/ catch
block. Это дает мне возможность отловить исключение на производстве и предотвратить фатальную ошибку.
Грубый пример класса:
# 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
класса, таким образом, вы всегда можете передать возвращаемое значение и даже внедрить его в другие объекты, которые используют подсказку типа, теперь беспокоится о том, что тип отличается.
Если функция вернула null
/ false
в случае ошибки, перед ее передачей вам пришлось проверить, верно ли возвращаемое значение.
В то же время у вас есть четкий способ понять, что с опцией экземпляра что-то не так.
Это хорошее решение, если ошибку легко исправить, используя значения по умолчанию или что-то еще.