4
4
The Filesystem Component
5
5
========================
6
6
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.
8
9
9
10
Installation
10
11
------------
@@ -18,20 +19,26 @@ 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 main classes called :class: `Symfony\\ Component\\ Filesystem\\ Filesystem `
23
+ and :class: ` Symfony \\ Component \\ Filesystem \\ Path ` ::
23
24
24
25
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
25
26
use Symfony\Component\Filesystem\Filesystem;
27
+ use Symfony\Component\Filesystem\Path;
26
28
27
29
$filesystem = new Filesystem();
28
30
29
31
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
+ );
31
35
} catch (IOExceptionInterface $exception) {
32
36
echo "An error occurred while creating your directory at ".$exception->getPath();
33
37
}
34
38
39
+ Filesystem Utilities
40
+ --------------------
41
+
35
42
``mkdir ``
36
43
~~~~~~~~~
37
44
@@ -224,6 +231,11 @@ Its behavior is the following::
224
231
* if ``$path `` does not exist, it returns null.
225
232
* if ``$path `` exists, it returns its absolute fully resolved final version.
226
233
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
+
227
239
``makePathRelative ``
228
240
~~~~~~~~~~~~~~~~~~~~
229
241
@@ -301,6 +313,186 @@ contents at the end of some file::
301
313
If either the file or its containing directory doesn't exist, this method
302
314
creates them before appending the contents.
303
315
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
+
304
496
Error Handling
305
497
--------------
306
498
0 commit comments