44The Filesystem Component
55========================
66
7- The Filesystem component provides basic utilities for the filesystem.
7+ The Filesystem component provides platform-independent utilities for
8+ filesystem operations and for file/directory paths manipulation.
89
910Installation
1011------------
@@ -18,20 +19,26 @@ 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 main classes called :class: `Symfony\\ Component\\ Filesystem\\ Filesystem `
23+ and :class: ` Symfony \\ Component \\ Filesystem \\ Path ` ::
2324
2425 use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
2526 use Symfony\Component\Filesystem\Filesystem;
27+ use Symfony\Component\Filesystem\Path;
2628
2729 $filesystem = new Filesystem();
2830
2931 try {
30- $filesystem->mkdir(sys_get_temp_dir().'/'.random_int(0, 1000));
32+ $filesystem->mkdir(
33+ Path::normalize(sys_get_temp_dir().'/'.random_int(0, 1000)),
34+ );
3135 } catch (IOExceptionInterface $exception) {
3236 echo "An error occurred while creating your directory at ".$exception->getPath();
3337 }
3438
39+ Filesystem Utilities
40+ --------------------
41+
3542``mkdir ``
3643~~~~~~~~~
3744
@@ -224,6 +231,11 @@ Its behavior is the following::
224231 * if ``$path `` does not exist, it returns null.
225232 * if ``$path `` exists, it returns its absolute fully resolved final version.
226233
234+ .. note ::
235+
236+ If you wish to canonicalize the path without checking its existence, you can
237+ use :method: `Symfony\\ Component\\ Filesystem\\ Path::canonicalize ` method instead.
238+
227239``makePathRelative ``
228240~~~~~~~~~~~~~~~~~~~~
229241
@@ -301,6 +313,186 @@ contents at the end of some file::
301313If either the file or its containing directory doesn't exist, this method
302314creates them before appending the contents.
303315
316+ Path Manipulation Utilities
317+ ---------------------------
318+
319+ Dealing with file paths usually involves some difficulties:
320+
321+ - Platform differences: file paths look different on different platforms. UNIX
322+ file paths start with a slash ("/"), while Windows file paths start with a
323+ system drive ("C:"). UNIX uses forward slashes, while Windows uses backslashes
324+ by default.
325+ - Absolute/relative paths: web applications frequently need to deal with absolute
326+ and relative paths. Converting one to the other properly is tricky and repetitive.
327+
328+ :class: `Symfony\\ Component\\ Filesystem\\ Path ` provides utility methods to tackle
329+ those issues.
330+
331+ Canonicalization
332+ ~~~~~~~~~~~~~~~~
333+
334+ Returns the shortest path name equivalent to the given path. It applies the
335+ following rules iteratively until no further processing can be done:
336+
337+ - "." segments are removed;
338+ - ".." segments are resolved;
339+ - backslashes ("\" ) are converted into forward slashes ("/");
340+ - root paths ("/" and "C:/") always terminate with a slash;
341+ - non-root paths never terminate with a slash;
342+ - schemes (such as "phar://") are kept;
343+ - replace "~" with the user's home directory.
344+
345+ You can canonicalize a path with :method: `Symfony\\ Component\\ Filesystem\\ Path::canonicalize `::
346+
347+ echo Path::canonicalize('/var/www/vhost/webmozart/../config.ini');
348+ // => /var/www/vhost/config.ini
349+
350+ You can pass absolute paths and relative paths to the
351+ :method: `Symfony\\ Component\\ Filesystem\\ Path::canonicalize ` method. When a
352+ relative path is passed, ".." segments at the beginning of the path are kept::
353+
354+ echo Path::canonicalize('../uploads/../config/config.yaml');
355+ // => ../config/config.yaml
356+
357+ Malformed paths are returned unchanged::
358+
359+ echo Path::canonicalize('C:Programs/PHP/php.ini');
360+ // => C:Programs/PHP/php.ini
361+
362+ Converting Absolute/Relative Paths
363+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
364+
365+ Absolute/relative paths can be converted with the methods
366+ :method: `Symfony\\ Component\\ Filesystem\\ Path::makeAbsolute `
367+ and :method: `Symfony\\ Component\\ Filesystem\\ Path::makeRelative `.
368+
369+ :method: `Symfony\\ Component\\ Filesystem\\ Path::makeAbsolute ` method expects a
370+ relative path and a base path to base that relative path upon::
371+
372+ echo Path::makeAbsolute('config/config.yaml', '/var/www/project');
373+ // => /var/www/project/config/config.yaml
374+
375+ If an absolute path is passed in the first argument, the absolute path is
376+ returned unchanged::
377+
378+ echo Path::makeAbsolute('/usr/share/lib/config.ini', '/var/www/project');
379+ // => /usr/share/lib/config.ini
380+
381+ The method resolves ".." segments, if there are any::
382+
383+ echo Path::makeAbsolute('../config/config.yaml', '/var/www/project/uploads');
384+ // => /var/www/project/config/config.yaml
385+
386+ This method is very useful if you want to be able to accept relative paths (for
387+ example, relative to the root directory of your project) and absolute paths at
388+ the same time.
389+
390+ :method: `Symfony\\ Component\\ Filesystem\\ Path::makeRelative ` is the inverse
391+ operation to :method: `Symfony\\ Component\\ Filesystem\\ Path::makeAbsolute `::
392+
393+ echo Path::makeRelative('/var/www/project/config/config.yaml', '/var/www/project');
394+ // => config/config.yaml
395+
396+ If the path is not within the base path, the method will prepend ".." segments
397+ as necessary::
398+
399+ echo Path::makeRelative('/var/www/project/config/config.yaml', '/var/www/project/uploads');
400+ // => ../config/config.yaml
401+
402+ Use :method: `Symfony\\ Component\\ Filesystem\\ Path::makeAbsolute ` and
403+ :method: `Symfony\\ Component\\ Filesystem\\ Path::makeRelative ` to check whether a
404+ path is absolute or relative::
405+
406+ Path::isAbsolute('C:\Programs\PHP\php.ini')
407+ // => true
408+
409+ All four methods internally canonicalize the passed path.
410+
411+ Finding Longest Common Base Paths
412+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
413+
414+ When you store absolute file paths on the file system, this leads to a lot of
415+ duplicated information::
416+
417+ return [
418+ '/var/www/vhosts/project/httpdocs/config/config.yaml',
419+ '/var/www/vhosts/project/httpdocs/config/routing.yaml',
420+ '/var/www/vhosts/project/httpdocs/config/services.yaml',
421+ '/var/www/vhosts/project/httpdocs/images/banana.gif',
422+ '/var/www/vhosts/project/httpdocs/uploads/images/nicer-banana.gif',
423+ ];
424+
425+ Especially when storing many paths, the amount of duplicated information is
426+ noticeable. You can use :method: `Symfony\\ Component\\ Filesystem\\ Path::getLongestCommonBasePath `
427+ to check a list of paths for a common base path::
428+
429+ $paths = [
430+ '/var/www/vhosts/project/httpdocs/config/config.yaml',
431+ '/var/www/vhosts/project/httpdocs/config/routing.yaml',
432+ '/var/www/vhosts/project/httpdocs/config/services.yaml',
433+ '/var/www/vhosts/project/httpdocs/images/banana.gif',
434+ '/var/www/vhosts/project/httpdocs/uploads/images/nicer-banana.gif',
435+ ];
436+
437+ Path::getLongestCommonBasePath($paths);
438+ // => /var/www/vhosts/project/httpdocs
439+
440+ Use this path together with :method: `Symfony\\ Component\\ Filesystem\\ Path::makeRelative `
441+ to shorten the stored paths::
442+
443+ $bp = '/var/www/vhosts/project/httpdocs';
444+
445+ return [
446+ $bp.'/config/config.yaml',
447+ $bp.'/config/routing.yaml',
448+ $bp.'/config/services.yaml',
449+ $bp.'/images/banana.gif',
450+ $bp.'/uploads/images/nicer-banana.gif',
451+ ];
452+
453+ :method: `Symfony\\ Component\\ Filesystem\\ Path::getLongestCommonBasePath ` always
454+ returns canonical paths.
455+
456+ Use :method: `Symfony\\ Component\\ Filesystem\\ Path::isBasePath ` to test whether a
457+ path is a base path of another path::
458+
459+ Path::isBasePath("/var/www", "/var/www/project");
460+ // => true
461+
462+ Path::isBasePath("/var/www", "/var/www/project/..");
463+ // => true
464+
465+ Path::isBasePath("/var/www", "/var/www/project/../..");
466+ // => false
467+
468+ Finding Directories/Root Directories
469+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
470+
471+ PHP offers the function :phpfunction: `dirname ` to obtain the directory path of a
472+ file path. This method has a few quirks::
473+
474+ - `dirname() ` does not accept backslashes on UNIX
475+ - `dirname("C:/Programs") ` returns "C:", not "C:/"
476+ - `dirname("C:/") ` returns ".", not "C:/"
477+ - `dirname("C:") ` returns ".", not "C:/"
478+ - `dirname("Programs") ` returns ".", not ""
479+ - `dirname() ` does not canonicalize the result
480+
481+ :method: `Symfony\\ Component\\ Filesystem\\ Path::getDirectory ` fixes these
482+ shortcomings::
483+
484+ echo Path::getDirectory("C:\Programs");
485+ // => C:/
486+
487+ Additionally, you can use :method: `Symfony\\ Component\\ Filesystem\\ Path::getRoot `
488+ to obtain the root of a path::
489+
490+ echo Path::getRoot("/etc/apache2/sites-available");
491+ // => /
492+
493+ echo Path::getRoot("C:\Programs\Apache\Config");
494+ // => C:/
495+
304496Error Handling
305497--------------
306498
0 commit comments