|
| 1 | +# CodeIgniter 4 — Repository Guidelines |
| 2 | + |
| 3 | +CodeIgniter 4 is a mature open-source PHP framework. Framework production |
| 4 | +code lives in `system/`; its tests mirror that structure under |
| 5 | +`tests/system/`. |
| 6 | + |
| 7 | +## Before making changes |
| 8 | + |
| 9 | +Consult the relevant sections of: |
| 10 | + |
| 11 | +- `contributing/pull_request.md` |
| 12 | +- `contributing/internals.md` |
| 13 | +- `contributing/styleguide.md` |
| 14 | +- `tests/README.md` |
| 15 | + |
| 16 | +Follow existing code and tests in the affected component. Search for an |
| 17 | +existing implementation before introducing a new abstraction or convention. |
| 18 | + |
| 19 | +## Target branch and compatibility policy |
| 20 | + |
| 21 | +Compatibility is judged against the pull request's base branch, not the |
| 22 | +contributor's source or feature branch. When the base branch is unknown, |
| 23 | +apply the stricter `develop` policy. |
| 24 | + |
| 25 | +### Base branch `develop` |
| 26 | + |
| 27 | +`develop` is the next patch-release line. Intentional backward-incompatible |
| 28 | +changes are not allowed. |
| 29 | + |
| 30 | +- Preserve public and protected APIs, documented behavior, configuration |
| 31 | + defaults, generated project files, exceptions, and observable side effects. |
| 32 | +- Do not remove deprecated items or change public/protected signatures, |
| 33 | + visibility, or interface/abstract requirements. |
| 34 | +- A bug or security fix may correct faulty behavior but must preserve the |
| 35 | + documented contract and ordinary valid usage. |
| 36 | +- If a fix necessarily breaks compatibility, target the appropriate minor |
| 37 | + branch instead. |
| 38 | + |
| 39 | +### Base branch `4.*` |
| 40 | + |
| 41 | +Minor-release lines (for example `4.9`). Small, deliberate compatibility |
| 42 | +breaks may be accepted when they materially improve the framework or |
| 43 | +complete the documented deprecation lifecycle. |
| 44 | + |
| 45 | +- Keep each break narrow, explicit, and justified; never an incidental |
| 46 | + side effect of refactoring. |
| 47 | +- Deprecated APIs may be removed no earlier than the second subsequent |
| 48 | + minor release (deprecated in 4.6.x means removable in 4.8.0), with a |
| 49 | + supported replacement. |
| 50 | +- Every accepted break needs tests for the new behavior, a minor-version |
| 51 | + changelog entry, and migration instructions in the upgrading guide. |
| 52 | + |
| 53 | +### All base branches |
| 54 | + |
| 55 | +- Production code must run on PHP 8.2. Do not require a newer PHP version, |
| 56 | + even when a newer version is installed locally. |
| 57 | +- Signatures, properties, constants, default values, exceptions, side |
| 58 | + effects, configuration, and generated project files are all |
| 59 | + compatibility-sensitive. |
| 60 | +- Major-scale redesigns and ecosystem-wide migration requirements belong in |
| 61 | + a major release, not a patch or minor release. |
| 62 | +- Prefer the minimum useful abstraction and keep framework components as |
| 63 | + independent as practical. |
| 64 | +- Dependencies should be injectable. When a framework service is used as a |
| 65 | + default, preserve the ability for applications to replace it. |
| 66 | +- Do not add or update a Composer dependency unless the task explicitly |
| 67 | + requires it and the change is justified. |
| 68 | +- Do not modify code in `system/ThirdParty/`. |
| 69 | + |
| 70 | +## Coding standards |
| 71 | + |
| 72 | +- Do not add `declare(strict_types=1)` mechanically. Follow nearby code and |
| 73 | + check the `DeclareStrictTypesRector` exclusions in `rector.php`; PHP files |
| 74 | + use strict types unless excluded there. Treat the existing exclusions as |
| 75 | + intentional compatibility constraints. Do not remove an exclusion without |
| 76 | + dedicated justification and tests. |
| 77 | +- Every new class property must have a native type declaration. Use the |
| 78 | + most precise type supported by PHP 8.2; use `mixed` only when the |
| 79 | + property intentionally accepts unrelated types. |
| 80 | +- Do not add or change a type on an existing public or protected property |
| 81 | + mechanically. Property types affect inheritance and must follow the |
| 82 | + target-branch compatibility policy. |
| 83 | +- Add PHPDoc only when it contributes information that native types cannot |
| 84 | + express. Do not duplicate a parent or interface docblock. |
| 85 | +- Never suppress a static-analysis error or update a baseline to make a |
| 86 | + check pass. |
| 87 | + |
| 88 | +## FrankenPHP Worker Mode |
| 89 | + |
| 90 | +In Worker Mode one process serves many requests. The entry point's source |
| 91 | +template is `system/Commands/Worker/Views/frankenphp-worker.php.tpl`; the |
| 92 | +`worker:install` command publishes it as `public/frankenphp-worker.php`. |
| 93 | + |
| 94 | +- For every change affecting application bootstrap, request handling, |
| 95 | + response sending, shutdown, superglobals, sessions, database or cache |
| 96 | + connections, services, factories, events, toolbar state, static state, or |
| 97 | + other request-lifecycle behavior, inspect the worker entry-point template |
| 98 | + even when it is not part of the diff. |
| 99 | +- Compare traditional per-process execution with worker execution, where |
| 100 | + the framework boots once and handles multiple requests in the same |
| 101 | + process. |
| 102 | +- Classify mutable state as process-lifetime, intentionally persistent, or |
| 103 | + request-specific. Request-specific state must be refreshed or reset for |
| 104 | + every request and must not leak into the next request. |
| 105 | +- Preserve the ordering requirements between per-request reconnection, |
| 106 | + framework reset, superglobal refresh, application execution, and |
| 107 | + post-request cleanup. |
| 108 | +- Treat the template as the source of truth. Do not edit a generated |
| 109 | + `public/frankenphp-worker.php` in place. |
| 110 | +- When a release changes the template in a way existing installations must |
| 111 | + receive, add an upgrading instruction telling Worker Mode users to |
| 112 | + republish it with `php spark worker:install --force`. |
| 113 | + |
| 114 | +## Tests |
| 115 | + |
| 116 | +- Every bug fix should include a regression test that fails without the |
| 117 | + fix. |
| 118 | +- Test failure paths, exceptions, boundary conditions, and state cleanup, |
| 119 | + not only the happy path. |
| 120 | +- Prefer strict and dedicated PHPUnit assertions as described in the |
| 121 | + project style guide. |
| 122 | +- Do not weaken or remove an existing test unless the documented behavior |
| 123 | + or specification changed. |
| 124 | + |
| 125 | +## Documentation |
| 126 | + |
| 127 | +- Public API, behavior, message, or default-value changes may require an |
| 128 | + update to the user guide and changelog. |
| 129 | +- Changes requiring user action, including configuration changes, may also |
| 130 | + require an upgrading-guide entry. |
| 131 | +- For a `4.*` target, every intentional compatibility break must be |
| 132 | + documented in both the minor-version changelog and its upgrading guide. |
| 133 | + |
| 134 | +## Focused validation |
| 135 | + |
| 136 | +GitHub Actions is the authoritative source for full validation. Do not |
| 137 | +reproduce the complete CI matrix locally. |
| 138 | + |
| 139 | +- Run only the narrowest PHPUnit test file or component that covers a code |
| 140 | + change, for example |
| 141 | + `vendor/bin/phpunit tests/system/<Component>/<Class>Test.php`. |
| 142 | +- Run a file-scoped analysis or formatting check only when it is quick and |
| 143 | + directly relevant. |
| 144 | +- Do not run the complete PHPUnit suite, `composer phpstan:check`, |
| 145 | + `composer cs`, Psalm, Structarmed, or a repository-wide Rector analysis |
| 146 | + by default. |
| 147 | +- Report which focused checks were executed and which validation was left |
| 148 | + to CI. |
0 commit comments