В чем разница между get_home_path() и ABSPATH?

15 мая 2015 г., 14:53:05
Просмотры: 34.1K
Голосов: 33

В чем разница между get_home_path() и ABSPATH? Разве они оба не предназначены для указания на корневую директорию установки WordPress?

0
Все ответы на вопрос 3
3
41

Они должны делать одно и то же, но при определенных условиях могут вести себя по-разному.

Прежде всего обратите внимание:

  • описание в кодексе вводит в заблуждение
  • 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:

Если вы вызовете 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

15 мая 2015 г. 16:49:17
Комментарии

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

luukvhoudt luukvhoudt
13 февр. 2018 г. 22:28:02

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

Adam Adam
19 мар. 2018 г. 10:01:18

Это решение было хорошо объяснено и сработало именно так, как нужно, после того как WP выдавал ошибку "not defined". Спасибо ;)

Chris Sprague Chris Sprague
9 июл. 2018 г. 15:39:50
0

Адам хорошо объяснил, но не предоставил решение, как избежать использования 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, когда это необходимо.

11 июн. 2022 г. 08:27:07
0
-1

Я использую home_url() для ссылки на главную страницу WordPress. Иногда site_url() может не совпадать с вашей home_url(). В WordPress вы можете назначить определённую страницу в качестве главной.

23 июл. 2018 г. 13:20:00