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,16 +19,23 @@ 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
}
@@ -44,6 +52,9 @@ endpoint for filesystem operations::
44
52
string, an array or any object implementing :phpclass: `Traversable ` as
45
53
the target argument.
46
54
55
+ Filesystem
56
+ ----------
57
+
47
58
``mkdir ``
48
59
~~~~~~~~~
49
60
@@ -236,6 +247,11 @@ Its behavior is the following::
236
247
* if ``$path `` does not exist, it returns null.
237
248
* if ``$path `` exists, it returns its absolute fully resolved final version.
238
249
250
+ .. note ::
251
+
252
+ If you wish to canonicalize the path without checking its existence, you can
253
+ use :method: `Symfony\\ Component\\ Filesystem\\ Path::canonicalize ` instead.
254
+
239
255
``makePathRelative ``
240
256
~~~~~~~~~~~~~~~~~~~~
241
257
@@ -315,6 +331,191 @@ contents at the end of some file::
315
331
If either the file or its containing directory doesn't exist, this method
316
332
creates them before appending the contents.
317
333
334
+ Path
335
+ ----
336
+
337
+ .. versionadded :: 5.4
338
+
339
+ The :class: `Symfony\\ Component\\ Filesystem\\ Path ` class was introduced in Symfony 5.4.
340
+
341
+ Dealing with file paths usually involves some difficulties:
342
+
343
+ - System Heterogeneity: file paths look different on different platforms. UNIX
344
+ file paths start with a slash ("/"), while Windows file paths start with a
345
+ system drive ("C:"). UNIX uses forward slashes, while Windows uses backslashes
346
+ by default ("").
347
+ - Absolute/relative paths: web applications frequently need to deal with absolute
348
+ and relative paths. Converting one to the other properly is tricky and
349
+ repetitive.
350
+
351
+ :class: `Symfony\\ Component\\ Filesystem\\ Path ` provides utility methods to tackle
352
+ those issues.
353
+
354
+ Canonicalization
355
+ ~~~~~~~~~~~~~~~~
356
+
357
+ *Canonicalization * is the transformation of a path into a normalized (the
358
+ "canonical") format. You can canonicalize a path with :method: `Symfony\\ Component\\ Filesystem\\ Path::canonicalize `::
359
+
360
+ echo Path::canonicalize('/var/www/vhost/webmozart/../config.ini');
361
+ // => /var/www/vhost/config.ini
362
+
363
+ The following modifications happen during canonicalization:
364
+
365
+ - "." segments are removed;
366
+ - ".." segments are resolved;
367
+ - backslashes ("\" ) are converted into forward slashes ("/");
368
+ - root paths ("/" and "C:/") always terminate with a slash;
369
+ - non-root paths never terminate with a slash;
370
+ - schemes (such as "phar://") are kept;
371
+ - replace "~" with the user's home directory.
372
+
373
+ You can pass absolute paths and relative paths to :method: `Symfony\\ Component\\ Filesystem\\ Path::canonicalize `.
374
+ When a relative path is passed, ".." segments at the beginning of the path are
375
+ kept::
376
+
377
+ echo Path::canonicalize('../uploads/../config/config.yml');
378
+ // => ../config/config.yml
379
+
380
+ Malformed paths are returned unchanged::
381
+
382
+ echo Path::canonicalize('C:Programs/PHP/php.ini');
383
+ // => C:Programs/PHP/php.ini
384
+
385
+ Converting Absolute/Relative Paths
386
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
387
+
388
+ Absolute/relative paths can be converted with the methods
389
+ :method: `Symfony\\ Component\\ Filesystem\\ Path::makeAbsolute `
390
+ and :method: `Symfony\\ Component\\ Filesystem\\ Path::makeRelative `.
391
+
392
+ :method: `Symfony\\ Component\\ Filesystem\\ Path::makeAbsolute ` expects a relative
393
+ path and a base path to base that relative path upon::
394
+
395
+ echo Path::makeAbsolute('config/config.yml', '/var/www/project');
396
+ // => /var/www/project/config/config.yml
397
+
398
+ If an absolute path is passed in the first argument, the absolute path is
399
+ returned unchanged::
400
+
401
+ echo Path::makeAbsolute('/usr/share/lib/config.ini', '/var/www/project');
402
+ // => /usr/share/lib/config.ini
403
+
404
+ The method resolves ".." segments, if there are any::
405
+
406
+ echo Path::makeAbsolute('../config/config.yml', '/var/www/project/uploads');
407
+ // => /var/www/project/config/config.yml
408
+
409
+ This method is very useful if you want to be able to accept relative paths (for
410
+ example, relative to the root directory of your project) and absolute paths at
411
+ the same time.
412
+
413
+ :method: `Symfony\\ Component\\ Filesystem\\ Path::makeRelative ` is the inverse
414
+ operation to :method: `Symfony\\ Component\\ Filesystem\\ Path::makeAbsolute `::
415
+
416
+ echo Path::makeRelative('/var/www/project/config/config.yml', '/var/www/project');
417
+ // => config/config.yml
418
+
419
+ If the path is not within the base path, the method will prepend ".." segments
420
+ as necessary::
421
+
422
+ echo Path::makeRelative('/var/www/project/config/config.yml', '/var/www/project/uploads');
423
+ // => ../config/config.yml
424
+
425
+ Use :method: `Symfony\\ Component\\ Filesystem\\ Path::makeAbsolute ` and
426
+ :method: `Symfony\\ Component\\ Filesystem\\ Path::makeRelative ` to check whether a
427
+ path is absolute or relative::
428
+
429
+ Path::isAbsolute('C:\Programs\PHP\php.ini')
430
+ // => true
431
+
432
+ All four methods internally canonicalize the passed path.
433
+
434
+ Finding Longest Common Base Paths
435
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
436
+
437
+ When you store absolute file paths on the file system, this leads to a lot of
438
+ duplicated information::
439
+
440
+ return array(
441
+ '/var/www/vhosts/project/httpdocs/config/config.yml',
442
+ '/var/www/vhosts/project/httpdocs/config/routing.yml',
443
+ '/var/www/vhosts/project/httpdocs/config/services.yml',
444
+ '/var/www/vhosts/project/httpdocs/images/banana.gif',
445
+ '/var/www/vhosts/project/httpdocs/uploads/images/nicer-banana.gif',
446
+ );
447
+
448
+ Especially when storing many paths, the amount of duplicated information is
449
+ noticeable. You can use :method: `Symfony\\ Component\\ Filesystem\\ Path::getLongestCommonBasePath `
450
+ to check a list of paths for a common base path::
451
+
452
+ $paths = array(
453
+ '/var/www/vhosts/project/httpdocs/config/config.yml',
454
+ '/var/www/vhosts/project/httpdocs/config/routing.yml',
455
+ '/var/www/vhosts/project/httpdocs/config/services.yml',
456
+ '/var/www/vhosts/project/httpdocs/images/banana.gif',
457
+ '/var/www/vhosts/project/httpdocs/uploads/images/nicer-banana.gif',
458
+ );
459
+
460
+ Path::getLongestCommonBasePath($paths);
461
+ // => /var/www/vhosts/project/httpdocs
462
+
463
+ Use this path together with :method: `Symfony\\ Component\\ Filesystem\\ Path::makeRelative `
464
+ to shorten the stored paths::
465
+
466
+ $bp = '/var/www/vhosts/project/httpdocs';
467
+
468
+ return array(
469
+ $bp.'/config/config.yml',
470
+ $bp.'/config/routing.yml',
471
+ $bp.'/config/services.yml',
472
+ $bp.'/images/banana.gif',
473
+ $bp.'/uploads/images/nicer-banana.gif',
474
+ );
475
+
476
+ :method: `Symfony\\ Component\\ Filesystem\\ Path::getLongestCommonBasePath ` always
477
+ returns canonical paths.
478
+
479
+ Use :method: `Symfony\\ Component\\ Filesystem\\ Path::isBasePath ` to test whether a
480
+ path is a base path of another path::
481
+
482
+ Path::isBasePath("/var/www", "/var/www/project");
483
+ // => true
484
+
485
+ Path::isBasePath("/var/www", "/var/www/project/..");
486
+ // => true
487
+
488
+ Path::isBasePath("/var/www", "/var/www/project/../..");
489
+ // => false
490
+
491
+ Finding Directories/Root Directories
492
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
493
+
494
+ PHP offers the function :phpfunction: `dirname ` to obtain the directory path of a
495
+ file path. This method has a few quirks::
496
+
497
+ - `dirname() ` does not accept backslashes on UNIX
498
+ - `dirname("C:/Programs") ` returns "C:", not "C:/"
499
+ - `dirname("C:/") ` returns ".", not "C:/"
500
+ - `dirname("C:") ` returns ".", not "C:/"
501
+ - `dirname("Programs") ` returns ".", not ""
502
+ - `dirname() ` does not canonicalize the result
503
+
504
+ :method: `Symfony\\ Component\\ Filesystem\\ Path::getDirectory ` fixes these
505
+ shortcomings::
506
+
507
+ echo Path::getDirectory("C:\Programs");
508
+ // => C:/
509
+
510
+ Additionally, you can use :method: `Symfony\\ Component\\ Filesystem\\ Path::getRoot `
511
+ to obtain the root of a path::
512
+
513
+ echo Path::getRoot("/etc/apache2/sites-available");
514
+ // => /
515
+
516
+ echo Path::getRoot("C:\Programs\Apache\Config");
517
+ // => C:/
518
+
318
519
Error Handling
319
520
--------------
320
521
0 commit comments