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
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions components/filesystem.rst
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,44 @@ Malformed paths are returned unchanged::
echo Path::canonicalize('C:Programs/PHP/php.ini');
// => C:Programs/PHP/php.ini

Joining Paths
~~~~~~~~~~~~~

The :method:`Symfony\\Component\\Filesystem\\Path::join` method concatenates
the given paths and normalizes separators. It's a cleaner alternative to
string concatenation for building file paths::

echo Path::join('/var/www', 'vhost', 'config.ini');
// => /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


The method handles multiple scenarios correctly:

- Empty parts are ignored::

echo Path::join('/var/www', '', 'config.ini');
// => /var/www/config.ini

- Leading slashes in subsequent arguments are removed::

echo Path::join('/var/www', '/etc', 'config.ini');
// => /var/www/etc/config.ini

- Trailing slashes are preserved only for root paths::

echo Path::join('/var/www', 'vhost/');
// => /var/www/vhost

echo Path::join('/', '');
// => /

- Works with any number of arguments::

echo Path::join('/var', 'www', 'vhost', 'symfony', 'config', 'config.ini');
// => /var/www/vhost/symfony/config/config.ini

Converting Absolute/Relative Paths
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down