xref: /PHP-8.4/CONTRIBUTING.md (revision 13f04116)
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