Как лучше всего получить путь к директории wp-config.php в WordPress?
Я разработчик плагина mapsmarker.com, который также предлагает несколько API, доступных напрямую (например, www.mapsmarker.com/wp-content/plugins/leaflet-maps-marker/leaflet-geojson.php?marker=1) Для этих API я изначально записывал абсолютный путь к файлу следующей функцией при установке плагина:
file_put_contents(dirname(__FILE__).'/leaflet-wp-path.php', '<?php define(\'WP_PATH\',\''.ABSPATH.'\'); ?>');
В API-файлах файл leaflet-wp-path.php включался следующим кодом:
include_once(dirname($_SERVER['SCRIPT_FILENAME']).'/leaflet-wp-path.php');
include_once(WP_PATH.'wp-config.php');
include_once(WP_PATH.'wp-includes/wp-db.php');
global $wpdb;
...
Затем я заметил, что на некоторых хостинг-провайдерах такие операции не поддерживаются, что вызывает сбой при установке плагина. Поэтому я перешел на другой метод определения пути к wp-config.php:
//информация: создаем путь к wp-config.php с резервным вариантом для установок в поддиректории
$wp_path = $_SERVER["DOCUMENT_ROOT"];
if ( file_exists($wp_path . '/wp-config.php') ) {
include_once($wp_path.'/wp-config.php');
include_once($wp_path.'/wp-includes/wp-db.php');
} else {
$wp_plugin_path_modified = explode(DIRECTORY_SEPARATOR, dirname(__FILE__),-3);
$wp_path = implode(DIRECTORY_SEPARATOR, $wp_plugin_path_modified);
include_once($wp_path.'/wp-config.php');
include_once($wp_path.'/wp-includes/wp-db.php');
}
if ( !file_exists($wp_path . '/wp-config.php') ) {
echo __('Ошибка: Не удалось определить путь к wp-config.php - подробнее см. <a href="http://mapsmarker.com/path-error">http://mapsmarker.com/path-error</a>','lmm') . '<br/>Путь на вашем хостинге: ' . $wp_path;
} else {
...
Это работало нормально даже на хостах, которые не разрешают функцию file_put_contents(), поскольку путь к директории определяется из текущего dirname API-файла.
Теперь я получил сообщение об ошибке от пользователя, который говорит, что этот метод не работает на его хостинге. Он пишет:
Это пример одной из ссылок на иконку. Похоже, все ссылки плагина некорректны. Единственное, что сейчас работает, это панель администратора. Также создаются маркеры, но они не отображаются в браузерах.
На Windows Web Host http://XXXXX/wordpress/wp-content/plugins/D:/Hosting/5465771/html/wordpress/wp-content/plugins/leaflet-maps-marker/img/logo-mapsmarker.png
На Linux Web Host http://XXXXX/wordpress/wp-content/plugins/D:/inetpub/vhosts/XXXXX/httpdocs/wordpress/wp-content/plugins/leaflet-maps-marker/img/logo-mapsmarker.png
Кто-нибудь знает лучший метод определения пути к wp-config.php, который поддерживал бы такую конфигурацию хостинга?

Я пришел к такому решению.
Эта функция проверяет на каждом уровне директории, начиная с директории текущего файла, наличие файла wp-config.php.
<?php
function find_wp_config_path() {
$dir = dirname(__FILE__);
do {
if( file_exists($dir."/wp-config.php") ) {
return $dir;
}
} while( $dir = realpath("$dir/..") );
return null;
}
?>
Для фактического подключения файла можно использовать это:
if ( ! function_exists('add_action') ) {
include_once( find_wp_config_path() . '/wp-load.php' );
}
Это также можно найти здесь: Как определить базовый путь WordPress, когда ядро WordPress не загружено

Я постоянно использую этот подход. Он делает код чище, мне не нравится идея полагаться на внешние функции для получения путей при подключении файлов. Вот ваш апвот.

Для ясности, вопрос подразумевает выполнение неверного действия — даже в то время, когда он был задан, не следовало напрямую обращаться к файлам плагина. Вместо этого стоило использовать уникальный параметр URL, например my_plugin_param
, наличие которого указывало бы плагину на необходимость выполнения определённых действий. Для его обнаружения плагин должен подключаться к действию init
и проверять, содержит ли URL параметр my_plugin_param
. При таком подходе не требуется отдельно загружать WordPress, так как он уже будет инициализирован.
Хотя файл wp-config.php
должен находиться либо в корне WordPress, либо на один уровень выше, плагины могут быть установлены за пределами директорий WordPress. Хотя такая настройка не особенно популярна, она возможна.

это не мой код, нашел на stack, но попробуйте это:
function FindWPConfig($dirrectory){
global $confroot;
foreach(glob($dirrectory."/*") as $f){
if (basename($f) == 'wp-config.php' ){
$confroot = str_replace("\\", "/", dirname($f));
return true;
}
if (is_dir($f)){
$newdir = dirname(dirname($f));
}
}
if (isset($newdir) && $newdir != $dirrectory){
if (FindWPConfig($newdir)){
return false;
}
}
return false; }
if (!isset($table_prefix)){
global $confroot;
FindWPConfig(dirname(dirname(__FILE__)));
include_once $confroot."/wp-load.php";
}

Поскольку это то же самое решение, что и у bueltge, я могу только повториться: это очень неприятный подход. Вывод осуществляется через глобальную переменную, что не очень хорошо. Код действительно запутанный и неэффективный. То же самое можно сделать гораздо лучше с моим решением, которое я опубликовал.

Следующее не совсем отвечает на вопрос в контексте, но точно отвечает на то, что указано в заголовке вопроса.
Для тех, кто ищет способ получить путь к файлу wp-config.php изнутри WordPress, следующий способ работает отлично.
Вот как это делает WP CLI:
function locate_wp_config() {
static $path;
if ( null === $path ) {
$path = false;
// Проверяем путь из переменной окружения WP_CONFIG_PATH
if ( getenv( 'WP_CONFIG_PATH' ) && file_exists( getenv( 'WP_CONFIG_PATH' ) ) {
$path = getenv( 'WP_CONFIG_PATH' );
// Проверяем стандартное расположение wp-config.php в корне ABSPATH
} elseif ( file_exists( ABSPATH . 'wp-config.php' ) ) {
$path = ABSPATH . 'wp-config.php';
// Проверяем расположение wp-config.php на уровень выше ABSPATH, если нет wp-settings.php
} elseif ( file_exists( dirname( ABSPATH ) . '/wp-config.php' ) && ! file_exists( dirname( ABSPATH ) . '/wp-settings.php' ) ) {
$path = dirname( ABSPATH ) . '/wp-config.php';
}
// Если путь найден, преобразуем его в реальный путь
if ( $path ) {
$path = realpath( $path );
}
}
return $path;
}

Но это на самом деле не выполняет поиск файла, поэтому не будет особо полезным для случая, описанного в вопросе. Это предполагает, что вы либо установили переменную окружения, либо запускаете код изнутри WordPress, либо уже находитесь в нужной папке.

Тогда заголовок вопроса некорректен. Потому что на wordpress.stackexchange.com, как для человека, который ищет ответы, подобные мне, ожидается, что мы работаем внутри WordPress. Я отредактировал свой ответ для тех, кто просто читает заголовок и ожидает ответа на него.
