Patched to Drupal 8.4.8 level. See https://www.drupal.org/sa-core-2018-004 and patch...
[yaffs-website] / vendor / webmozart / path-util / docs / usage.md
1 Painfree Handling of File Paths
2 ===============================
3
4 Dealing with file paths usually involves some difficulties:
5  
6 * **System Heterogeneity**: File paths look different on different platforms. 
7   UNIX file paths start with a slash ("/"), while Windows file paths start with
8   a system drive ("C:"). UNIX uses forward slashes, while Windows uses 
9   backslashes by default ("\").
10   
11 * **Absolute/Relative Paths**: Web applications frequently need to deal with
12   absolute and relative paths. Converting one to the other properly is tricky
13   and repetitive.
14
15 This package provides few, but robust utility methods to simplify your life
16 when dealing with file paths.
17
18 Canonicalization
19 ----------------
20
21 *Canonicalization* is the transformation of a path into a normalized (the
22 "canonical") format. You can canonicalize a path with `Path::canonicalize()`:
23
24 ```php
25 echo Path::canonicalize('/var/www/vhost/webmozart/../config.ini');
26 // => /var/www/vhost/config.ini
27 ```
28
29 The following modifications happen during canonicalization:
30
31 * "." segments are removed;
32 * ".." segments are resolved;
33 * backslashes ("\") are converted into forward slashes ("/");
34 * root paths ("/" and "C:/") always terminate with a slash;
35 * non-root paths never terminate with a slash;
36 * schemes (such as "phar://") are kept;
37 * replace "~" with the user's home directory.
38
39 You can pass absolute paths and relative paths to `canonicalize()`. When a
40 relative path is passed, ".." segments at the beginning of the path are kept:
41
42 ```php
43 echo Path::canonicalize('../uploads/../config/config.yml');
44 // => ../config/config.yml
45 ```
46
47 Malformed paths are returned unchanged:
48
49 ```php
50 echo Path::canonicalize('C:Programs/PHP/php.ini');
51 // => C:Programs/PHP/php.ini
52 ```
53
54 Converting Absolute/Relative Paths
55 ----------------------------------
56
57 Absolute/relative paths can be converted with the methods `Path::makeAbsolute()`
58 and `Path::makeRelative()`.
59
60 `makeAbsolute()` expects a relative path and a base path to base that relative
61 path upon:
62
63 ```php
64 echo Path::makeAbsolute('config/config.yml', '/var/www/project');
65 // => /var/www/project/config/config.yml
66 ```
67
68 If an absolute path is passed in the first argument, the absolute path is
69 returned unchanged:
70
71 ```php
72 echo Path::makeAbsolute('/usr/share/lib/config.ini', '/var/www/project');
73 // => /usr/share/lib/config.ini
74 ```
75
76 The method resolves ".." segments, if there are any:
77
78 ```php
79 echo Path::makeAbsolute('../config/config.yml', '/var/www/project/uploads');
80 // => /var/www/project/config/config.yml
81 ```
82
83 This method is very useful if you want to be able to accept relative paths (for 
84 example, relative to the root directory of your project) and absolute paths at
85 the same time.
86
87 `makeRelative()` is the inverse operation to `makeAbsolute()`:
88
89 ```php
90 echo Path::makeRelative('/var/www/project/config/config.yml', '/var/www/project');
91 // => config/config.yml
92 ```
93
94 If the path is not within the base path, the method will prepend ".." segments
95 as necessary:
96
97 ```php
98 echo Path::makeRelative('/var/www/project/config/config.yml', '/var/www/project/uploads');
99 // => ../config/config.yml
100 ```
101
102 Use `isAbsolute()` and `isRelative()` to check whether a path is absolute or
103 relative:
104
105 ```php
106 Path::isAbsolute('C:\Programs\PHP\php.ini')
107 // => true
108 ```
109
110 All four methods internally canonicalize the passed path.
111
112 Finding Longest Common Base Paths
113 ---------------------------------
114
115 When you store absolute file paths on the file system, this leads to a lot of 
116 duplicated information:
117
118 ```php
119 return array(
120     '/var/www/vhosts/project/httpdocs/config/config.yml',
121     '/var/www/vhosts/project/httpdocs/config/routing.yml',
122     '/var/www/vhosts/project/httpdocs/config/services.yml',
123     '/var/www/vhosts/project/httpdocs/images/banana.gif',
124     '/var/www/vhosts/project/httpdocs/uploads/images/nicer-banana.gif',
125 );
126 ```
127
128 Especially when storing many paths, the amount of duplicated information is
129 noticeable. You can use `Path::getLongestCommonBasePath()` to check a list of
130 paths for a common base path:
131
132 ```php
133 $paths = array(
134     '/var/www/vhosts/project/httpdocs/config/config.yml',
135     '/var/www/vhosts/project/httpdocs/config/routing.yml',
136     '/var/www/vhosts/project/httpdocs/config/services.yml',
137     '/var/www/vhosts/project/httpdocs/images/banana.gif',
138     '/var/www/vhosts/project/httpdocs/uploads/images/nicer-banana.gif',
139 );
140
141 Path::getLongestCommonBasePath($paths);
142 // => /var/www/vhosts/project/httpdocs
143 ```
144
145 Use this path together with `Path::makeRelative()` to shorten the stored paths:
146
147 ```php
148 $bp = '/var/www/vhosts/project/httpdocs';
149
150 return array(
151     $bp.'/config/config.yml',
152     $bp.'/config/routing.yml',
153     $bp.'/config/services.yml',
154     $bp.'/images/banana.gif',
155     $bp.'/uploads/images/nicer-banana.gif',
156 );
157 ```
158
159 `getLongestCommonBasePath()` always returns canonical paths.
160
161 Use `Path::isBasePath()` to test whether a path is a base path of another path:
162
163 ```php
164 Path::isBasePath("/var/www", "/var/www/project");
165 // => true
166
167 Path::isBasePath("/var/www", "/var/www/project/..");
168 // => true
169
170 Path::isBasePath("/var/www", "/var/www/project/../..");
171 // => false
172 ```
173
174 Finding Directories/Root Directories
175 ------------------------------------
176
177 PHP offers the function `dirname()` to obtain the directory path of a file path.
178 This method has a few quirks:
179
180 * `dirname()` does not accept backslashes on UNIX
181 * `dirname("C:/Programs")` returns "C:", not "C:/"
182 * `dirname("C:/")` returns ".", not "C:/"
183 * `dirname("C:")` returns ".", not "C:/"
184 * `dirname("Programs")` returns ".", not ""
185 * `dirname()` does not canonicalize the result
186
187 `Path::getDirectory()` fixes these shortcomings:
188
189 ```php
190 echo Path::getDirectory("C:\Programs");
191 // => C:/
192 ```
193
194 Additionally, you can use `Path::getRoot()` to obtain the root of a path:
195
196 ```php
197 echo Path::getRoot("/etc/apache2/sites-available");
198 // => /
199
200 echo Path::getRoot("C:\Programs\Apache\Config");
201 // => C:/
202 ```
203