В чем разница между get_home_path() и ABSPATH?
Они должны делать одно и то же, но при определенных условиях могут вести себя по-разному.
Прежде всего обратите внимание:
- описание в кодексе вводит в заблуждение
wp-admin/includes/file.php
должен быть подключен в контексте, иначе вызовget_home_path()
приведет к ошибке вызова неопределенной функции.
Что касается записи в кодексе:
Описание
Получает абсолютный путь к корневой директории установки WordPress в файловой системе.
Возвращаемое значение
Полный путь в файловой системе к корню установки WordPress. Если WordPress установлен в поддиректории, функция вернет путь до этой поддиректории.
Примеры
$path = get_home_path(); print "Path: ".$path; // Вернет "Path: /var/www/htdocs/" или "Path: /var/www/htdocs/wordpress/" если установлен в поддиректории
Указано, что функция вернет путь поддиректории, если WordPress установлен в ней. На самом деле, это неверно.
get_home_path()
возвращает корневую директорию установки WordPress, даже если он установлен в поддиректории. В этом и заключается назначение функции.
Предположим, WordPress установлен в поддиректории /dev
:
- http://www.example.com/dev (
site_url
) (например, /var/www/htdocs/dev) - http://www.example.com/ (
home_url
)
Если вы вызовете ABSPATH
, то получите /var/www/htdocs/dev
, что не является корнем установки. Корень установки — /var/www/htdocs
.
ABSPATH
определяется в wp-load.php
, который находится в /var/www/htdocs/dev/wp-load.php
, поэтому именно отсюда ABSPATH
берет свое значение.
Если изучить get_home_path()
глубже, можно заметить, что если site_url
и home_url
отличаются, то из пути вырезается подстрока, определяемая позицией (первым вхождением) поддиректории в строке.
function get_home_path() {
$home = set_url_scheme( get_option( 'home' ), 'http' );
$siteurl = set_url_scheme( get_option( 'siteurl' ), 'http' );
if ( ! empty( $home ) && 0 !== strcasecmp( $home, $siteurl ) ) {
$wp_path_rel_to_home = str_ireplace( $home, '', $siteurl ); /* $siteurl - $home */
$pos = strripos( str_replace( '\\', '/', $_SERVER['SCRIPT_FILENAME'] ), trailingslashit( $wp_path_rel_to_home ) );
$home_path = substr( $_SERVER['SCRIPT_FILENAME'], 0, $pos );
$home_path = trailingslashit( $home_path );
} else {
$home_path = ABSPATH;
}
return str_replace( '\\', '/', $home_path );
}
Таким образом, get_home_path()
и ABSPATH
могут возвращать разные значения, если WordPress установлен в поддиректории.
Во-вторых, вызов get_home_path()
должен происходить в контексте, где уже подключен упомянутый wp-admin/includes/file.php
.
Например, использование get_home_path()
внутри хука admin_init
допустимо, а внутри init
— нет.
Поскольку этот файл подключается только в контексте админ-панели, если вам необходимо использовать функцию вне этого контекста, подключите файл вручную перед вызовом:
require_once(ABSPATH . 'wp-admin/includes/file.php');
Иронично (или нет), что здесь используется ABSPATH
:D

Хорошее объяснение, хотя я считаю, что сторонним разработчикам не следует использовать ни константу, ни функцию. Поскольку WordPress может быть размещен где угодно, его расположение вне корневой директории документа приводит к тому, что и константа, и функция возвращают, например, /var/apps/wordpress
вместо /var/www/htdocs
. Лучше использовать $_SERVER['DOCUMENT_ROOT']
, по крайней мере, если вы уверены, что корневая директория документа не изменится.

@Fleuv Действительно, это сложный момент... даже у $_SERVER['DOCUMENT_ROOT']
есть свои проблемы... например, он может быть не установлен или установлен некорректно и так далее. Есть и другие способы решения этой проблемы... Каждый со своими нюансами. Весело :)

Адам хорошо объяснил, но не предоставил решение, как избежать использования ABSPATH
.
Это особенно важно, когда нам нужно получить путь к wp-admin, а файл wp-admin/includes/file.php еще не подключен, например, на хуке init или при выполнении на фронтенде.
Мы можем избежать вызова ABSPATH
в require_once(ABSPATH . 'wp-admin/includes/file.php');
Скопировав определение get_home_path()
в файл вашего проекта и подключив его, если выполняется следующее условие:
if ( ! function_exists( 'get_home_path' ) ) {
require_once MY_PLUGIN_DIR . 'includes/helpers/admin_functions.php';
}
а внутри вашего MY_PLUGIN_DIR . 'includes/helpers/admin_functions.php'
скопируйте функцию get_home_path()
из 'wp-admin/includes/file.php'.
Обновления WordPress также не вызовут проблем, поскольку эта функция зависит только от PHP-функций и некоторых второстепенных include-функций. Таким образом, мы избегаем использования ABSPATH, когда это необходимо.
