1# Contributing to PHP 2 3Anybody who programs in PHP can be a contributing member of the community that 4develops and deploys it; the task of deploying PHP, documentation and associated 5websites is a never-ending one. With every release or release candidate comes a 6wave of work, which takes a lot of organization and co-ordination. 7 8You don't need any special access to download, build, debug and begin submitting 9PHP or PECL code, tests or documentation. Once you've followed this guide and 10had several contributions accepted, commit privileges are often quickly granted. 11 12## Index 13 14* [Pull requests](#pull-requests) 15* [Filing bugs](#filing-bugs) 16* [Feature requests](#feature-requests) 17* [Technical resources](#technical-resources) 18* [Writing tests](#writing-tests) 19* [Writing documentation](#writing-documentation) 20* [Getting help](#getting-help) 21* [PHP source code directory structure](#php-source-code-directory-structure) 22* [PHP internals](#php-internals) 23* [PECL extensions](#pecl-extensions) 24* [Checklist for submitting contribution](#checklist-for-submitting-contribution) 25* [What happens after submitting contribution?](#what-happens-after-submitting-contribution) 26* [What happens when your contribution is applied?](#what-happens-when-your-contribution-is-applied) 27* [Git commit rules](#git-commit-rules) 28* [Copyright and license headers](#copyright-and-license-headers) 29 30## Pull requests 31 32PHP welcomes pull requests to [add tests](#writing-tests), fix bugs and to 33implement RFCs. Please be sure to include tests as appropriate! 34 35If you are fixing a bug, then please submit your PR against the lowest actively 36supported branch of PHP that the bug affects (only green branches on 37[the supported version page](https://www.php.net/supported-versions.php) are 38supported). For example, at the time of writing, the lowest supported version is 39PHP 8.0, which corresponds to the `PHP-8.0` branch in Git. Please also make sure 40you add a link to the PR in the bug on [the bug tracker](https://github.com/php/php-src/issues) 41or [the old bug tracker](https://bugs.php.net/). 42 43Pull requests implementing RFCs should be submitted against `master`. 44 45Pull requests should *never* be submitted against `PHP-x.y.z` branches, as these 46are only used for release management. 47 48If your pull request exhibits conflicts with the base branch, please resolve 49them by using `git rebase` instead of `git merge`. 50 51Fork the official PHP repository and send a pull request. A notification will be 52sent to the pull request mailing list. Sending a note to PHP Internals list 53(internals@lists.php.net) may help getting more feedback and quicker turnaround. 54You can also add pull requests to [bug reports](https://github.com/php/php-src/issues) 55and [old bug reports](https://bugs.php.net/). 56 57Read [Git access page](https://www.php.net/git.php) for help on using Git to get 58and build PHP source code. We recommend to look at our 59[workflow](https://wiki.php.net/vcs/gitworkflow) and our 60[FAQ](https://wiki.php.net/vcs/gitfaq). 61 62## Filing bugs 63 64Bugs can be filed on [GitHub Issues](https://github.com/php/php-src/issues/new/choose). 65If this is the first time you've filed a bug, we suggest reading the 66[guide to reporting a bug](https://bugs.php.net/how-to-report.php). 67 68Where possible, please include a self-contained reproduction case! 69 70## Feature requests 71 72Feature requests are generally submitted in the form of 73[Requests for Comments (RFC)](https://wiki.php.net/rfc/howto), ideally 74accompanied by [pull requests](#pull-requests). You can find the extremely large 75list of RFCs that have been previously considered on the 76[PHP Wiki](https://wiki.php.net/rfc). 77 78To create an RFC, discuss it with the extension maintainer, and discuss it on 79the development mailing list internals@lists.php.net. RFC Wiki accounts can be 80requested on https://wiki.php.net/start?do=register. PHP extension maintainers 81can be found in the [EXTENSIONS](/EXTENSIONS) file in the PHP source code 82repository. Mailing list subscription is explained on the 83[mailing lists page](https://www.php.net/mailing-lists.php). 84 85You may also want to read 86[The Mysterious PHP RFC Process](https://blogs.oracle.com/opal/post/the-mysterious-php-rfc-process-and-how-you-can-change-the-web) 87for additional notes on the best way to approach submitting an RFC. 88 89## Technical resources 90 91There are a number of technical resources on php-src. Unfortunately, they are 92scattered across different websites, and often outdated. Nonetheless, they can 93provide a good starting point for learning about the fundamentals of the code 94base. 95 96* https://www.phpinternalsbook.com/ 97* https://www.npopov.com/ 98 * [Internal value representation](https://www.npopov.com/2015/05/05/Internal-value-representation-in-PHP-7-part-1.html), [part 2](https://www.npopov.com/2015/06/19/Internal-value-representation-in-PHP-7-part-2.html) 99 * [HashTable implementation](https://www.npopov.com/2014/12/22/PHPs-new-hashtable-implementation.html) 100 * [Zend Virtual Machine](https://www.npopov.com/2017/04/14/PHP-7-Virtual-machine.html) 101 * [How opcache works](https://www.npopov.com/2021/10/13/How-opcache-works.html) 102 * [The opcache optimizer](https://www.npopov.com/2022/05/22/The-opcache-optimizer.html) 103* https://wiki.php.net/internals 104 * [Objects](https://wiki.php.net/internals/engine/objects) 105* https://qa.php.net/ 106 * [Writing tests](https://qa.php.net/write-test.php) 107 * [Running tests](https://qa.php.net/running-tests.php) 108 * [PHPT structure](https://qa.php.net/phpt_details.php) 109* https://phpinternals.net/ 110 * [Implementing new operator](https://phpinternals.net/articles/implementing_a_range_operator_into_php), [part 2](https://phpinternals.net/articles/a_reimplementation_of_the_range_operator) 111 * [Opcode extending](https://phpinternals.net/articles/implementing_new_language_constructs_via_opcode_extending) 112 113## Writing tests 114 115We love getting new tests! PHP is a huge project and improving test coverage is 116a huge win for every PHP user. 117 118[Our QA site includes a page detailing how to write test cases.](https://qa.php.net/write-test.php) 119 120Submitting test scripts helps us to understand what functionality has changed. 121It is important for the stability and maintainability of PHP that tests are 122comprehensive. 123 124Failure conditions of `zend_parse_parameters`, `ZEND_PARSE_PARAMETERS()` and 125similar functions should not be tested. These parameter parsing APIs are already 126extensively tested, and additional tests only complicate future modifications. 127 128For newly created tests, a `--CREDITS--` section should no longer be included, 129as test authorship is already accurately tracked by Git. If multiple authors 130should be credited, the `Co-authored-by` tag in the commit message may be used. 131 132## Writing documentation 133 134Editing the manual is done by checking out the XML sources using Git and editing 135and building it [per the instructions on the documentation site](http://doc.php.net/tutorial/). 136 137## Getting help 138 139If you are having trouble contributing to PHP, or just want to talk to a human 140about what you're working on, you can contact us via the 141[internals mailing list](mailto:internals@lists.php.net), or the 142[documentation mailing list](mailto:phpdoc@lists.php.net) for documentation 143issues. 144 145Although not a formal channel, you can also find a number of core developers on 146the #php.pecl channel on [EFnet](http://www.efnet.org/). Similarly, many 147documentation writers can be found on #php.doc. Windows development IRC channel 148is available at #winphp-dev on FreeNode. 149 150## PHP source code directory structure 151 152PHP source code also includes several files generated during development and 153several parts where maintenance is happening upstream in their respective 154locations. 155 156```bash 157<php-src>/ 158 ├─ .git/ # Git configuration and source directory 159 ├─ TSRM/ # Thread Safe Resource Manager 160 └─ Zend/ # Zend Engine 161 ├─ asm/ # Bundled from src/asm in https://github.com/boostorg/context 162 ├─ zend_vm_execute.h # Generated by `Zend/zend_vm_gen.php` 163 ├─ zend_vm_opcodes.c # Generated by `Zend/zend_vm_gen.php` 164 ├─ zend_vm_opcodes.h # Generated by `Zend/zend_vm_gen.php` 165 └─ ... 166 └─ build/ # *nix build system files 167 ├─ ax_*.m4 # https://github.com/autoconf-archive/autoconf-archive 168 ├─ config.guess # https://git.savannah.gnu.org/cgit/config.git 169 ├─ config.sub # https://git.savannah.gnu.org/cgit/config.git 170 ├─ libtool.m4 # https://git.savannah.gnu.org/cgit/libtool.git 171 ├─ ltmain.sh # https://git.savannah.gnu.org/cgit/libtool.git 172 ├─ pkg.m4 # https://gitlab.freedesktop.org/pkg-config/pkg-config 173 ├─ shtool # https://www.gnu.org/software/shtool/ 174 └─ ... 175 ├─ docs/ # PHP internals and repository documentation 176 └─ ext/ # PHP core extensions 177 └─ bcmath/ 178 ├─ libbcmath/ # Forked and maintained in php-src 179 └─ ... 180 └─ curl/ 181 ├─ sync-constants.php # The curl symbols checker 182 └─ ... 183 └─ date/ 184 └─ lib/ # Bundled datetime library https://github.com/derickr/timelib 185 ├─ parse_date.c # Generated by re2c 0.15.3 186 ├─ parse_iso_intervals.c # Generated by re2c 0.15.3 187 └─ ... 188 └─ ... 189 └─ ffi/ 190 ├─ ffi_parser.c # Generated by https://github.com/dstogov/llk 191 └─ ... 192 └─ fileinfo/ 193 ├─ libmagic/ # Modified libmagic https://github.com/file/file 194 ├─ data_file.c # Generated by `ext/fileinfo/create_data_file.php` 195 ├─ libmagic.patch # Modifications patch from upstream libmagic 196 ├─ magicdata.patch # Modifications patch from upstream libmagic 197 └─ ... 198 └─ gd/ 199 ├─ libgd/ # Bundled and modified GD library https://github.com/libgd/libgd 200 └─ ... 201 └─ mbstring/ 202 ├─ libmbfl/ # Forked and maintained in php-src 203 ├─ unicode_data.h # Generated by `ext/mbstring/ucgendat/ucgendat.php` 204 └─ ... 205 └─ opcache/ 206 └─ jit/ 207 └─ ir/ # Bundled part of IR framework https://github.com/dstogov/ir 208 └─ pcre/ 209 ├─ pcre2lib/ # https://www.pcre.org/ 210 └─ ... 211 └─ skeleton/ # Skeleton for developing new extensions with `ext/ext_skel.php` 212 └─ ... 213 └─ standard/ 214 └─ html_tables/ 215 ├─ mappings/ # https://www.unicode.org/Public/MAPPINGS/ 216 └─ ... 217 ├─ credits_ext.h # Generated by `scripts/dev/credits` 218 ├─ credits_sapi.h # Generated by `scripts/dev/credits` 219 ├─ html_tables.h # Generated by `ext/standard/html_tables/html_table_gen.php` 220 └─ ... 221 └─ tokenizer/ 222 ├─ tokenizer_data.c # Generated by `ext/tokenizer/tokenizer_data_gen.sh` 223 └─ ... 224 └─ zend_test # For testing internal APIs. Not needed for regular builds. 225 └─ ... 226 └─ zip/ # Bundled https://github.com/pierrejoye/php_zip 227 └─ ... 228 └─ ... 229 └─ main/ # Binding that ties extensions, SAPIs, and engine together 230 ├─ streams/ # Streams layer subsystem 231 ├─ php_version.h # Generated by release managers using `configure` 232 └─ ... 233 ├─ pear/ # PEAR installation 234 └─ sapi/ # PHP SAPI modules 235 └─ cli/ 236 ├─ mime_type_map.h # Generated by `sapi/cli/generate_mime_type_map.php` 237 └─ ... 238 └─ ... 239 ├─ scripts/ # php-config, phpize and internal development scripts 240 ├─ tests/ # Core features tests 241 └─ win32/ # Windows build system files 242 ├─ cp_enc_map.c # Generated by `win32/cp_enc_map_gen.exe` 243 └─ ... 244 └─ ... 245``` 246 247## PHP internals 248 249For information on PHP internal C functions see 250[References about Maintaining and Extending PHP](https://wiki.php.net/internals/references). 251Various external resources can be found on the web. A standard printed reference 252is the book "Extending and Embedding PHP" by Sara Golemon. 253 254## PECL extensions 255 256If you are fixing broken functionality in a [PECL](https://pecl.php.net) 257extension then create a bug or identify an existing bug at 258[bugs.php.net](https://bugs.php.net). A bug can be used to track the change 259progress and prevent your changes getting lost in the PHP mail archives. Some 260PECL extensions have their own bug tracker locations and different contributing 261procedures. 262 263If your change is large then create a 264[Request for Comments (RFC)](https://wiki.php.net/rfc), discuss it with the 265extension maintainer, and discuss it on the development mailing list 266pecl-dev@lists.php.net depending on the extension. PECL mailing list 267subscription is explained on the 268[PECL support page](https://pecl.php.net/support.php). 269 270Update any open bugs and add a link to the source of your change. Send the patch 271or pointer to the bug to pecl-dev@lists.php.net. Also CC the extension 272maintainer. Explain what has been changed by your patch. Test scripts should be 273included. 274 275## Checklist for submitting contribution 276 277- Read [Coding standards](/CODING_STANDARDS.md) before you start working. 278- Update git source just before running your final `diff` and before testing. 279- Add inline comments and/or have external documentation ready. Use only 280 `/* */` style comments, not `//`. 281- Create test scripts for use with `make test`. 282- Run `make test` to check your change doesn't break other features. 283- Rebuild PHP with `--enable-debug` which will show some kinds of memory errors 284 and check the PHP and web server error logs after running your PHP tests. 285- Rebuild PHP with `--enable-zts` to check your change compiles and operates 286 correctly in a thread-safe PHP. 287- Review the change once more just before submitting it. 288 289## What happens after submitting contribution? 290 291If your change is easy to review and obviously has no side-effects, it might be 292committed relatively quickly. 293 294Because PHP is a volunteer-driven effort, more complex changes will require 295patience on your side. If you do not receive feedback in a few days, consider 296bumping. Before doing this think about these questions: 297 298- Did I send the patch to the right mailing list? 299- Did I review the mailing list archives to see if these kind of changes had 300 been discussed before? 301- Did I explain my change clearly? 302- Is my change too hard to review? If so, why? 303 304## What happens when your contribution is applied? 305 306Your name will likely be included in the Git commit log. If your change affects 307end users, a brief description and your name might be added to the [NEWS](/NEWS) 308file. 309 310## Git commit rules 311 312This section refers to contributors that have Git push access and make commit 313changes themselves. We'll assume you're basically familiar with Git, but feel 314free to post your questions on the mailing list. Please have a look at the more 315detailed [information on Git](https://git-scm.com/). 316 317PHP is developed through the efforts of a large number of people. Collaboration 318is a Good Thing(tm), and Git lets us do this. Thus, following some basic rules 319with regard to Git usage will: 320 321* Make everybody happier, especially those responsible for maintaining PHP 322 itself. 323* Keep the changes consistently well documented and easily trackable. 324* Prevent some of those 'Oops' moments. 325* Increase the general level of good will on planet Earth. 326 327Having said that, here are the organizational rules: 328 3291. Respect other people working on the project. 330 3312. Discuss any significant changes on the list before committing and get 332 confirmation from the release manager for the given branch. 333 3343. Look at [EXTENSIONS](/EXTENSIONS) file to see who is the primary maintainer 335 of the code you want to contribute to. 336 3374. If you "strongly disagree" about something another person did, don't start 338 fighting publicly - take it up in private email. 339 3405. If you don't know how to do something, ask first! 341 3426. Test your changes before committing them. We mean it. Really. To do so use 343 `make test`. 344 3457. For development use the `--enable-debug` switch to avoid memory leaks and the 346 `--enable-zts` switch to ensure your code handles TSRM correctly and doesn't 347 break for those who need that. 348 349Currently, we have the following branches in use: 350 351| Branch | | 352| --------- | --------- | 353| master | Active development branch for PHP 8.4, which is open for backwards incompatible changes and major internal API changes. | 354| PHP-8.3 | Is used to release the PHP 8.3.x series. This is a current stable version and is open for bugfixes only. | 355| PHP-8.2 | Is used to release the PHP 8.2.x series. This is a current stable version and is open for bugfixes only. | 356| PHP-8.1 | Is used to release the PHP 8.1.x series. This is an old stable version and is open for security fixes only. | 357| PHP-8.0 | This branch is closed. | 358| PHP-7.4 | This branch is closed. | 359| PHP-7.3 | This branch is closed. | 360| PHP-7.2 | This branch is closed. | 361| PHP-7.1 | This branch is closed. | 362| PHP-7.0 | This branch is closed. | 363| PHP-5.6 | This branch is closed. | 364| PHP-5.5 | This branch is closed. | 365| PHP-5.4 | This branch is closed. | 366| PHP-5.3 | This branch is closed. | 367| PHP-5.2 | This branch is closed. | 368| PHP-5.1 | This branch is closed. | 369| PHP-4.4 | This branch is closed. | 370| PHP-X.Y.Z | These branches are used for the release managers for tagging the releases, hence they are closed to the general public. | 371 372The next few rules are more of a technical nature: 373 3741. All non-security bugfix changes should first go to the lowest bugfix branch 375 (i.e. 8.0) and then get merged up to all other branches. All security fixes 376 should go to the lowest security fixes branch (i.e 7.4). If a change is not 377 needed for later branches (i.e. fixes for features which were dropped from 378 later branches) an empty merge should be done. 379 3802. All news updates intended for public viewing, such as new features, bug 381 fixes, improvements, etc., should go into the NEWS file of *any stable 382 release* version with the given change. In other words, news about a bug fix 383 which went into PHP-5.4, PHP-5.5 and master should be noted in both 384 PHP-5.4/NEWS and PHP-5.5/NEWS but not master, which is not a public released 385 version yet. 386 3873. Do not commit multiple files and dump all messages in one commit. If you 388 modified several unrelated files, commit each group separately and provide a 389 nice commit message for each one. See example below. 390 3914. Do write your commit message in such a way that it makes sense even without 392 the corresponding diff. One should be able to look at it, and immediately 393 know what was modified. Definitely include the function name in the message 394 as shown below. 395 3965. In your commit messages, keep each line shorter than 80 characters. And try 397 to align your lines vertically, if they wrap. It looks bad otherwise. 398 3996. If you modified a function that is callable from PHP, prepend PHP to the 400 function name as shown below. 401 402The format of the commit messages is pretty simple. 403 404 <max 79 characters short description>\n 405 \n 406 <long description, 79 chars per line> 407 \n 408 409An Example from the git project (commit 2b34e486bc): 410 411 pack-objects: Fix compilation with NO_PTHREDS 412 413 It looks like commit 99fb6e04 (pack-objects: convert to use parse_options(), 414 2012-02-01) moved the #ifdef NO_PTHREDS around but hasn't noticed that the 415 'arg' variable no longer is available. 416 417If you fix some bugs, you should note the bug ID numbers in your commit message. 418Bug ID should be prefixed by `#`. 419 420Example: 421 422 Fixed bug #14016 (pgsql notice handler double free crash bug.) 423 424When you change the NEWS file for a bug fix, then please keep the bugs sorted in 425decreasing order under the fixed version. 426 427## Copyright and license headers 428 429New source code files should include the following header block: 430 431```c 432/* 433 +----------------------------------------------------------------------+ 434 | Copyright (c) The PHP Group | 435 +----------------------------------------------------------------------+ 436 | This source file is subject to version 3.01 of the PHP license, | 437 | that is bundled with this package in the file LICENSE, and is | 438 | available through the world-wide-web at the following url: | 439 | https://www.php.net/license/3_01.txt | 440 | If you did not receive a copy of the PHP license and are unable to | 441 | obtain it through the world-wide-web, please send a note to | 442 | license@php.net so we can mail you a copy immediately. | 443 +----------------------------------------------------------------------+ 444 | Author: | 445 +----------------------------------------------------------------------+ 446*/ 447``` 448 449Thank you for contributing to PHP! 450