Skip to content

[Filesystem] Document the Path::join() method #21164

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 1, 2025

Conversation

OskarStark
Copy link
Contributor

Fix #21163

@OskarStark OskarStark changed the base branch from 7.3 to 6.4 July 1, 2025 07:39
@OskarStark OskarStark added this to the 6.4 milestone Jul 1, 2025
@OskarStark OskarStark changed the title Document the Path::join() method Document the Path::join() method Jul 1, 2025
@carsonbot carsonbot changed the title Document the Path::join() method [Filesystem] Document the Path::join() method Jul 1, 2025
@OskarStark OskarStark force-pushed the document-path-join branch from fa81e3d to 0ef903d Compare July 1, 2025 08:20
- Add clear documentation for path joining behavior
- Show examples for common use cases
- Clarify that leading slashes in subsequent arguments are removed
- Include examples for empty parts, trailing slashes, and multiple arguments
@OskarStark OskarStark force-pushed the document-path-join branch from 0ef903d to 9ef642b Compare July 1, 2025 08:22
// => /var/www/vhost/config.ini

echo Path::join('C:\\Program Files', 'PHP', 'php.ini');
// => C:/Program Files/PHP/php.ini
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks correct because the join() method calls canonicalize() and this turns any slashes into forward slashes. See https://github.com/symfony/symfony/blob/01f0faf9c332bda3d63e4dce05e4deaf8491cf2b/src/Symfony/Component/Filesystem/Path.php#L49-L66

My question though: is the resulting path fully valid on Windows?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the resulting path is fully valid on Windows. Windows accepts both forward slashes (/) and backslashes () as path separators in most contexts, including:

  • File operations in PHP (fopen, file_get_contents, etc.)
  • Command line operations
  • Most Windows APIs

The canonicalization to forward slashes is actually a best practice for cross-platform compatibility. PHP's file system functions handle forward slashes correctly on Windows, automatically converting them when needed for the underlying Windows API calls.

The only exception might be when passing paths to external Windows programs that specifically require backslashes, but this is rare and can be handled with Path::normalize() when needed.

Here are some references:

  1. PHP Manual on Windows file paths: https://www.php.net/manual/en/wrappers.file.php

    "On Windows, both slash (/) and backslash () are used as directory separator character."

  2. Microsoft Documentation: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file

    "File I/O functions in the Windows API convert "/" to "" as part of converting the name to an NT-style name"

  3. PHP source code (main/streams/plain_wrapper.c): PHP internally handles the conversion when needed for Windows file operations.

You can test this yourself on Windows:

// Both work identically on Windows:
file_exists("C:/Windows/System32");  // true
file_exists("C:\\Windows\\System32"); // true

@OskarStark OskarStark requested a review from javiereguiluz July 1, 2025 09:19
@javiereguiluz javiereguiluz merged commit cb2294e into symfony:6.4 Jul 1, 2025
3 checks passed
@javiereguiluz
Copy link
Member

Thanks Oskar!

I did some mionor tweakes while merging (6276aca) to mention that both types of slashes work on Windows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Path::join() is not documented
3 participants