4
4
The Filesystem Component
5
5
========================
6
6
7
- The Filesystem component provides basic utilities for the filesystem.
7
+ The Filesystem component provides basic utilities for the filesystem and
8
+ paths manipulation.
8
9
9
10
Installation
10
11
------------
@@ -18,20 +19,30 @@ Installation
18
19
Usage
19
20
-----
20
21
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.::
23
28
24
29
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
25
30
use Symfony\Component\Filesystem\Filesystem;
31
+ use Symfony\Component\Filesystem\Path;
26
32
27
33
$filesystem = new Filesystem();
28
34
29
35
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
+ );
31
39
} catch (IOExceptionInterface $exception) {
32
40
echo "An error occurred while creating your directory at ".$exception->getPath();
33
41
}
34
42
43
+ Filesystem
44
+ ----------
45
+
35
46
``mkdir ``
36
47
~~~~~~~~~
37
48
@@ -224,6 +235,11 @@ Its behavior is the following::
224
235
* if ``$path `` does not exist, it returns null.
225
236
* if ``$path `` exists, it returns its absolute fully resolved final version.
226
237
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
+
227
243
``makePathRelative ``
228
244
~~~~~~~~~~~~~~~~~~~~
229
245
@@ -309,6 +325,192 @@ creates them before appending the contents.
309
325
310
326
The third argument of ``appendToFile() `` was introduced in Symfony 5.4.
311
327
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
+
312
514
Error Handling
313
515
--------------
314
516
0 commit comments