WordPress.org

Make WordPress Core

Opened 4 years ago

Closed 22 months ago

Last modified 36 hours ago

#17092 closed enhancement (fixed)

use dirname(__file__).'/file.php' instead of './file' for includes

Reported by: ketwaroo Owned by: nacin
Milestone: 3.7 Priority: normal
Severity: minor Version: 3.1.1
Component: General Keywords: has-patch 2nd-opinion
Focuses: Cc:

Description

most initial includes prior to having ABSPATH defined are usually of the format:

require('./wp-blog-header.php');

as seen in the main index.php. Most of these occur in /wp-admin.

which is fine in most cases. Except on some windows servers where relative paths can get a bit funky. or if you're trying to include the file which contains a relative include in a file found in another directory (which happens when you're trying to use wordpress for something other than its intended purpose, like developing a more practical multisite system, on multiple domains, with a single copy of wordpress files for all the sites).

anyway, I just wanted to request that absolute paths be used for includes.

for example:

in /index.php
 require('./wp-blog-header.php');
becomes:
 require( dirname(__FILE__) . '/wp-blog-header.php' );
in /wp-admin/admin-ajax.php
 require_once('../wp-load.php');
becomes
 require_once( dirname(dirname(__FILE__)) . '/wp-load.php' );
in /wp-admin/maint/repair.php
 require_once('../../wp-load.php');
becomes
 require_once( dirname(dirname(dirname(__FILE__))) . '/wp-load.php' );

it may not look as pretty but I think it's a saner/safer method of inclusion. Just a suggestion for the next major release. Or as you gradually update files.

Attached is the patch I made from 3.1.1. It replaces every relative include|require(_once)? by absolute ones. As far as I've tested, works the same as unpatched and no includes are broken.

Attachments (4)

pathfix 3.1.1.patch (62.7 KB) - added by ketwaroo 4 years ago.
replaces all relative includes by absolute ones.
pathfix 3.1.1.stragglers.patch (1019 bytes) - added by ketwaroo 4 years ago.
a few missing includes.
17092.diff (66.8 KB) - added by kawauso 4 years ago.
Against trunk, using ABSPATH
17092.001.patch (65.3 KB) - added by hakre 2 years ago.
update to remove superfluous dirname() calls.

Download all attachments as: .zip

Change History (21)

@ketwaroo4 years ago

replaces all relative includes by absolute ones.

comment:1 @nacin4 years ago

I'm not sure I've ever run into a situation where ./ doesn't work the same as dirname( __FILE__ ). It skips include_path, looking for the file in the same directory.

We used to have require( 'admin.php' ); in some situations, thus relying on the include_path and often the script that started the process. But that shouldn't be the case here with ./.

I would like some real-life examples of issues where this fails. I've not seen a Windows server with a problem with this. Additionally, having multiple domains run off a single copy of WordPress multisite is pretty common, and given it's the same set of files, this doesn't really come into play as far as I can tell.

comment:2 @ketwaroo4 years ago

for example.

wrapper.php in /path/to/site1.com/htdocs

  define ('COREDIR','/path/to/wordpress/');
  // do some wrapper stuff
   include COREDIR.'/index.php';

index.php

  require('./wp-blog-header.php');

A fatal error occurs as index.php is looking for wp-blog-header.php in /path/to/site1.com/htdocs. and as you said, ./ skips include_path so I can't set it in the wrapper.

It's a rare case scenario, but still.

@ketwaroo4 years ago

a few missing includes.

comment:3 follow-up: @sivel4 years ago

We absolutely should not be doing dirname( __FILE__ ) for every include, include_once, require, require_once.

My tests show that if you do it for the roughly 200 places that WordPress uses ./ that it increases memory usage by 0.087MB and increases execution time by 0.000830888748169 seconds.

These figures seem small, but as core grows, and added on top of other things these changes only add to inefficiency.

If we were to do this at all we need to start utilizing ABSPATH, that we use for most of the other includes, especially for files within wp-includes.

In general I am -1 for this, but if we do it, we should rely on already in use file path constants from core, and not add new vars/constants or run dirname for every include/require.

comment:4 @dd324 years ago

We absolutely should not be doing dirname( FILE ) for every include, include_once, require, require_once.

No we shouldn't. It should only be used before ABSPATH is defined. so files in the loading process.

comment:5 in reply to: ↑ 3 @ketwaroo4 years ago

Replying to sivel:

We absolutely should not be doing dirname( __FILE__ ) for every include, include_once, require, require_once.

like dd32 said, it's only for the initial bootstrap file (usually wp-load.php) before ABSPATH is defined. Per script execution that's done only once. Actually, dirname(__FILE__) was already being used a few places.

It is a fairly minor issue. There are only about 80 places where the replacements would take place. You can see them in the patch files I uploaded.

My tests show that if you do it for the roughly 200 places that WordPress uses ./ that it increases memory usage by 0.087MB and increases execution time by 0.000830888748169 seconds.

er.. how.. did you test that?

comment:6 @dd324 years ago

Looking through the patch, The only files which should be using dirname() are 'admin.php', 'wp-load.php', and 'wp-blog-header.php'. The rest should be using ABSPATH . 'wp-admin/...'

@kawauso4 years ago

Against trunk, using ABSPATH

comment:7 @kawauso4 years ago

Re-did patch with ABSPATH except where necessary and caught some remaining relative paths.

Took out changes to the external package file wp-includes/js/tinymce/plugins/spellchecker/rpc.php

Noticed the use of include(), require() and require_once() for admin-header.php and admin-footer.php seems pretty inconsistent.

Version 0, edited 4 years ago by kawauso (next)

comment:8 @ace_dent3 years ago

+1 for patching wp-cron.
Users opting for 'proper' cron jobs may follow a guide like:
http://bit51.com/stop-wp-cron-wordpress-cron-jobs-from-firing-on-every-page-load/

Here wp-cron is being called without ABSPATH and can then fail due to server restrictions/ incorrect path being returned.
Safer to use the proposed method here ...

comment:9 @ace_dent3 years ago

  • Cc ace_dent added

comment:10 @ocean902 years ago

#25068 was marked as a duplicate.

comment:11 @hakre2 years ago

Attachment is a patch against WP 3.6.

comment:12 @ocean902 years ago

  • Milestone changed from Awaiting Review to 3.7

@hakre2 years ago

update to remove superfluous dirname() calls.

comment:13 @hakre2 years ago

last patch had a bug, fixed.

comment:14 @hakre23 months ago

if someone could please review this again and let me know into which direction you want to go please.

This patch addresses valid things, if there is some matter of taste please let me know.

In my understanding includes should not be done relative to the current working directory (as it is the case with include paths starting with ./ or ../).

If there is a an opinion different to that (not so clear with the earlier comments), please raise your concerns again. Include-Path searches aren't the case with CWD relative includes as well as the ABSPATH based ones.

comment:15 @nacin22 months ago

  • Owner set to nacin
  • Resolution set to fixed
  • Status changed from new to closed

In 25616:

Don't rely on include_path to include files.

Always use dirname() or, once available, ABSPATH.

props ketwaroo, hakre.
fixes #17092.

comment:16 @nacin22 months ago

[25616] was done after reviewing each instance to ensure there were no typos.

The only issues were a few dirname() calls when ABSPATH could be used instead, isolated to wp-admin/revison.php wp-admin/options-permalink.php wp-admin/themes.php wp-admin/widgets.php. Nice work.

comment:17 @pento36 hours ago

In 33459:

XML-RPC: Don't rely on include_path to include files, use dirname() instead.

See #17092.

Note: See TracTickets for help on using tickets.