Вопрос или проблема
Я сталкиваюсь с странной проблемой, которую пока не смог решить.
Я вызываю скрипт .php через cronjob (Debian/GNU Linux).
Чтобы воспользоваться функциональностью WordPress, я добавил:
define('WP_USE_THEMES', false);
require( '/full/path/to/wp-blog-header.php' );
Теперь запросы к базе данных и стандартная функциональность WordPress работают нормально, но я также вызываю некоторые функции, предоставленные плагином (а именно Advanced Custom Fields, однако проблема затрагивает и другие плагины, как я протестировал), и возвращается следующая ошибка PHP:
PHP Fatal error: Call to undefined function update_field() in executed.php on line 24
Это говорит мне о том, что функция этого плагина не была подключена.
Так кажется, что require wp-blog-header.php не подключает функциональность плагина (что оно и делало, когда я начал разрабатывать упомянутый скрипт, но теперь, когда я протестировал его, возникла ошибка PHP).
Может быть, обновление WordPress до 3.5 что-то изменило? Или кто-нибудь из вас может дать мне совет, почему возникает эта проблема?
Спасибо!
Правка
Я провел дополнительные тесты. Проблема, похоже, в том, что я выполняю PHP в оболочке, используя следующую команду:
/usr/bin/php5 -q -d memory_limit=256M /path/to/executed.php
Таким образом, определенные переменные не установлены, такие как $_SERVER['REQUEST_METHOD']
WordPress, следовательно, выдаст мне предупреждения в режиме отладки. Поэтому я определил переменную DOCUMENT_ROOT
и вручную включил мой function.php (который также не загружался):
$_SERVER['DOCUMENT_ROOT'] = '/full/path/to/my/document/root/';
define('WP_USE_THEMES', false);
require( '/full/path/to/wp-blog-header.php' );
require_once( '/full/path/to/themes/mytheme/functions.php' );
Теперь это работает. Но мне кажется, что это лишь нездоровый обходной путь…
Вы, вероятно, вызываете функцию прежде, чем она определена – почему бы не подключиться к ней?
Что-то вроде:
function someFunction() {
require( '/full/path/to/wp-blog-header.php' );
}
add_action('some_hook', 'someFunction');
Примечание: Вы можете попробовать хуки plugins_loaded
.
Я не уверен, сработает ли это решение, но попробуйте require_once
основной PHP файл плагина в ваш PHP файл cron-job или вы просто можете заново создать функциональность этого плагина в своем собственном PHP, чтобы выполнить задачи этого плагина.
WordPress предназначен для работы с веб-сервера, а не из командной строки. Хотя не очевидно, какая зависимость могла вызвать такое поведение, эти зависимости существуют, и если вы хотите “запустить” WordPress из командной строки, вам нужно смоделировать среду веб-сервера, что, вероятно, делает wp-cli, и интеграция с ним могла бы помочь вам лучше, чем пытаться вызвать WordPress самостоятельно.
Как насчет того, чтобы использовать ваш cronjob для вызова wp-cron.php WordPress?
WordPress использует квази-cron систему, которая позволяет вам планировать определенные функции, которые выполняются при доступе к веб-сайту после запланированного времени. Вы можете отключить эту функциональность “Выполнять cronjob при обращении к сайту” и вместо этого запустить реальный cronjob для вызова wp-cron.php каждые 15 минут.
Затем вы сможете подключить функцию, которая должна выполняться, в планирование cron WordPress, что означает, что вам следует иметь возможность использовать все функции WordPress, включая функции плагинов в этом действии.
Шаг 1: отключите WP-Cron.
Откройте файл wp-config.php.
Перейдите в конец настроек базы данных в wp-config.php (примерно на 37 строке). Добавьте код: define(‘DISABLE_WP_CRON’, ‘true’);
Шаг 2: добавьте “настоящую” задачу cron для вызова файла wp-cron.php так часто, как вам нужно.
Шаг 3: напишите плагин. В этом плагине опишите функциональность, которую вам нужно запустить с помощью cron, в функции.
function do_awesome_cron_stuff(){
//выполняйте все удивительные вещи
}
Шаг 4: подключите вашу функцию к WordPress Cron
Сначала вы регистрируете запуск планирования при активации плагина:
register_activation_hook(__FILE__, 'awesome_cron_scheduling_activation');
function awesome_cron_scheduling_activation() {
if (! wp_next_scheduled ( 'my_awesome_cron' )) {
wp_schedule_event(time(), 'hourly', 'my_awesome_cron');
//каждый час (очевидно), есть и другие ключевые слова для использования для временных интервалов, вы можете найти их здесь:
//https://codex.wordpress.org/Function_Reference/wp_schedule_event
}
}
Для информации, вы не планируете функцию напрямую, а действие (здесь: my_awesome_cron). Теперь нам нужно подключить нашу функцию к этому действию
add_action('my_awesome_cron', 'do_awesome_cron_stuff');
Для последней части: деактивируйте Cron при деактивации плагина
register_deactivation_hook(__FILE__, 'awesome_cron_scheduling_deactivation');
function awesome_cron_scheduling_deactivation() {
wp_clear_scheduled_hook('my_awesome_cron');
}
Вот и всё. Ваш cron будет работать и работать, и работать, и работать, пока вы не отключите плагин 😉 .
Счастливого кодирования!
Ответ или решение
Если вам не удается использовать функциональность плагинов в вашем внешнем PHP-скрипте, вызванном через cron на Debian/GNU Linux, это можно объяснить несколькими важными аспектами работы WordPress и его экосистемы. Рассмотрим вашу проблему подробнее и предложим решение.
Проблема
Вы используете следующий код для включения функциональности WordPress в вашем скрипте:
define('WP_USE_THEMES', false);
require('/full/path/to/wp-blog-header.php');
Сначала это работало, и вы могли выполнять запросы к базе данных и использовать стандартные функции WordPress. Однако при попытке вызвать функции плагинов, таких как Advanced Custom Fields, вы получили ошибку:
PHP Fatal error: Call to undefined function update_field() in executed.php on line 24
Эта ошибка указывает на то, что функциональность плагина не загружена, и, следовательно, возникающая проблема не позволяет получить доступ к его функциям.
Влияние обновления WordPress 3.5
Важно отметить, что обновления WordPress могут добавить или изменить зависимости, которые влияют на загрузку плагинов и их функций. В вашем случае возможно, что вызов функций плагина происходит до их инициализации.
Причина проблемы: Среда выполнения
Использование CLI (интерфейс командной строки) для выполнения скриптов PHP создает среду, которая отличается от веб-сервера. Это может приводить к отсутствию некоторых переменных среды, таких как $_SERVER['REQUEST_METHOD']
, которые важны для правильной работы WordPress и некоторых его компонентов.
Чтобы устранить эту проблему, вы определили переменную DOCUMENT_ROOT
и вручную подключили файл functions.php
вашей темы:
$_SERVER['DOCUMENT_ROOT'] = '/full/path/to/my/document/root/';
define('WP_USE_THEMES', false);
require('/full/path/to/wp-blog-header.php');
require_once('/full/path/to/themes/mytheme/functions.php');
Хотя это решение работает, оно не является оптимальным, так как требует обширных манипуляций с установкой переменных.
Рекомендации по улучшению
-
Использование WP-CLI:
Если ваша задача запускается через командную строку, рассмотрите использование WP-CLI. Это инструмент, разработанный специально для взаимодействия с WordPress из командной строки и который учитывает все зависимости и загружает платформу должным образом. -
WP-Cron:
Другим вариантом является использование встроенной в WordPress системы WP-Cron. Вы можете настроить свой cron для вызоваwp-cron.php
вместо выполнения скрипта напрямую.-
Отключите WP-Cron:
В вашем файлеwp-config.php
добавьте:define('DISABLE_WP_CRON', true);
-
Создайте реальный cron-задачу:
Настройте систему cron для вызоваwp-cron.php
через определенные промежутки времени, что обеспечит выполнение задач, запланированных в WordPress. -
Создание собственного плагина:
Напишите свой плагин, где создайте функции для выполнения необходимых действий, добавляя их в WP-Cron:function do_awesome_cron_stuff() { // Ваша логика здесь } add_action('my_awesome_cron', 'do_awesome_cron_stuff');
-
-
Подключение нужных функций:
Убедитесь, что функции плагина вызываются после его полной загрузки. Вы можете использовать хуки, такие какplugins_loaded
для этого:add_action('plugins_loaded', 'your_function');
Заключение
Ваши действия по устранению проблемы были разумны, но для стабильной работы и легкости последующего обслуживания рекомендуется использовать стратегии, описанные выше. Использование WP-CLI и системного cron позволит более эффективно справляться с выполнением задач и уменьшит вероятность появления ошибок.
Если у вас есть дополнительные вопросы или вам нужна помощь, не стесняйтесь обращаться!