Как правильно подключать PHP файлы в плагинах WordPress
Моя проблема в том, что когда в основном файле плагина я подключаю PHP файл примерно так:
include(WP_PLUGIN_URL . '/wordpress-group-buying/ipn/paypal-ipn.php');
// или
include_once(WP_PLUGIN_URL . '/wordpress-group-buying/ipn/paypal-ipn.php');
// или
require(WP_PLUGIN_URL . '/wordpress-group-buying/ipn/paypal-ipn.php');
// или
require_once(WP_PLUGIN_URL . '/wordpress-group-buying/ipn/paypal-ipn.php');
и в этом файле у меня есть вызов функции WordPress:
add_action('hook', 'callback');
я получаю:
Fatal Error: Call to undefined function add_action()
И прежде чем вы скажете "используйте if(**function_exists**('add_action')){
", если я использую это, то просто не работает.
Вопросы:
- Какой правильный способ это сделать?
- В чем разница между
include
,include_once
,require
и когда что использовать?

Присоединяюсь к обсуждению с опозданием, но вот "WordPress"-способ: используйте plugin_dir_path( __FILE__ )
, например:
<?php
include( plugin_dir_path( __FILE__ ) . 'ipn/paypal-ipn.php');
?>
Обратите внимание, что функция возвращает путь с завершающим слешем.

Обратите внимание, что использование __FILE__
выводит путь относительно текущего файла, из которого вы его вызываете. Поэтому если ваш оператор include
выполняется из подкаталога внутри структуры файлов плагина, вы также получите этот подкаталог.

Я просмотрел несколько плагинов, которые создал ранее, чтобы изучить различные способы подключения дополнительных файлов внутри плагинов, и заметил, что можно использовать два основных метода, хотя, вероятно, их больше.
Определение директории плагина
Внутри вашего плагина можно использовать следующее определение для указания текущего местоположения плагина.
Пример кода:
define( 'PLUGIN_DIR', dirname(__FILE__).'/' );
Прямое подключение через include или require
Вы можете просто использовать функции: include, include_once, require или require_once внутри папки плагина, указывая путь к файлу, как в примере ниже. В этом примере файл из корневой директории плагина подключает другой файл из папки внутри директории плагина.
Пример кода:
include "classes/plugin-core.php";

В итоге я отказался от конструкций WordPress для подключения файлов и использую следующее:
require_once(dirname(__FILE__) . '/filename.php');
Не думаю, что это действительно решит вашу проблему, которая, судя по всему, связана с областью видимости, но это код, который я использую.
Что касается различий между include и require:
include выдаст предупреждение, если файл не найден
require вызовет фатальную ошибку, если файл не найден
include_once и require_once не будут подключать файл/код повторно, если он уже был подключён ранее (обратите внимание, что насколько я могу судить, это работает только для конкретного файла в конкретной директории).

Include
Функция include() включает и выполняет указанный файл.
Include Once
Функция include_once() включает и выполняет указанный файл во время выполнения скрипта. Это поведение аналогично функции include(), с единственной разницей: если код из файла уже был включен ранее, он не будет включен снова. Как следует из названия, файл будет включен только один раз.
Require
Функции require() и include() идентичны во всем, кроме реакции на ошибки. Обе генерируют Warning, но require() приводит к Fatal Error. Другими словами, используйте require(), если отсутствие файла должно остановить обработку страницы.
Require Once
Функция require_once() включает и выполняет указанный файл во время выполнения скрипта. Это поведение аналогично функции require(), с единственной разницей: если код из файла уже был включен ранее, он не будет включен снова.
Вышеуказанная информация взята из документации PHP. Дело в том, что нет "правильного" варианта - выбор зависит от потребностей кода. Я использую require() для важных вещей, таких как функции, но для файлов темы, таких как подвал (footer) или цикл (loop), я применяю include_once или include, потому что могу обработать предупреждение и сообщить пользователю/посетителю о произошедшей ошибке, а не просто выдать fatal_error.

В первую очередь, спасибо всем, кто ответил,
Моя проблема заключалась в подключении включаемых файлов с использованием полного URL, из-за чего они не проходили через WordPress. Это произошло потому, что, как я указал в вопросе, я вызывал их из основного файла плагина. Решением стало использование:
include_once('/ipn/paypal-ipn.php');
Я прочитал об этом в поддержке WordPress. И снова спасибо за ответы!

Не могли бы вы пересмотреть решение и отметить этот ответ (https://wordpress.stackexchange.com/a/32002/123092) как принятый?

include( plugin_dir_path( __FILE__ ) . 'ipn/paypal-ipn.php');
или
define( 'PLUGIN_ROOT_DIR', plugin_dir_path( __FILE__ ) );
include( PLUGIN_ROOT_DIR . 'ipn/paypal-ipn.php');
или
$plugin_dir_path = plugin_dir_path( __FILE__ );
include( $plugin_dir_path . 'ipn/paypal-ipn.php');
Примечание: для подключения .css и .js файлов через admin_enqueue_scripts
внутри плагина используйте plugin_dir_url( __FILE__ )
$plugin_dir_uri = plugin_dir_url( __FILE__ );
wp_enqueue_style( 'plugin-style', $plugin_dir_uri . 'css/plugin-style.css');

Привет @בניית אתרים:
При загрузке WordPress определяет функцию add_action()
до попытки загрузки любых плагинов. Тот факт, что вы получаете ошибку, говорит мне, что вы делаете что-то странное или что-то не так с вашей установкой WordPress.
Как вы загружаете свой "плагин"? Используете ли вы include*()
или require*()
для его загрузки, возможно, в файле wp-config.php
?

Когда вы создаете новый файл в рабочей директории, вам приходится подключать его каждый раз вручную. Но существует метод автоматического сканирования директории и подключения файлов, причем не только PHP, но и JS, CSS файлов, что удобно как для бэкенда, так и для фронтенда.
http://kvcodes.com/2014/05/wordpress-theme-development-include-files-automatically/
