DEV Community

Cover image for Always use `/` as directory separator in php
Julian
Julian

Posted on • Updated on

Always use `/` as directory separator in php

as a long time windows user and php developer, i can only say: do not use DIRECTORY_SEPARATOR! it has no real benefit but really can break things.

use /. it is the better choice nearly every time.

yes it break things!

if you use DIRECTORY_SEPARATOR, which resolves to \ on windows, things tend to break. For example:\ gets converted to %5C in urls.

http://example.com/media/cache/resolve/my_thumb/d/0/1%5Cfilename.jpg
Enter fullscreen mode Exit fullscreen mode

if DIRECTORY_SEPARATOR is used, it easily happens that the (relative) path, which will contain a backslash on windows, is passed to something which should be a url. assuming that most of the php developers are using linux or mac (i personally don't know many people who develop php on windows), they don't notice that in a windows environment a backslash is passed to the url and gets escaped as %5C which leads to urls like in the example above.

windows and php on windows are capable of opening files with the path foo/bar\example/test.txt
so DIRECTORY_SEPARATOR is of no real use except for easily detecting windows or for example if you export a path for a file list where a windows user would be confused to see / instead of \

λ cat ./foo/bar\example/test.txt
mycontent
Enter fullscreen mode Exit fullscreen mode

(yes cat exists on windows)

notepad ./foo/bar\example/test.txt
Enter fullscreen mode Exit fullscreen mode

also opens the file

foo.php:

<?php
$content = file_get_contents('foo/bar\example/test.txt');
var_dump($content);
Enter fullscreen mode Exit fullscreen mode
λ php foo.php
C:\test\foo.php:5:
string(9) "mycontent"
Enter fullscreen mode Exit fullscreen mode

even that works:

<?php
$content = file_get_contents('c:/foo/bar\example/test.txt');
var_dump($content);
Enter fullscreen mode Exit fullscreen mode

Top comments (9)

Collapse
 
mehranhadidi profile image
Mehran Hadidi

You are not supposed to use DIRECTORY_SEPARATOR on URLs. You should use it only for working with directories and files.

Collapse
 
funkedgeek profile image
Manny Fleurmond

Agreed. My rule of thumb now that I've discovered this constant is to use it just for file directory access. The problems illustrated seem to only occur when dealing with URLs. For me it's an anal stylistic choice. Thank you for the warning though, Mr Author

Collapse
 
c33s profile image
Julian

linux user won't notice if their program will return \ on windows. so they don't recognize if a relative path will be exposed to an url somewhere.

Collapse
 
anonyco profile image
Jack Giffin • Edited

You don't have to test it on Windows. You just have to do str_replace($url, '\\', '//') at every location in your code which deals with URLs. Backslashes, even encoded ones, are not part of normal common URLs, so this code may even help prevent possible bugs. If you have special needs that require an encoded backslash to be preserved, you can tweak this function. It's that simple.

Furthermore, you really shouldn't be hosting a server on Windows. It's a terrible awful very bad idea. You never know when MS is going to push the next update that's going to crash your server or make the CIA's backdoors to your PC vulnerable or worse. Linux and BSD are where it's at, and any self-respecting dev uses a *nix server.

Collapse
 
keinos profile image
KEINOS

I understand URL's slashes came from UNIX based directory separator so DIRECTORY_SEPARATOR is almost equal to the URL's.

Though, I think there are a bunch of Windows PHP coders in the world, at least in Asia. (I'm a macOS user but I've seen many)

As a info, in a non-English locale env such as Japan, backslash \ is replaced as ¥ as a directory separator. Yes, different ASCII code they are, so even more annoying.

So if you aim to code for an international usage, or run the script on their env., I think DIRECTORY_SEPARATOR is worth to care about it.

Since, with this, you can think less about the locale to access files, run the script. Except if you're using it for URL or directory path.

Collapse
 
c33s profile image
Julian

and to which symbol / is replaced? if it stays the same your argument that \ is replaced to ¥ also hardens my argument to only use / as separator

Collapse
 
keinos profile image
KEINOS

/ (as a directory separator) is ¥ on Japanese Win env.

And on non-UNICODE encoding env such as Shift-JIS, \ is displayed also as ¥.

Since we have to handle a lot of encodings (Shift-JIS, JIS, EUC, UTF-8, UTF-16) until all the systems become UTF-16 or at least UTF-8, we have to convert encoding each other.

The problem is, Windows10 JP uses half Shift-JIS and half UTF-16 inside, so you can type /, ¥, \ as is.

But once changing the encoding (UTF-8 -> S-JIS) it becomes a mess. Imagine \ as escaping and directory as / becomes all ¥.

Well, I agree "always using / as a directory separator" would be nice. Really.

But so far I think for directory separator purposes using DIRECTORY_SEPARATOR is safer.

Thread Thread
 
c33s profile image
Julian

that sounds odd... of course a thing to keep in mind.

But so far I think for directory separator purposes using DIRECTORY_SEPARATOR is safer.

not sure if you can generalize that. as i wrote in my post, people are using the DIRECTORY_SEPARATOR and it happened to me more than once, that the well-intentioned DIRECTORY_SEPARATOR simply broke stuff.
of course you arguments are really good ones, i simply try to balance what happens more often, a special encoding which is known to break things or a DIRECTORY_SEPARATOR which is used wrong because it can't be tested on linux systems.

Thread Thread
 
shipman profile image
jon™

But you shouldn't use DIRECTORY_SEPARATOR on urls, hence your "simply broke stuff" issue.

It's like using move_uploaded_file to move file A.txt to B.txt, it simply won't work.