|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2006-05-07 18:08 UTC] k95vz5f02 at sneakemail dot com
Description:
------------
The realpath function doesn't canonicalize the case of the drive letter on Windows (and possibly on certain other platforms).
For example:
realpath('C:\WINDOWS') returns 'C:\WINDOWS'
but realpath('c:\WINDOWS') returns 'c:\WINDOWS'
(note the different case of the 'C:')
Hence comparing realpaths cannot reliably be used to check that two files are the same on Windows.
Reproduce code:
---------------
echo (realpath('C:\WINDOWS')==realpath('c:\WINDOWS')) ? "true" : "false";
Expected result:
----------------
true
Actual result:
--------------
false
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Nov 05 21:00:02 2025 UTC |
On further investigation, realpath doesn't consistently canonicalize the case at all on Windows, I've updated the summary accordingly. First to remember the need for this: the documentation definition for realpath is "Returns canonicalized absolute pathname", and Wikipedia defines canonicalization as "Canonicalization (abbreviated c14n) is the process of converting data that has more than one possible representation into a "standard" canonical representation. This can be done to compare different representations for equivalence (...)" So clearly case should be converted to a standard form on platforms such as Windows that are case-insensitive, and indeed Windows stores the preferred case for every file, for example the standard directory 'C:\Program Files' should be capitalised like that, rather than, e.g. 'C:\program files' or 'C:\PROGRAM FILES', whereas 'C:\WINDOWS' is the preferred case for that directory (on Win XP at least). Tests: 1. realpath("C:\\Program Files") => C:\Program Files 2. realpath("c:\\PrOgRaM fIlEs") => c:\PrOgRaM fIlEs 3. realpath("C:\\program files\\") => C:\program files 4. realpath("C:/program files/") => C:\program files 5. realpath("C:\\pRoGrA~1") => C:\Program Files 6. realpath("c:\\windows") => c:\WINDOWS 7. realpath("c:\\wInDoWs\\DoWnLoAdEd PrOgRaM fIlEs\\") => c:\WINDOWS\DoWnLoAdEd PrOgRaM fIlEs Conclusion: realpath deals with slashes consistently, but it only canonicalizes the case of short filenames (as well as expanding them), not long file names (anything more than 8.3, or with a space, etc); and it never capitalizes the drive letter as it should. A possible solution, if slightly inefficient, would be to convert path components into short (8.3) form then apply the normal realpath logic.Perfect, thanks for fixing this. Tests done to verify, using the windows version linked to above [PHP 5.2.0RC5-dev (cli) (built: Sep 27 2006 00:22:40)]: realpath("C:\\Program Files") => C:\Program Files realpath("c:\\PrOgRaM fIlEs") => C:\Program Files realpath("C:\\program files\\") => C:\Program Files realpath("C:/program files/") => C:\Program Files realpath("C:\\pRoGrA~1") => C:\Program Files realpath("c:\\windows") => C:\WINDOWS realpath("c:\\wInDoWs\\DoWnLoAdEd PrOgRaM fIlEs\\") => C:\WINDOWS\Downloaded Program FilesI don't think this issue is quite fixed yet. php.exe -r "echo realpath('C:\WINDOWS\System32\cmd.exe');" Expected result: ---------------- C:\WINDOWS\System32\cmd.exe Actual result: -------------- C:\WINDOWS\system32\cmd.exe System32 -> system32 This is with the PHP 5.2.14 windows binary on Windows XP SP3.