Get URL of any PHP file in WordPress

Getting URL of the current page or current PHP file is a very common task. And that is not exceptional in WordPress. For example: when you include a plugin in a theme or using LESS PHP compiler. There’re some available techniques, but I found that all of them are not good enough to work in all situation, so I hope what I write in this post is a better approach.

Let’s look at these methods before getting to the final solution:

1. Get current URL by Konstantin Kovshenin

This technique is covered here. It uses $wp->request and $wp->query_string to get current URL of a page in the front end

global $wp;
$current_url = add_query_arg( $wp->query_string, '', home_url( $wp->request ) );

It’s good enough if you only want URL for the current page and in the front end. It doesn’t help if you want to have URL to a plugin file.

This technique is updated by Stephen Harris:

$current_url = home_url( add_query_arg( array(), $wp->request ) );

2. Get URL of current PHP file, common approach

There’re several tutorials on the Internet about this technique, all of them are similar to this:

$pageURL = @$_SERVER['HTTPS'] == 'on' ? 'https://' : 'http://';
if ( $_SERVER['SERVER_PORT'] != '80' )
    $pageURL .= $_SERVER['HTTP_HOST'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI'];
else 
    $pageURL .= $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
return $pageURL;

(Source)

Or in WordPress way:

$current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );

This also works quite well. The logic is similar to 1st method, it based on request URI, server name.

But it has only one disadvantage: this method work only with current requested PHP file. And that totally fails if you want to get URL to a plugin of WordPress (you probably never access to plugin PHP file directly, right?)

3. Replace WP_CONTENT_DIR by WP_CONTENT_URL

The logic is simple: all our PHP files are located in wp-content dir, thus replacing WP_CONTENT_DIR by WP_CONTENT_URL is a good hope to get correct URL:

$file = __FILE__; // Current PHP file, but can be anyone
$link = str_replace( WP_CONTENT_DIR, WP_CONTENT_URL, $file );

Of course, this is very simple and works in most cases. These 2 variables are initialized when WordPress is loaded. We don’t need to consider about server path, server request, query string list 1st and 2nd methods. Safe enough.

But there’re 2 problems with this method:

  • In Windows environment, due to inconsistent of using backward slash (/) and forward slash (\) in the path by WordPress (see how it defines these constants without considering this problem), the function doesn’t return correct URL.

Test code:

add_action( 'init', '_test_url' );

function _test_url()
{
    $file = __FILE__;
    $url = str_replace( WP_CONTENT_DIR, WP_CONTENT_URL, $file );
    echo
        '<pre>',
        '__FILE__      : ' . $file . '<br>',
        'WP_CONTENT_DIR: ' . WP_CONTENT_DIR . '<br>',
        'WP_CONTENT_URL: ' . WP_CONTENT_URL . '<br>',
        'URL           : ' . $url . '<br>',
        '</pre>'
    ;
    die;
}

Result:

__FILE__      : D:\Dropbox\UniServer\www\wp\wp-content\mu-plugins\test.php
WP_CONTENT_DIR: D:\Dropbox\UniServer\www\wp/wp-content
WP_CONTENT_URL: http://localhost:8080/wp/wp-content
URL           : D:\Dropbox\UniServer\www\wp\wp-content\mu-plugins\test.php
  • Second problem comes from MultiSite environment with Domain Mapping plugin installed. Because the constant WP_CONTENT_URL is defined via function get_option( 'siteurl' ), it doesn’t give you the correct URL to wp-content folder in sub-site.

Assume we have a multisite with main domain test.com, and a sub-site with domain exam.com. If we run the same test code as above, we’ll see this results:

In main site (correct):

__FILE__      : /var/home/testuser/www/test.com/wp-content/mu-plugins/test.php
WP_CONTENT_DIR: /var/home/testuser/www/test.com/wp-content
WP_CONTENT_URL: http://test.com/wp-content
URL           : http://test.com/wp-content/mu-plugins/test.php

In sub-site (incorrect):

__FILE__      : /var/home/testuser/www/test.com/wp-content/mu-plugins/test.php
WP_CONTENT_DIR: /var/home/testuser/www/test.com/wp-content
WP_CONTENT_URL: http://test.com/exam/wp-content
URL           : http://test.com/exam/wp-content/mu-plugins/test.php

4. Final (working) solution:

If you run your site in Linux environment and not in MultiSite mode, you can use 3rd method above. It’s short and works like a charm!

But if you want a solution that works in all situation, let’s try this:

$file = __FILE__;

// Get correct URL and path to wp-content
$content_url = untrailingslashit( dirname( dirname( get_stylesheet_directory_uri() ) ) );
$content_dir = untrailingslashit( WP_CONTENT_DIR );

// Fix path on Windows
$file = wp_normalize_path( $file );
$content_dir = wp_normalize_path( $content_dir );

$url = str_replace( $content_dir, $content_url, $file );

Basically, this solution is an additional version of 3rd method above with 2 fixes mentioned. Please try this, and if you have any suggestion or idea, please let me know via comments!

Update December 16th, 2015: Use wp_normalize_path to fix path on Windows.

Update December 24th, 2015: Use WP_CONTENT_DIR as it’s safe.

2 thoughts on “Get URL of any PHP file in WordPress

Comments are closed.

Newsletter

Subscribe to our newsletter to receive news and tutorials about WordPress and web development.

Want to get away from Pipdig drama? See 30+ Pipdig blog themes alternatives See here →