When to use DIRECTORY_SEPARATOR in PHP code?
Asked Answered
S

4

40
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 "/" ?

Sever answered 12/11, 2014 at 7:19 Comment(6)
"DIRECTORY_SEPARATOR is not necessarily needed, PHP always converts / to the appropriate character in its file functions."Goff
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,Hydromedusa
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.Frymire
the answers here are not realisticPeriodical
Nicely explained here, please check https://mcmap.net/q/398072/-is-using-the-directory-separator-constant-necessaryTonsillotomy
Also note if you're using PHP to shell_exec a command which contains a path you will need the DIRECTORY_SEPARATOR to build that path in Windows.Edible
P
43

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.

Percentage answered 12/11, 2014 at 7:24 Comment(8)
Ok then why does the same code use / explicitly in the same line later?Swec
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.Swec
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.Gifferd
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 cmljnelson.wordpress.com/2018/07/26/…Pantin
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.Cirrus
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 dev.to/c33s/always-use--as-directory-seperator-in-php-43l7Garnishee
@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.Percentage
Thank you. You saved my day (y)Hornblende
G
18

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.

Garnishee answered 10/12, 2019 at 6:19 Comment(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 %5cFlavoring
My URL example is for everything except Windows. "While this will work on Windows, for everyone else..."Garnishee
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.Sarilda
V
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.

Verity answered 8/4, 2022 at 3:9 Comment(3)
This solution might not work in some regions. For instance, in the Japanese and Korean regions on Windows, the directory separator is the their respective currency symbols: ¥ for Japan and for Korea. You can test this by changing your region in Windows settings. Modern versions of Windows might handle conversion for you, but that wasn't always the case. I haven't used Windows in a long time, so can't say for sure. Just something to consider.Pitfall
@undefined, interesting fact. I did not know that. I have an internationally distributed platform. To date there's been no reports from either of those countries that forward slash produces a problem. If I hear that, I will comment here.Verity
It's worth noting that you might never encounter a problem because the backslash unicode character (U+005c) is the same in Japan (code page 932, 0x5c) and Korea (code page 949, 0x5c). It only LOOKS different. The problem that may arise is if THEY try to type the directory separator, because 1) The yen symbol occupies two different unicode characters, the other being U+00A5; and 2) they enter a Japanese backslash, which would be a different unicode char. Further reading: en.wikipedia.org/wiki/….Pitfall
F
3

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").

Freezedrying answered 24/12, 2015 at 1:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.