What's the difference between get_home_path()
and ABSPATH
?
Isn't the point of both to point to the WordPress install root?
3 Answers
They should do the same thing, but under certain conditions, may not.
First of all note:
- that the codex entry description is misleading
- that
wp-admin/includes/file.php
must be included in context else callingget_home_path()
will lead to calling an undefined function.
Regarding the codex entry,
Description
Get the absolute filesystem path to the root of the WordPress installation.
Return Value
Full filesystem path to the root of the WordPress installation. If you install wordpress in subfolder, it will show subfolder location
Examples
$path = get_home_path(); print "Path: ".$path; // Return "Path: /var/www/htdocs/" or "Path: /var/www/htdocs/wordpress/" if it is subfolder
It states that the return value will return the path of the subfolder if you have installed WordPress in a sub-directory. This is in fact, incorrect.
get_home_path()
will return the root directory of your WordPress installation, even if it's installed in a sub-directory. That is the purpose of the function.
Assume your WordPress installation is within a sub-directory called /dev
,
- http://www.example.com/dev (
site_url
) (e.g. /var/www/htdocs/dev) - http://www.example.com/ (
home_url
)
If you log a call to ABSPATH
, then the result of which will be, /var/www/htdocs/dev
which is not the root of your installation. The root of your installation is /var/www/htdocs
.
ABSPATH
is first defined in wp-load.php
which will be located at /var/www/htdocs/dev/wp-load.php
hence this is where ABSPATH
will take its definition from.
If you inspect the get_home_path()
further you will note that if the site_url
and home_url
differ, then a sub-string is taken of the path governed by the position (first occurance) of the sub-directory found within the string.
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 );
}
Therefore, as a result of this, get_home_path()
and ABSPATH
may return different results if you have WordPress installed in a sub-directory.
Secondly, calling get_home_path()
must be done in a context where the afortmentioned wp-admin/includes/file.php
has already been included.
As an example using get_home_path()
within the admin_init
hook is fine where as using it within init
is not.
Seeing as this file only gets included from within the admin (dashboard) context, if you absolutely need it outside of this context you will need to include the file yourself before calling the function,
require_once(ABSPATH . 'wp-admin/includes/file.php');
Ironically (or not) which uses ABSPATH
:D
-
Well explained, all though I think third party developers should neither use the constant nor the function. Because WordPress can be located anywhere, placing it outside the document root causes both the constant and the function to return e.g.
/var/apps/wordpress
instead of/var/www/htdocs
. Rather use$_SERVER['DOCUMENT_ROOT']
, at least if you can assure that the document root wouldn't change. Feb 13, 2018 at 20:28 -
@Fleuv Indeed this is a tricky one... even
$_SERVER['DOCUMENT_ROOT']
has its issues... e.g.may not be set or set correctly and so on. There's other ways I can think of too to handle this... Each with their own caveats. Much fun :)– AdamMar 19, 2018 at 8:01 -
2This solution was well explained and worked exactly as desired after WP was throwing the "not defined" error. Thanks ;) Jul 9, 2018 at 12:39
Nicely explained by Adam but he didn't give solution to avoid using ABSPATH
.
That is when we need to get wp-admin path and wp-admin/includes/file.php is also not included such as in init hook or execution on frontend.
We can avoid calling ABSPATH
in require_once(ABSPATH . 'wp-admin/includes/file.php');
By copying get_home_path()
definition into a file in your project and include that file if following condition meets like
if ( ! function_exists( 'get_home_path' ) ) {
require_once MY_PLUGIN_DIR . 'includes/helpers/admin_functions.php';
}
and inside your MY_PLUGIN_DIR . 'includes/helpers/admin_functions.php'
copy the get_home_path()
from 'wp-admin/includes/file.php'.
WP Update will also not cause the problem since this function depends only on php functions some minor include functions. So we are avoiding ABSPATH when needed.
I am using home_url() for linking to the "Home" page of WP. Sometimes, site_url() may not be really your home_url(). You can define a spesific page as homepage in Wordpress.