What Path is acceptable? - php

I am using below statement to return the directory name of the running script:
print dirname(__FILE__);
it outputs something like this with back-slashes:
www\EZPHP\core\ezphp.php
Question:
Is a path with back-slashes acceptable across all major operating systems? If not, how should i construct the path either with slashes or back-slashes so that it is acceptable on all major operating systems eg Windows, Linux, Ubuntu.
Thank You.

Forward slashes are a good route.
There is also a constant called DIRECTORY_SEPARATOR that will return the directory separator for the system the code is running on.
I use forward slashes when I write paths for all my apps, and I often use DIRECTORY_SEPARATOR when I am exploding the results of a call that returns a path so that I can ensure I always have the right one to break on.
HTH,
Jc

I would normalize that to forward slashes. Windows accepts forward slashes, and they are the default on *nix systems
print str_replace('\\','/',dirname(__FILE__));

In reality, it doesn't matter... this is because dirname() doesn't necessarily return backslashes: it returns whatever directory separator is used by the OS. That is to say, whatever dirname returns is the separator you should be using anyway.
Other than that, just use forward slashes: PHP will interpret it correctly in Windows and Linux.

It doesn't matter, dirname() always return the path in the OS format.
dirname('c:/x'); // returns 'c:\'
dirname('c:/Temp/x'); // returns 'c:/Temp'
dirname('/x'); // returns '\'

Related

php can't find class [duplicate]

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 "/" ?
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.
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.
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.
Do not use your own folder separators. Always use DIRECTORY_SEPARATOR, because:
In some special cases you really need the correct path delimiter
The OS might handle it correctly, but many 3rd party applications can't and might fail!
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").

Magic constants separator php on iis

I am running PHP on an IIS and I am having trouble with magic constants
I wish to use a framework(YII) which has alot of the following:
require(__DIR__ . '\..\vendor\autoload.php');
Problem is that this returns:
G:\PleskVhosts\***.com\api\web/../vendor/autoload.php
Which causes obvious problems
So I was wondering if there was a way to configure PHP so that the magic constants always return with / (To my understanding IIS/Windows accepts both back-slash and forward-slash)
I don't think it matters if you use / or \ in file paths, Windows usually works with both. It won't work with a single backslash though, you need to double backslash it in your code to escape the backslash if that makes sense. Try running...
var_dump(file_exists(__DIR__ . '/../vendor/autoload.php'));
If it returns true then there shouldn't be a problem. Otherwise double check the file path is actually correct. You can also use realpath to translate the /../ into a full path first.

When to use DIRECTORY_SEPARATOR in PHP code?

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 "/" ?
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.
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.
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.
Do not use your own folder separators. Always use DIRECTORY_SEPARATOR, because:
In some special cases you really need the correct path delimiter
The OS might handle it correctly, but many 3rd party applications can't and might fail!
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").

Does PHP self auto-handle path delimiters in Win and *nix?

Does PHP self auto-handle path delimiters in Win and *nix?
Ex.: converting \ to / ... or \ to \\?
Thanks.
No. But you can use the DIRECTORY_SEPARATOR constant.
Predefined Constants
Your question is not fully clear to me but... I'd aswer "yes, but". "Yes" as your script can do i.e. include "foo/bar/smth.php"; and it will work the same on windows and linux/unix PHPs and you do not need to bother (however if you do include "foo\bar\smth.php"; then it may work on windows (never checked) but will not work on linux/unix, so beware). So filesystem access layer is aware about this and would take care. And "but", becasue if you are also talking about i.e. doing http access (i.e. over HTTP) then "No" as it got nothing do with PHP. Also, I recall some MSIE did convert backslashes for normal slashes, so crap like htt:\\ works, but that's example of extremely wrong approach.

PHP directory separators, forcing forward slash; non-intrusive

Whenever I work with PHP (often) I typically work on a Windows box, however I (try to) develop platform agnostic applications; one major point of issue being the use of directory separators.
As many know, doing any filesystem work in a Windows environment in PHP, you can use forward slashes in lieu of backwards, and PHP sorts it out under the hood. This is all fine when it comes to using string literals to pass a path to fopen() or whatever; but when retrieving paths, be it __FILE__ or expanding with realpath(), the paths retrieved are of course using the OS appropriate slashes. Also, I've noticed some inconsistencies in trailing slashes. Once or twice __DIR__ has appended one (a backslash) and realpath() too (I prefer the trailing slash, but not intermittently)
This is clearly a problem for string comparison, because instead of doing:
compare_somehow('path/to/file.php', __DIR__);
For the sake of reliability, I'm having to go:
compare_somehow('path/to/file.php', rtrim(strtr(__DIR__, '\\', '/'), '/') . '/');
This seems like alot of work. I can drop it into a function, sure; now I'm stuck with an arbitrary function dependency in all my OO code.
I understand that PHP isn't perfect, and accommodations need to be made, but surely there must exist some platform agnostic workaround to force filesystem hits to retrieve forward slashed paths, or at least a non-intrusive way to introduce a class-independent function for this purpose.
Summary question(s):
Is there some magical (though reliable) workaround, hack, or otherwise to force PHP to kick back forward slashed filesystem paths, regardless of the server OS?
I'm going to assume the answer is no to the above, so moving on; what provisions can I make to enforce forward slash (or whatever choice, really) as the directory separator? I'm assuming through the aforementioned filter function, but now where should it go?
Forward slash for everything. Even if the host OS separator is #*&#.
As I commented I can't really see why you would have to do this (I'd be interested in a quick description of the specific problem you are solving), but here is a possible solution using the output of __FILE__ as an example:-
$path = str_replace('\\', '/', __FILE__);
See it working
This will(should?) work regardless of the *slashes returned by the OS (I think).
Unfortunately I'm not aware of "some magical (though reliable) workaround, hack, or otherwise to force PHP to kick back forward slashed filesystem paths, regardless of the server OS" other than this. I imagine it could be wrapped in a helper class, but that still gives you an arbitary dependancy in your code.

Categories