xref: /php-src/CONTRIBUTING.md (revision 59c38969)
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
134There are two ways to contribute to the PHP manual. You can edit the manual and
135send patches anonymously via [the online editor](https://edit.php.net/), or you
136can check the XML source out from Subversion and edit that and build it
137[per the instructions on the documentation site](http://doc.php.net/tutorial/).
138Patches created that way should be sent to the
139[documentation mailing list](mailto:phpdoc@lists.php.net).
140
141## Getting help
142
143If you are having trouble contributing to PHP, or just want to talk to a human
144about what you're working on, you can contact us via the
145[internals mailing list](mailto:internals@lists.php.net), or the
146[documentation mailing list](mailto:phpdoc@lists.php.net) for documentation
147issues.
148
149Although not a formal channel, you can also find a number of core developers on
150the #php.pecl channel on [EFnet](http://www.efnet.org/). Similarly, many
151documentation writers can be found on #php.doc. Windows development IRC channel
152is available at #winphp-dev on FreeNode.
153
154## PHP source code directory structure
155
156PHP source code also includes several files generated during development and
157several parts where maintenance is happening upstream in their respective
158locations.
159
160```bash
161<php-src>/
162 ├─ .git/                           # Git configuration and source directory
163 ├─ TSRM/                           # Thread Safe Resource Manager
164 └─ Zend/                           # Zend Engine
165    ├─ asm/                         # Bundled from src/asm in https://github.com/boostorg/context
166    ├─ zend_vm_execute.h            # Generated by `Zend/zend_vm_gen.php`
167    ├─ zend_vm_opcodes.c            # Generated by `Zend/zend_vm_gen.php`
168    ├─ zend_vm_opcodes.h            # Generated by `Zend/zend_vm_gen.php`
169    └─ ...
170 └─ build/                          # *nix build system files
171    ├─ ax_*.m4                      # https://github.com/autoconf-archive/autoconf-archive
172    ├─ config.guess                 # https://git.savannah.gnu.org/cgit/config.git
173    ├─ config.sub                   # https://git.savannah.gnu.org/cgit/config.git
174    ├─ libtool.m4                   # https://git.savannah.gnu.org/cgit/libtool.git
175    ├─ ltmain.sh                    # https://git.savannah.gnu.org/cgit/libtool.git
176    ├─ pkg.m4                       # https://gitlab.freedesktop.org/pkg-config/pkg-config
177    ├─ shtool                       # https://www.gnu.org/software/shtool/
178    └─ ...
179 ├─ docs/                           # PHP internals and repository documentation
180 └─ ext/                            # PHP core extensions
181    └─ bcmath/
182       ├─ libbcmath/                # Forked and maintained in php-src
183       └─ ...
184    └─ curl/
185       ├─ sync-constants.php        # The curl symbols checker
186       └─ ...
187    └─ date/
188       └─ lib/                      # Bundled datetime library https://github.com/derickr/timelib
189          ├─ parse_date.c           # Generated by re2c 0.15.3
190          ├─ parse_iso_intervals.c  # Generated by re2c 0.15.3
191          └─ ...
192       └─ ...
193    └─ ffi/
194       ├─ ffi_parser.c              # Generated by https://github.com/dstogov/llk
195       └─ ...
196    └─ fileinfo/
197       ├─ libmagic/                 # Modified libmagic https://github.com/file/file
198       ├─ data_file.c               # Generated by `ext/fileinfo/create_data_file.php`
199       ├─ libmagic.patch            # Modifications patch from upstream libmagic
200       ├─ magicdata.patch           # Modifications patch from upstream libmagic
201       └─ ...
202    └─ gd/
203       ├─ libgd/                    # Bundled and modified GD library https://github.com/libgd/libgd
204       └─ ...
205    └─ mbstring/
206       ├─ libmbfl/                  # Forked and maintained in php-src
207       ├─ unicode_data.h            # Generated by `ext/mbstring/ucgendat/ucgendat.php`
208       └─ ...
209    └─ opcache/
210       └─ jit/
211          └─ ir/                    # Bundled part of IR framework https://github.com/dstogov/ir
212    └─ pcre/
213       ├─ pcre2lib/                 # https://www.pcre.org/
214       └─ ...
215    └─ skeleton/                    # Skeleton for developing new extensions with `ext/ext_skel.php`
216       └─ ...
217    └─ standard/
218       └─ html_tables/
219          ├─ mappings/              # https://www.unicode.org/Public/MAPPINGS/
220          └─ ...
221       ├─ credits_ext.h             # Generated by `scripts/dev/credits`
222       ├─ credits_sapi.h            # Generated by `scripts/dev/credits`
223       ├─ html_tables.h             # Generated by `ext/standard/html_tables/html_table_gen.php`
224       └─ ...
225    └─ tokenizer/
226       ├─ tokenizer_data.c          # Generated by `ext/tokenizer/tokenizer_data_gen.sh`
227       └─ ...
228    └─ zend_test                    # For testing internal APIs. Not needed for regular builds.
229       └─ ...
230    └─ zip/                         # Bundled https://github.com/pierrejoye/php_zip
231       └─ ...
232    └─ ...
233 └─ main/                           # Binding that ties extensions, SAPIs, and engine together
234    ├─ streams/                     # Streams layer subsystem
235    ├─ php_version.h                # Generated by release managers using `configure`
236    └─ ...
237 ├─ pear/                           # PEAR installation
238 └─ sapi/                           # PHP SAPI modules
239    └─ cli/
240       ├─ mime_type_map.h           # Generated by `sapi/cli/generate_mime_type_map.php`
241       └─ ...
242    └─ ...
243 ├─ scripts/                        # php-config, phpize and internal development scripts
244 ├─ tests/                          # Core features tests
245 ├─ travis/                         # Travis CI service files
246 └─ win32/                          # Windows build system files
247    ├─ cp_enc_map.c                 # Generated by `win32/cp_enc_map_gen.exe`
248    └─ ...
249 └─ ...
250```
251
252## PHP internals
253
254For information on PHP internal C functions see
255[References about Maintaining and Extending PHP](https://wiki.php.net/internals/references).
256Various external resources can be found on the web. A standard printed reference
257is the book "Extending and Embedding PHP" by Sara Golemon.
258
259## PECL extensions
260
261If you are fixing broken functionality in a [PECL](https://pecl.php.net)
262extension then create a bug or identify an existing bug at
263[bugs.php.net](https://bugs.php.net). A bug can be used to track the change
264progress and prevent your changes getting lost in the PHP mail archives. Some
265PECL extensions have their own bug tracker locations and different contributing
266procedures.
267
268If your change is large then create a
269[Request for Comments (RFC)](https://wiki.php.net/rfc), discuss it with the
270extension maintainer, and discuss it on the development mailing list
271pecl-dev@lists.php.net depending on the extension. PECL mailing list
272subscription is explained on the
273[PECL support page](https://pecl.php.net/support.php).
274
275Update any open bugs and add a link to the source of your change. Send the patch
276or pointer to the bug to pecl-dev@lists.php.net. Also CC the extension
277maintainer. Explain what has been changed by your patch. Test scripts should be
278included.
279
280## Checklist for submitting contribution
281
282- Read [Coding standards](/CODING_STANDARDS.md) before you start working.
283- Update git source just before running your final `diff` and before testing.
284- Add inline comments and/or have external documentation ready. Use only
285  `/* */` style comments, not `//`.
286- Create test scripts for use with `make test`.
287- Run `make test` to check your change doesn't break other features.
288- Rebuild PHP with `--enable-debug` which will show some kinds of memory errors
289  and check the PHP and web server error logs after running your PHP tests.
290- Rebuild PHP with `--enable-zts` to check your change compiles and operates
291  correctly in a thread-safe PHP.
292- Review the change once more just before submitting it.
293
294## What happens after submitting contribution?
295
296If your change is easy to review and obviously has no side-effects, it might be
297committed relatively quickly.
298
299Because PHP is a volunteer-driven effort, more complex changes will require
300patience on your side. If you do not receive feedback in a few days, consider
301bumping. Before doing this think about these questions:
302
303- Did I send the patch to the right mailing list?
304- Did I review the mailing list archives to see if these kind of changes had
305  been discussed before?
306- Did I explain my change clearly?
307- Is my change too hard to review? If so, why?
308
309## What happens when your contribution is applied?
310
311Your name will likely be included in the Git commit log. If your change affects
312end users, a brief description and your name might be added to the [NEWS](/NEWS)
313file.
314
315## Git commit rules
316
317This section refers to contributors that have Git push access and make commit
318changes themselves. We'll assume you're basically familiar with Git, but feel
319free to post your questions on the mailing list. Please have a look at the more
320detailed [information on Git](https://git-scm.com/).
321
322PHP is developed through the efforts of a large number of people. Collaboration
323is a Good Thing(tm), and Git lets us do this. Thus, following some basic rules
324with regard to Git usage will:
325
326* Make everybody happier, especially those responsible for maintaining PHP
327  itself.
328* Keep the changes consistently well documented and easily trackable.
329* Prevent some of those 'Oops' moments.
330* Increase the general level of good will on planet Earth.
331
332Having said that, here are the organizational rules:
333
3341. Respect other people working on the project.
335
3362. Discuss any significant changes on the list before committing and get
337   confirmation from the release manager for the given branch.
338
3393. Look at [EXTENSIONS](/EXTENSIONS) file to see who is the primary maintainer
340   of the code you want to contribute to.
341
3424. If you "strongly disagree" about something another person did, don't start
343   fighting publicly - take it up in private email.
344
3455. If you don't know how to do something, ask first!
346
3476. Test your changes before committing them. We mean it. Really. To do so use
348   `make test`.
349
3507. For development use the `--enable-debug` switch to avoid memory leaks and the
351   `--enable-zts` switch to ensure your code handles TSRM correctly and doesn't
352   break for those who need that.
353
354Currently, we have the following branches in use:
355
356| Branch    |           |
357| --------- | --------- |
358| master    | Active development branch for PHP 8.4, which is open for backwards incompatible changes and major internal API changes. |
359| 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. |
360| 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. |
361| 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. |
362| PHP-8.0   | This branch is closed. |
363| PHP-7.4   | This branch is closed. |
364| PHP-7.3   | This branch is closed. |
365| PHP-7.2   | This branch is closed. |
366| PHP-7.1   | This branch is closed. |
367| PHP-7.0   | This branch is closed. |
368| PHP-5.6   | This branch is closed. |
369| PHP-5.5   | This branch is closed. |
370| PHP-5.4   | This branch is closed. |
371| PHP-5.3   | This branch is closed. |
372| PHP-5.2   | This branch is closed. |
373| PHP-5.1   | This branch is closed. |
374| PHP-4.4   | This branch is closed. |
375| PHP-X.Y.Z | These branches are used for the release managers for tagging the releases, hence they are closed to the general public. |
376
377The next few rules are more of a technical nature:
378
3791. All non-security bugfix changes should first go to the lowest bugfix branch
380   (i.e. 8.0) and then get merged up to all other branches. All security fixes
381   should go to the lowest security fixes branch (i.e 7.4). If a change is not
382   needed for later branches (i.e. fixes for features which were dropped from
383   later branches) an empty merge should be done.
384
3852. All news updates intended for public viewing, such as new features, bug
386   fixes, improvements, etc., should go into the NEWS file of *any stable
387   release* version with the given change. In other words, news about a bug fix
388   which went into PHP-5.4, PHP-5.5 and master should be noted in both
389   PHP-5.4/NEWS and PHP-5.5/NEWS but not master, which is not a public released
390   version yet.
391
3923. Do not commit multiple files and dump all messages in one commit. If you
393   modified several unrelated files, commit each group separately and provide a
394   nice commit message for each one. See example below.
395
3964. Do write your commit message in such a way that it makes sense even without
397   the corresponding diff. One should be able to look at it, and immediately
398   know what was modified. Definitely include the function name in the message
399   as shown below.
400
4015. In your commit messages, keep each line shorter than 80 characters. And try
402   to align your lines vertically, if they wrap. It looks bad otherwise.
403
4046. If you modified a function that is callable from PHP, prepend PHP to the
405   function name as shown below.
406
407The format of the commit messages is pretty simple.
408
409    <max 79 characters short description>\n
410    \n
411    <long description, 79 chars per line>
412    \n
413
414An Example from the git project (commit 2b34e486bc):
415
416    pack-objects: Fix compilation with NO_PTHREDS
417
418    It looks like commit 99fb6e04 (pack-objects: convert to use parse_options(),
419    2012-02-01) moved the #ifdef NO_PTHREDS around but hasn't noticed that the
420    'arg' variable no longer is available.
421
422If you fix some bugs, you should note the bug ID numbers in your commit message.
423Bug ID should be prefixed by `#`.
424
425Example:
426
427    Fixed bug #14016 (pgsql notice handler double free crash bug.)
428
429When you change the NEWS file for a bug fix, then please keep the bugs sorted in
430decreasing order under the fixed version.
431
432## Copyright and license headers
433
434New source code files should include the following header block:
435
436```c
437/*
438  +----------------------------------------------------------------------+
439  | Copyright (c) The PHP Group                                          |
440  +----------------------------------------------------------------------+
441  | This source file is subject to version 3.01 of the PHP license,      |
442  | that is bundled with this package in the file LICENSE, and is        |
443  | available through the world-wide-web at the following url:           |
444  | https://www.php.net/license/3_01.txt                                 |
445  | If you did not receive a copy of the PHP license and are unable to   |
446  | obtain it through the world-wide-web, please send a note to          |
447  | license@php.net so we can mail you a copy immediately.               |
448  +----------------------------------------------------------------------+
449  | Author:                                                              |
450  +----------------------------------------------------------------------+
451*/
452```
453
454Thank you for contributing to PHP!
455