44The Filesystem Component
55========================
66
7- The Filesystem component provides basic utilities for the filesystem.
7+ The Filesystem component provides basic utilities for the filesystem and
8+ paths manipulation.
89
910Installation
1011------------
@@ -18,20 +19,30 @@ Installation
1819Usage
1920-----
2021
21- The :class: `Symfony\\ Component\\ Filesystem\\ Filesystem ` class is the unique
22- endpoint for filesystem operations::
22+ The component contains two classes:
23+
24+ - The :class: `Symfony\\ Component\\ Filesystem\\ Filesystem ` which provides utilities
25+ for filesystem write operations.
26+ - The :class: `Symfony\\ Component\\ Filesystem\\ Path ` which provides utilities
27+ for paths manipulation.::
2328
2429 use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
2530 use Symfony\Component\Filesystem\Filesystem;
31+ use Symfony\Component\Filesystem\Path;
2632
2733 $filesystem = new Filesystem();
2834
2935 try {
30- $filesystem->mkdir(sys_get_temp_dir().'/'.random_int(0, 1000));
36+ $filesystem->mkdir(
37+ Path::normalize(sys_get_temp_dir().'/'.random_int(0, 1000)),
38+ );
3139 } catch (IOExceptionInterface $exception) {
3240 echo "An error occurred while creating your directory at ".$exception->getPath();
3341 }
3442
43+ Filesystem
44+ ----------
45+
3546``mkdir ``
3647~~~~~~~~~
3748
@@ -224,6 +235,11 @@ Its behavior is the following::
224235 * if ``$path `` does not exist, it returns null.
225236 * if ``$path `` exists, it returns its absolute fully resolved final version.
226237
238+ .. note ::
239+
240+ If you wish to canonicalize the path without checking its existence, you can
241+ use :method: `Symfony\\ Component\\ Filesystem\\ Path::canonicalize ` method instead.
242+
227243``makePathRelative ``
228244~~~~~~~~~~~~~~~~~~~~
229245
@@ -309,6 +325,192 @@ creates them before appending the contents.
309325
310326 The third argument of ``appendToFile() `` was introduced in Symfony 5.4.
311327
328+ Path
329+ ----
330+
331+ .. versionadded :: 5.4
332+
333+ The :class: `Symfony\\ Component\\ Filesystem\\ Path ` class was introduced in Symfony 5.4.
334+
335+ Dealing with file paths usually involves some difficulties:
336+
337+ - System Heterogeneity: file paths look different on different platforms. UNIX
338+ file paths start with a slash ("/"), while Windows file paths start with a
339+ system drive ("C:"). UNIX uses forward slashes, while Windows uses backslashes
340+ by default ("").
341+ - Absolute/relative paths: web applications frequently need to deal with absolute
342+ and relative paths. Converting one to the other properly is tricky and
343+ repetitive.
344+
345+ :class: `Symfony\\ Component\\ Filesystem\\ Path ` provides utility methods to tackle
346+ those issues.
347+
348+ Canonicalization
349+ ~~~~~~~~~~~~~~~~
350+
351+ Returns the shortest path name equivalent to the given path. It applies the
352+ following rules iteratively until no further processing can be done:
353+
354+ - "." segments are removed;
355+ - ".." segments are resolved;
356+ - backslashes ("\" ) are converted into forward slashes ("/");
357+ - root paths ("/" and "C:/") always terminate with a slash;
358+ - non-root paths never terminate with a slash;
359+ - schemes (such as "phar://") are kept;
360+ - replace "~" with the user's home directory.
361+
362+ You can canonicalize a path with :method: `Symfony\\ Component\\ Filesystem\\ Path::canonicalize `::
363+
364+ echo Path::canonicalize('/var/www/vhost/webmozart/../config.ini');
365+ // => /var/www/vhost/config.ini
366+
367+ You can pass absolute paths and relative paths to the
368+ :method: `Symfony\\ Component\\ Filesystem\\ Path::canonicalize ` method. When a
369+ relative path is passed, ".." segments at the beginning of the path are kept::
370+
371+ echo Path::canonicalize('../uploads/../config/config.yaml');
372+ // => ../config/config.yaml
373+
374+ Malformed paths are returned unchanged::
375+
376+ echo Path::canonicalize('C:Programs/PHP/php.ini');
377+ // => C:Programs/PHP/php.ini
378+
379+ Converting Absolute/Relative Paths
380+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
381+
382+ Absolute/relative paths can be converted with the methods
383+ :method: `Symfony\\ Component\\ Filesystem\\ Path::makeAbsolute `
384+ and :method: `Symfony\\ Component\\ Filesystem\\ Path::makeRelative `.
385+
386+ :method: `Symfony\\ Component\\ Filesystem\\ Path::makeAbsolute ` method expects a
387+ relative path and a base path to base that relative path upon::
388+
389+ echo Path::makeAbsolute('config/config.yaml', '/var/www/project');
390+ // => /var/www/project/config/config.yaml
391+
392+ If an absolute path is passed in the first argument, the absolute path is
393+ returned unchanged::
394+
395+ echo Path::makeAbsolute('/usr/share/lib/config.ini', '/var/www/project');
396+ // => /usr/share/lib/config.ini
397+
398+ The method resolves ".." segments, if there are any::
399+
400+ echo Path::makeAbsolute('../config/config.yaml', '/var/www/project/uploads');
401+ // => /var/www/project/config/config.yaml
402+
403+ This method is very useful if you want to be able to accept relative paths (for
404+ example, relative to the root directory of your project) and absolute paths at
405+ the same time.
406+
407+ :method: `Symfony\\ Component\\ Filesystem\\ Path::makeRelative ` is the inverse
408+ operation to :method: `Symfony\\ Component\\ Filesystem\\ Path::makeAbsolute `::
409+
410+ echo Path::makeRelative('/var/www/project/config/config.yaml', '/var/www/project');
411+ // => config/config.yaml
412+
413+ If the path is not within the base path, the method will prepend ".." segments
414+ as necessary::
415+
416+ echo Path::makeRelative('/var/www/project/config/config.yaml', '/var/www/project/uploads');
417+ // => ../config/config.yaml
418+
419+ Use :method: `Symfony\\ Component\\ Filesystem\\ Path::makeAbsolute ` and
420+ :method: `Symfony\\ Component\\ Filesystem\\ Path::makeRelative ` to check whether a
421+ path is absolute or relative::
422+
423+ Path::isAbsolute('C:\Programs\PHP\php.ini')
424+ // => true
425+
426+ All four methods internally canonicalize the passed path.
427+
428+ Finding Longest Common Base Paths
429+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
430+
431+ When you store absolute file paths on the file system, this leads to a lot of
432+ duplicated information::
433+
434+ return [
435+ '/var/www/vhosts/project/httpdocs/config/config.yaml',
436+ '/var/www/vhosts/project/httpdocs/config/routing.yaml',
437+ '/var/www/vhosts/project/httpdocs/config/services.yaml',
438+ '/var/www/vhosts/project/httpdocs/images/banana.gif',
439+ '/var/www/vhosts/project/httpdocs/uploads/images/nicer-banana.gif',
440+ ];
441+
442+ Especially when storing many paths, the amount of duplicated information is
443+ noticeable. You can use :method: `Symfony\\ Component\\ Filesystem\\ Path::getLongestCommonBasePath `
444+ to check a list of paths for a common base path::
445+
446+ $paths = [
447+ '/var/www/vhosts/project/httpdocs/config/config.yaml',
448+ '/var/www/vhosts/project/httpdocs/config/routing.yaml',
449+ '/var/www/vhosts/project/httpdocs/config/services.yaml',
450+ '/var/www/vhosts/project/httpdocs/images/banana.gif',
451+ '/var/www/vhosts/project/httpdocs/uploads/images/nicer-banana.gif',
452+ ];
453+
454+ Path::getLongestCommonBasePath($paths);
455+ // => /var/www/vhosts/project/httpdocs
456+
457+ Use this path together with :method: `Symfony\\ Component\\ Filesystem\\ Path::makeRelative `
458+ to shorten the stored paths::
459+
460+ $bp = '/var/www/vhosts/project/httpdocs';
461+
462+ return [
463+ $bp.'/config/config.yaml',
464+ $bp.'/config/routing.yaml',
465+ $bp.'/config/services.yaml',
466+ $bp.'/images/banana.gif',
467+ $bp.'/uploads/images/nicer-banana.gif',
468+ ];
469+
470+ :method: `Symfony\\ Component\\ Filesystem\\ Path::getLongestCommonBasePath ` always
471+ returns canonical paths.
472+
473+ Use :method: `Symfony\\ Component\\ Filesystem\\ Path::isBasePath ` to test whether a
474+ path is a base path of another path::
475+
476+ Path::isBasePath("/var/www", "/var/www/project");
477+ // => true
478+
479+ Path::isBasePath("/var/www", "/var/www/project/..");
480+ // => true
481+
482+ Path::isBasePath("/var/www", "/var/www/project/../..");
483+ // => false
484+
485+ Finding Directories/Root Directories
486+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
487+
488+ PHP offers the function :phpfunction: `dirname ` to obtain the directory path of a
489+ file path. This method has a few quirks::
490+
491+ - `dirname() ` does not accept backslashes on UNIX
492+ - `dirname("C:/Programs") ` returns "C:", not "C:/"
493+ - `dirname("C:/") ` returns ".", not "C:/"
494+ - `dirname("C:") ` returns ".", not "C:/"
495+ - `dirname("Programs") ` returns ".", not ""
496+ - `dirname() ` does not canonicalize the result
497+
498+ :method: `Symfony\\ Component\\ Filesystem\\ Path::getDirectory ` fixes these
499+ shortcomings::
500+
501+ echo Path::getDirectory("C:\Programs");
502+ // => C:/
503+
504+ Additionally, you can use :method: `Symfony\\ Component\\ Filesystem\\ Path::getRoot `
505+ to obtain the root of a path::
506+
507+ echo Path::getRoot("/etc/apache2/sites-available");
508+ // => /
509+
510+ echo Path::getRoot("C:\Programs\Apache\Config");
511+ // => C:/
512+ >>>>>>> a992f6342 ([Filesystem] Add documentation for the Path class)
513+
312514Error Handling
313515--------------
314516
0 commit comments