39
require_once dirname(__FILE__).DIRECTORY_SEPARATOR . './../../../wp-config.php';
require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'inc/options.php';

The above code is from a plugin from the Wordpress. I don't understand why half of it uses DIRECTORY_SEPARATOR, but the other half uses "/" ?

j08691
  • 204,283
  • 31
  • 260
  • 272
tanteng
  • 648
  • 1
  • 6
  • 11
  • 13
    "DIRECTORY_SEPARATOR is not necessarily needed, PHP always converts / to the appropriate character in its file functions." – fiction Nov 12 '14 at 07:24
  • 3
    `windows` understands the use of '/' as the directory separator. I run PHP code on both linux and windows without any change. I use '/' always in file paths etc. The main issue is that `windows` is not case sensitive as regards filenames so it is important to always use correct lettercase on windows otherwise it will not work when moved to `linux`, – Ryan Vincent Jun 16 '15 at 21:13
  • This is only important when you want to run your code on different operating systems who use a filesystem where the directory separator is not the same, like Windows or Linux. I am only running on Apache on Linux (even under Windows 10 you may use Apache with Ubuntu Subsystem). So I encode everything with the forward slash. – Markus Zeller Jan 06 '17 at 16:45
  • the answers here are not realistic – Jonathan DS Mar 10 '20 at 16:37
  • 1
    Nicely explained here, please check https://stackoverflow.com/a/7032949/3824618 – Aryashree Pritikrishna Nov 12 '20 at 13:13

4 Answers4

41

Because in different OS there is different directory separator. In Windows it's \ in Linux it's /. DIRECTORY_SEPARATOR is constant with that OS directory separator. Use it every time in paths.

In you code snippet we clearly see bad practice code. If framework/cms are widely used it doesn't mean that it's using best practice code.

Justinas
  • 41,402
  • 5
  • 66
  • 96
  • 3
    Ok then why does the same code use `/` explicitly in the same line later? – Hanky Panky Nov 12 '14 at 07:25
  • 2
    Yeah that's what the OP intends to know whether it is just a bad practice or does it serve any purpose to have both in the same line? And your comment is actually one possible answer to the question. – Hanky Panky Nov 12 '14 at 07:28
  • 4
    I don't think it's necessary to use the constant. I've always used a `/` in my paths and they work on both Windows and Unix. I think PHP is smart enough to do the conversion. – Simon East Jul 17 '15 at 08:47
  • 2
    there's not much point in using `DIRECTORY_SEPARATOR` in WordPress code though, because WordPress' built-in functions don't use it, they just use forward slashes (a little inconsistently, like in the code being discussed). In WordPress, you just need to expect a mix of forward and backslashes used as directory separators. But for PHP outside a framework, or at least outside WordPress, I think you're right, `DIRECTORY_SEPARATOR` is best. See https://cmljnelson.wordpress.com/2018/07/26/which-way-do-your-slashes-face/ – thespacecamel Jul 27 '18 at 16:18
  • 1
    I also use / on both windows and Unix, but there is a catch people should know about. It can bite you if you are manipulating paths. For example, if you call dirname(\_\_FILE\_\_) on Windows, you will get backslashes. If you then try to use str_replace() or preg_replace() to replace part of the path using forward slashes in your search pattern, there will be no match. I always normalize paths with $path = str_replace('\\', '/',$path) before doing any transformations. – Bob Ray Dec 28 '18 at 05:03
  • 4
    All of the io functions will internally convert slashes based on the OS being used. There is no need to use DIRECTORY_SEPARATOR (except in the scenario where you are passing filepaths to non-PHP code). In fact, it can even cause unexpected side effects in URLs as pointed out by Julian in https://dev.to/c33s/always-use--as-directory-seperator-in-php-43l7 – hostingutilities.com Dec 10 '19 at 05:02
  • 1
    @wp-overwatch.com Well, it's never intended to be used in URL. Url does not contain directories, just path to resource and it's structure is consistent. – Justinas Dec 10 '19 at 09:02
  • Thank you. You saved my day (y) – Anjana Silva Sep 29 '20 at 19:02
13

All of the PHP IO functions will internally convert slashes to the appropriate character, so it's not a huge deal which method you use. Below are some things to consider.

  • It can look ugly and confusing when you print out your file paths and there is a mix of \ and /. This won't ever happen if DIRECTORY_SEPARATOR is used

  • Using something such as $generated_css = DIRECTORY_SEPARATOR.'minified.css'; will work all fine and dandy for file IO, but if a developer unknowingly references it in a URL such as echo "<link rel='stylesheet'href='https:​//example.com$generated_css'>";, a bug was just created. Did you catch it? While this will work on Windows, for everyone else a forward slash, instead of a backslash, will be in $generated_css, resulting in the percent encoded, non-existant, URL https://example.com%5cgenerated_css! When using a DIRECTORY_SEPARATOR you have to take special care to make sure your filepath variables never end up in a URL.

  • And lastly, in the unlikely scenario your filepath is used by non-PHP code — for example, in a shell_exec call — you won't be able to mix slashes and will need to either construct the filepath with DIRECTORY_SEPARATOR or use realpath.

hostingutilities.com
  • 8,894
  • 3
  • 41
  • 51
  • 3
    I think you have that in reverse for your URL example: on Windows, a back slash would be created which could being encoded to %5c – georaldc May 29 '20 at 17:55
  • My URL example is for everything except Windows. *"While this will work on Windows, for everyone else..."* – hostingutilities.com Sep 01 '21 at 00:27
  • This should be the accepted answer. Mostly because it's more readble to avoid using `DIRECTORY_SEPERATOR` and secondly because there're some pitfails everyone should know about. – Jens Kohl Aug 08 '22 at 12:55
4

I learned from distributing code that the best way for your application to run on both Linux and Windows is to never use DIRECTORY_SEPARATOR, or backslashes \\, and to ONLY use forward slashes /.

Why? Because a backslash directory separator ONLY works on Windows. And forward slashes works on ALL (Linux, Windows, Mac altogether).

Using the constant DIRECTORY_SEPARATOR or escaping your backslashes \\ quickly becomes messy. I mean look at it:

$file = 'path' . DIRECTORY_SEPARATOR . 'to' . DIRECTORY_SEPARATOR . 'file';
$file = str_replace('/', DIRECTORY_SEPARATOR, 'path/to/file';
$file = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? 'path\\to\\file' : 'path/to/file';

When you can just do this:

$file = 'path/to/file';

The only downside is that on Windows; PHP will return backslashes for all file references from functions like realpath(), glob(), and magic constants like __FILE__ and __DIR__. So you might need to str_replace() them into forward slashes to keep it consistant.

$dir = str_replace('\\', '/', realpath('../'));

I wish there was a php.ini setting to always return forward slashes.

tim
  • 2,530
  • 3
  • 26
  • 45
2

Do not use your own folder separators. Always use DIRECTORY_SEPARATOR, because:

  1. In some special cases you really need the correct path delimiter
  2. The OS might handle it correctly, but many 3rd party applications can't and might fail!
  3. Some operating systems do not use / or \ as separators but something different

Don't forget: Use the constant only on the remote system - don't use it for URIs or anything else that you want to send to the client (except you really need it, like a "remote browser").

StanE
  • 2,704
  • 29
  • 38