|
10 | 10 | * project root, applied before the page lifecycle begins. It is designed to be |
11 | 11 | * simple to maintain, friendly for editors, and safe by default. |
12 | 12 | * |
13 | | - * Contents |
14 | | - * - Overview |
15 | | - * - Quick start |
16 | | - * - Redirect file formats (INI, CSV, TSV) |
17 | | - * - Regex rules (nginx-style) |
18 | | - * - Status codes and validation |
19 | | - * - Exceptions and error messages |
20 | | - * - Programmatic API (Redirect, RedirectUri) |
21 | | - * - How loading and matching works |
22 | | - * |
23 | | - * Overview |
24 | 13 | * Place a file named one of the following in your project root: |
25 | 14 | * - redirect.ini |
26 | 15 | * - redirect.csv |
27 | 16 | * - redirect.tsv |
28 | 17 | * The Redirect class automatically discovers and loads the single redirect file |
29 | | - * using the glob pattern `redirect.{csv,tsv,ini}`. If more than one file |
30 | | - * matches, a RedirectException is thrown, as multiple sources would be |
31 | | - * ambiguous. |
32 | | - * |
33 | | - * Quick start |
34 | | - * 1) Create redirect.ini in your project root: |
35 | | - * /old-path=/new-path |
36 | | - * 2) Start your application (Application calls Redirect->execute()). Requests to |
37 | | - * /old-path will be redirected to /new-path with HTTP 307 by default. |
38 | | - * |
39 | | - * Redirect file formats |
40 | | - * - INI |
41 | | - * - Flat (no sections): each line `oldURI=newURI` uses the default status 307. |
42 | | - * - Sectioned: use numeric status code sections, e.g.: |
43 | | - * [301] |
44 | | - * /moved=/new-location |
45 | | - * [303] |
46 | | - * /see-other=/somewhere |
47 | | - * - Section names must be numeric between 301 and 308 inclusive; any |
48 | | - * non-numeric section causes a RedirectException. |
49 | | - * |
50 | | - * - CSV |
51 | | - * - Columns: oldURI,newURI[,status] |
52 | | - * - If the third column is present it must be numeric (301–308); otherwise a |
53 | | - * RedirectException is thrown. If omitted, 307 is used. |
54 | | - * |
55 | | - * - TSV |
56 | | - * - Same as CSV but tab-delimited: oldURI \t newURI [\t status] |
57 | | - * - Same validation rules as CSV apply. |
58 | | - * |
59 | | - * Regex rules (nginx-style) |
60 | | - * - To define a regex match for the old URI, prefix the pattern with `~`. |
61 | | - * Example that maps both /shop/cat/item and /shop/dog/thing: |
62 | | - * ~^/shop/([^/]+)/(.+)$=/newShop/$1/$2 (INI) |
63 | | - * ~^/shop/([^/]+)/(.+)$,/newShop/$1/$2,302 (CSV) |
64 | | - * The replacement may reference capture groups using $1, $2, etc. |
65 | | - * - All URIs begin with `/`, so patterns should be anchored appropriately. |
66 | | - * - Invalid regex patterns result in a RedirectException. |
67 | | - * |
68 | | - * Status codes and validation |
69 | | - * - Default status code: 307. |
70 | | - * - Allowed range: 301–308 (inclusive). Values are validated and normalised. |
71 | | - * - For INI with sections, the section number is the status code; for CSV/TSV, |
72 | | - * the optional third column is the status. |
73 | | - * - Non-numeric INI sections and non-numeric third columns in CSV/TSV throw a |
74 | | - * RedirectException with a message describing the invalid value. |
75 | | - * |
76 | | - * Exceptions and error messages |
77 | | - * - Multiple redirect files: "Multiple redirect files in project root". |
78 | | - * - Invalid HTTP status code read from a file: "Invalid HTTP status code in |
79 | | - * redirect file: <value>". |
80 | | - * - Invalid regex pattern: message explains which pattern failed. |
81 | | - * |
82 | | - * Programmatic API |
83 | | - * - new Redirect(string $glob = "redirect.{csv,tsv,ini}", ?Closure $handler = null) |
84 | | - * - $glob allows overriding the discovery pattern/location. |
85 | | - * - $handler receives (string $uri, int $code). If omitted, the default |
86 | | - * implementation sends a Location header and code. |
87 | | - * - execute(string $uri = "/"): void |
88 | | - * - Looks up the given $uri and, if a redirect exists, invokes the handler. |
89 | | - * - getRedirectUri(string $oldUri): ?RedirectUri |
90 | | - * - Returns RedirectUri with target uri and status code, or null if no match. |
91 | | - * - RedirectUri |
92 | | - * - Value object with public string $uri and public int $code. |
93 | | - * |
94 | | - * How loading and matching works |
95 | | - * - Redirect determines the loader from the file extension (INI, CSV, TSV) and |
96 | | - * populates an internal RedirectMap. |
97 | | - * - Literal rules and regex rules are both supported. Matching prefers literal |
98 | | - * rules first; if no literal match is found, regex rules are evaluated in a |
99 | | - * deterministic order. |
100 | | - * - Only a single redirect file may exist; if none is found, getRedirectUri |
101 | | - * returns null and execute does nothing. |
| 18 | + * using the glob pattern `redirect.{csv,tsv,ini}`. |
102 | 19 | */ |
103 | 20 | class Redirect { |
104 | 21 | private ?string $redirectFile = null; |
|
0 commit comments