Почему при вызове скрипта с сайта возникает ошибка PHP Fatal error: Uncaught Error: Call to undefined function WP_CLI\Utils\check_proc_available()?

У меня возникает проблема с одним из плагинов для WordPress. В частности, у меня есть следующий код:

```php
\WP_CLI::runcommand("db export $path/{$this->backup_filename}.sql --tables={$this->wpdb->prefix}table --skip-comments=true --no-create-info=true");
```

Этот метод вызывается в классе, который использует пространство имен, и автозагрузка настроена в соответствии с конфигурацией в файле `composer.json`:

```json
"autoload": {
    "psr-4": {
        "MYCLASS\\": "classes"
    }
}
```

Когда я пытаюсь вызвать данный метод через GET-запрос из админки, возникает ошибка:

```
PHP Fatal error:  Uncaught Error: Call to undefined function WP_CLI\Utils\check_proc_available() in ..../wp-content/mu-plugins/my-plugin/vendor/wp-cli/wp-cli/php/class-wp-cli.php:1316
```

При этом, если я вызываю тот же метод через `wp-cli`, он работает корректно. Если заглянуть внутрь `class-wp-cli.php`, выполнение кода останавливается на строке:

```php
Utils\check_proc_available( 'launch option' );
```

Судя по всему, проблема связана с отсутствием пространства имен `\WP_CLI\` перед `Utils`. Это так? В нужном вызове должно быть так:

```php
\WP_CLI\Utils\check_proc_available( 'launch option' );
```
  • 13 ноября 2024 г. 10:13
Ответы на вопрос 2
Ошибка, с которой вы сталкиваетесь, связана с тем, что ваш код пытается запустить команду WP-CLI из контекста, который не поддерживает WP-CLI. Когда вы вызываете метод через админку WordPress, WP-CLI не инициализирован, и отсутствуют функции утилит WP-CLI, такие как `check_proc_available()`, что и вызывает данную ошибку.

### Решение проблемы

1. **Проверка среды выполнения**: Перед выполнением любой команды WP-CLI, вы должны убедиться, что вы действительно находитесь в контексте WP-CLI. Вы можете добавить проверку на наличие константы `WP_CLI`:

   ```php
   if ( defined( 'WP_CLI' ) && WP_CLI ) {
       \WP_CLI::runcommand("db export $path/{$this->backup_filename}.sql --tables={$this->wpdb->prefix}table --skip-comments=true --no-create-info=true");
   } else {
       // Обработка случая, когда WP-CLI не инициализирован
       // Например, можно вернуть ошибку или выполнить другой код
       error_log("WP-CLI is not available.");
   }
   ```

2. **Использование команды напрямую**: Если вы хотите выполнить экспорт базы данных из админки, возможно, имеет смысл использовать функции, которые предоставляются самим WordPress, вместо использования WP-CLI. Например, вы можете использовать функции `global $wpdb;` для работы с базой данных непосредственно внутри WordPress.

3. **Вызов через командную строку**: Если вам действительно необходимо использовать команды WP-CLI, вы можете рассмотреть вариант запуска вашего скрипта через оболочку (например, с помощью функции `exec()`), вызывая WP-CLI напрямую в неком другом окружении. Однако это потребует дополнительных мер предосторожности для безопасности и обработки ошибок.

### Исправление пространства имен

Что касается вашего вопроса:

> Судя по всему, проблема связана с отсутствием пространства имен `\WP_CLI\` перед `Utils`. Это так?

Не совсем. Проблема не в том, что вы не добавили `\` перед `Utils`, а в том, что функция `check_proc_available()` вообще не существует в контексте выполнения вашего кода. Если вы работаете не в контексте WP-CLI, то любые функции WP-CLI не будут доступны.

### Заключение

Рекомендуется реализовать логику, которая будет выполнять экспорт базы данных без использования команд WP-CLI, если вы вызываете код из админ-панели. Это обеспечит совместимость и избежит подобного рода ошибок.
WP_CLI используется для работы через консоль и либо не поддерживает веб запросы, либо поддерживаем их с ограничениями. 

Используйте в плагине выборку из БД без WP_CLI, например:
global $wpdb;
$data = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}table", ARRAY_A);
file_put_contents($path . '/' . $this->backup_filename . '.sql', serialize($data));
Похожие вопросы