Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consolidate information from the three RFCs it is based on #11

Merged
merged 4 commits into from
Jan 28, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
616 changes: 312 additions & 304 deletions coding-standards-and-naming.rst
Original file line number Diff line number Diff line change
@@ -2,155 +2,79 @@
Coding Standards and Naming Policy
####################################

*********
Classes
*********

From: `Class Naming RFC <https://wiki.php.net/rfc/class-naming>`_

**Editor’s note: Parts of this RFC have been superseded by the “Casing of
acronyms in class and method names” section**

The PHP coding standard does not cover how class names should be written. This
leads to friction within the userland community that is now largely following
the `standard recommendation PSR-1 <http://www.php-fig.org/psr/psr-1/>`_.

Extending our current coding standard to cover edge cases about abbreviations
and acronyms/initialisms would resolve any future discussion.

Proposal
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in `BCP 14
<https://www.rfc-editor.org/bcp/bcp14.txt>`_ [`RFC2119
<https://datatracker.ietf.org/doc/html/rfc2119>`_] [`RFC8174
<https://datatracker.ietf.org/doc/html/rfc8174>`_] when, and only when, they
appear in all capitals, as shown here.

This policy lists standards that any programmer adding or changing code in PHP
should follow.

**************
Symbol Names
**************

Acronyms
========

Extend the coding standard to explicitly specify how abbreviations and
acronyms/initialisms are to be handled when writing user-level class names. The
current rule is:
Abbreviations and acronyms as well as initialisms SHOULD be avoided wherever
possible.

.. code::
Abbreviations, acronyms, and initialisms MUST be treated like regular words,
thus they should be written with an uppercase first character, followed by
lowercase characters.

Classes should be given descriptive names. Avoid using abbreviations where
possible. Each word in the class name should start with a capital letter,
without underscore delimiters (CamelCaps starting with a capital letter).
The class name should be prefixed with the name of the 'parent set' (e.g.
the name of the extension)::
Diverging from this policy is NOT RECOMMENDED, but it is allowed to keep
internal consistency within a single extension, if the name follows an
established, language-agnostic standard, or for other reasons, if those reasons
are properly justified and voted on as part of the RFC process.

Good:
'Curl'
'FooBar'
Functions
=========

Bad:
'foobar'
'foo_bar'
Function names MUST be in lowercase, with words underscore delimited, with care
taken to minimize the letter count.

— `CODING_STANDARDS
<https://github.com/php/php-src/blob/abac7e81dd7b2e851562c60377951da5a5a99e30/CODING_STANDARDS#L154-L166>`_.
Good function names:

While it is stated that abbreviations should be avoided, it is silent on what to
do if they are used; especially in the case of acronyms/initialisms. There are
essentially three choices possible now:
- ``str_word_count``
- ``array_key_exists``

- **PascalCase except Acronyms/Initialisms** — which is how the majority of
user-level class names are written, and it matches the approach of many other
programming languages.
Bad function names:

- **Always PascalCase** — which is basically what `PSR-1
<http://www.php-fig.org/psr/psr-1/>`_ defines, however, it would make most of
the currently existing user-level class names invalid.
- ``hw_GetObjectByQueryCollObj``
- ``pg_setclientencoding``
- ``jf_n_s_i``

- **Do Nothing** — which of course automatically means that any approach is
allowed, and the community discussions around this topic will continue.
If functions are part of a "parent set" of functions, that parent MUST be
included in the user function name, and should be clearly related to the parent
program or function family. This should be in the form of ``parent_*``:

**IMPORTANT!**: Regardless of the outcome of this RFC, existing user-level class
names are not required to be changed. Although it would be possible (class names
are case-insensitive). The reason why renaming is not proposed is simple: this
RFC would most probably fail because too many people are against such purely
cosmetic changes.
A family of ``foo`` functions, for example:

PascalCase except Acronyms/Initialisms
--------------------------------------
Good names:

**Editor’s note: This section has been superseded by the “Casing of acronyms in
class and method names” section**
- ``foo_select_bar``
- ``foo_insert_baz``
- ``foo_delete_baz``

Class names should be descriptive nouns in PascalCase and as short as possible.
Each word in the class name should start with a capital letter, without
underscore delimiters. The class name should be prefixed with the name of the
"parent set" (e.g. the name of the extension) if no namespaces are used.
Abbreviations and acronyms as well as initialisms should be avoided wherever
possible, unless they are much more widely used than the long form (e.g. HTTP or
URL). Abbreviations start with a capital letter followed by lowercase letters,
whereas acronyms and initialisms are written according to their standard
notation. Usage of acronyms and initialisms is not allowed if they are not
widely adopted and recognized as such.
Bad names:

Good:
- ``fooselect_bar``
- ``fooinsertbaz``
- ``delete_foo_baz``

- ``Curl``
- ``CurlResponse``
- ``HTTPStatusCode``
- ``URL``
- ``BTreeMap`` (B-tree Map)
- ``Id`` (Identifier)
- ``ID`` (Identity Document)
- ``Char`` (Character)
- ``Intl`` (Internationalization)
- ``Radar`` (Radio Detecting and Ranging)
Methods
=======

Bad:

- ``curl``
- ``curl_response``
- ``HttpStatusCode``
- ``Url``
- ``BtreeMap``
- ``ID`` (Identifier)
- ``CHAR``
- ``INTL``
- ``RADAR`` (Radio Detecting and Ranging)

**********************************************
Casing of acronyms in class and method names
**********************************************

From: `Casing of acronyms in class and method names RFC
<https://wiki.php.net/rfc/class-naming-acronyms>`_

The class naming policy should be updated to the following, with changes
highlighted:

Method names follow the studlyCaps (also referred to as bumpy case or camel
caps) naming convention, with care taken to minimize the letter count. The
Method names SHOULD follow the studlyCaps (also referred to as bumpy case or
camel caps) naming convention, with care taken to minimize the letter count. The
initial letter of the name is lowercase, and each letter that starts a new word
is capitalized.

Class names should be descriptive nouns in PascalCase and as short as possible.
Each word in the class name should start with a capital letter, without
underscore delimiters. The class name should be prefixed with the name of the
"parent set" (e.g. the name of the extension) if no namespaces are used.

Abbreviations and acronyms as well as initialisms should be avoided wherever
possible, unless they are much more widely used than the long form (e.g. HTTP or
URL).

.. raw:: html

<s>Abbreviations start with a capital letter followed by lowercase letters, whereas acronyms and initialisms are written according to their standard notation.</s>

**Abbreviations, acronyms, and initialisms should be treated like regular words,
thus they should be written with an uppercase first character, followed by
lowercase characters.**

.. raw:: html

<s>Usage of acronyms and initialisms is not allowed if they are not widely adopted and recognized as such.</s>

**Diverging from this policy is allowed to keep internal consistency within a
single extension, if the name follows an established, language-agnostic
standard, or for other reasons, if those reasons are properly justified and
voted on as part of the RFC process.**

Examples
========

Good method names:

- ``connect()``
@@ -165,6 +89,17 @@ Bad method names:
- ``getI()``
- ``performHTTPRequest()``

Classes
=======

Existing user-level class names are NOT RECOMMENDED to be changed. Although it
would be possible (class names are case-insensitive).

New class names MUST be descriptive nouns in PascalCase and as short as
possible. Each word in the class name MUST start with a capital letter, without
underscore delimiters. The class name MUST be prefixed with the name of the
"parent set" (e.g. the name of the extension) if no namespaces are used.

Good class names:

- ``Curl``
@@ -193,135 +128,62 @@ Bad class names:
- ``SSL\CRL``
- ``SSL\CRLURL``

**************************
Namespaces in Extensions
**************************

From `Namespaces in Bundled Extensions RFC
<https://wiki.php.net/rfc/namespaces_in_bundled_extensions>`_.

Classes and functions provided by bundled PHP extensions are currently all
located in the global namespace (with one exception). There is a strong
sentiment that future additions to PHP's standard library should make use of
namespaces, to the point that otherwise unrelated proposals increasingly
degenerate into namespace-related discussions. This question needs to be
resolved one way or another, to avoid reiterating it for every future addition
to the standard library.
************
Namespaces
************

PHP Extension Classification
============================

All symbols (classes, functions, constants) provided by PHP are part of an
extension. Extensions can be classified into three categories:

- Required extensions (including Core and standard). These extensions are
always present, and PHP cannot be built without them.

- Bundled extensions (including ctype and mbstring). These extensions are part
of the php-src distribution, but PHP can be built without them. Bundled
extensions can be either enabled or disabled by default.

- 3rd-party extensions (including apcu and igbinary). These extensions are not
part of the php-src distribution, and either available through PECL, or
simply on GitHub.

Extensions may move between these three categories over time. hash and json
recently moved from "bundled" to "required" (though I believe extensions never
move out of the "required" category). sodium and ffi moved from 3rd-party to
bundled. xmlrpc and wddx moved from bundled to 3rd-party.

Vendor Namespace
================

Most userland open-source libraries nowadays follow a namespace structure of the
form ``VendorNamespace\PackageNamespace\Symbol``, with all names being at least
two levels deep. PSR-4 itself only requires a top-level namespace and permits
symbols of the form ``TopLevelNamespace\Symbol``.

The concept of a vendor namespace is hard to reconcile with the extension
classification discussed in the previous section, as extensions may move between
different "vendors". It is educative to consider the issues that a
''PHP\Component\Symbol'' name structure would encounter, which was assumed by
many prior RFCs and discussions.

3rd-party extensions clearly cannot start out under a ''PHP'' namespace, as they
have no direct relation to, endorsement by, or oversight of the PHP project. If
all symbols in bundled extensions are to be prefixed by ''PHP'', this would
require a rename of all symbols when an extension moves from 3rd-party to
bundled. While compatibility shims can somewhat mitigate this, such a rename
constitutes an unnecessary disruption to all existing users of the extension, as
well as any documentation relating to it.

Conversely, if a bundled extension is removed from PHP, the question arises
whether it should be moved out of the ''PHP'' namespace. Extensions are
typically unbundled from PHP if they are unmaintained. Retaining them under the
''PHP'' namespace may create the mistaken impression that the PHP project still
maintains such extensions. Of course, changing the vendor prefix on unbundling
would once again disrupt any remaining users.

The `PHP Namespace Policy <https://wiki.php.net/rfc/php_namespace_policy>`_ RFC
(declined) RFC sought to address this by introducing two vendor namespaces for
extensions: ''PHP'' and ''Ext''. The latter may be used by all extensions,
whether they be bundled or 3rd-party. The ''PHP'' namespace would only be
eligible for bundled functionality directly tied to PHP, such as built-in
attributes, altough the exact dividing line is unclear. Most symbols would be
part of the ''Ext'' vendor namespace.

Existing practice
=================

PHP itself only bundles a single extension with namespaced symbols (ffi).
However, there are a number of 3rd-party extensions making use of namespaces.
For extensions present in phpstorm-stubs, the following list summarizes in what
way they utilize namespaces:

- ``ffi`` (bundled): Uses ``FFI`` namespace, e.g. ``FFI\CType``. Also uses
``FFI`` itself.
- ``aerospike``: Uses ``Aerospike`` namespace, e.g. ``Aerospike\Bytes``. Also
uses ``Aerospike`` itself.
- ``cassandra``: Uses ``Cassandra`` namespace, e.g. ``Cassandra\Table``. Also
uses ``Cassandra`` itself.
- ``couchbase``: Uses ``Couchbase`` namespace, e.g. ``Couchbase\Document``.
- ``crypto``: Uses ``Crypto`` namespace, e.g. ``Crypto\PBKDF2``.
- ``decimal``: Uses ``Decimal`` namespace, e.g. ``Decimal\Decimal``.
- ``ds``: Uses ``Ds`` namespace, e.g. ``Ds\Collection``.
- ``grpc``: Uses ``Grpc`` namespace, e.g. ``Grpc\Server``.
- ``http``: Uses ``http`` namespace, e.g. ``http\Client``.
- ``mongodb``: Uses ``MongoDB`` namespace, e.g. ``MongoDB\Driver\Manager``.
- ``mosquitto``: Uses ``Mosquitto`` namespace, e.g. ``Mosquitto\Client``.
- ``mysql_xdevapi``: Uses ``mysql_xdevapi`` namespace, e.g.
``mysql_xdevapi\Collection``.
- ``parallel``: Uses ``parallel`` namespace, e.g. ``parallel\Runtime``.
- ``parle``: Uses ``Parle`` namespace, e.g. ``Parle\Lexer``.
- ``pcov``: Uses ``pcov`` namespace, e.g. ``pcov\start()``.
- ``pq``: Uses ``pq`` namespace, e.g. ``pq\Connection``.
- ``rdkafka``: Uses ``RdKafka`` namespace, e.g. ``RdKafka\Producer``. Also uses
``RdKafka`` itself, and a handful of ``rd_kafka_*()`` functions.
- ``xlswriter``: Uses ``Vtiful\Kernel`` namespace, e.g.
``Vtiful\Kernel\Excel``.
- ``yaf``: Uses ``Yaf`` namespace, e.g. ``Yaf\Application``. Also supports
aliases in the global namespace, e.g. ``Yaf_Application``.
- ``zstd``: Uses ``Zstd`` namespace, e.g. ``Zstd\compress()``. However, it also
declares ``zstd_*()`` functions in the global namespace.

It is notable that with the exception of ``xlswriter``, none of these extensions
make use of a vendor namespace. They all use the package/extension name as the
top-level namespace. Some extensions additionally have a global class that
matches the extension name, e.g. the ffi extension uses both ``FFI`` and
``FFI\CType``.

Proposal
========
- Required extensions (including ``Core`` and ``standard``). These extensions
are always present, and PHP cannot be built without them.

- Bundled extensions (including ``ctype`` and ``mbstring``). These extensions
are part of the php-src distribution, but PHP can be built without them.
Bundled extensions can be either enabled or disabled by default.

- 3rd-party extensions (including ``apcu`` and ``igbinary``). These extensions
are not part of the php-src distribution, and either available through PECL,
or on GitHub.

Extensions may move between these three categories over time. ``hash`` and
``json`` moved from "bundled" to "required", in PHP 7.4 and 8.0 respectively.
``sodium`` and ``ffi`` moved from 3rd-party to bundled. ``xmlrpc`` and ``wddx``
moved from bundled to 3rd-party.

This RFC proposes to explicitly allow and encourage the use of namespaces for
bundled PHP extensions, subject to the guidelines laid out in the following:
Core, Standard, Spl
===================

- Extensions should not use a vendor namespace.
- The top-level namespace should match the extension name (apart from casing).
- Namespace names should follow ``CamelCase``.
- All symbols defined in the extension should be part of the extension's
Symbols MUST NOT be namespaced under the ``Core``, ``Standard`` or ``Spl``
namespaces. Instead, these extensions should be considered as a collection of
different components (``str_*``, ``password_*``), and SHOULD be namespaced
according to these component names.

If a component gets introduced it MAY use a namespace. For example, if a new
component ``vector`` is introduced, it MUST consist of functions all starting
with ``vector_*`` (such as ``vector_multiply()``), OR they MUST all be
namespaced functions under the ``Vector`` namespace, such as
``Vector\multiply()``.

Bundled Extensions
==================

Bundled PHP extensions SHOULD use namespaces, subject to the guidelines laid out
in the following:

- Extensions MUST NOT use a vendor namespace.
- The top-level namespace MUST match the extension name (apart from casing).
- Namespace names MUST follow ``CamelCase``.
- All symbols defined in the extension SHOULD be part of the extension's
top-level namespace or a sub-namespace.

This policy allows the use of namespaces, and provides basic guidelines for
their use. It does not propose to migrate already existing non-namespaced
symbols to use namespaces.

Examples
--------

@@ -332,76 +194,222 @@ the symbol names could change in line with these guidelines:
- ``openssl_dh_compute_key()`` becomes ``OpenSSL\dh_compute_key()``
- ``X509_PURPOSE_SSL_CLIENT`` becomes ``OpenSSL\X509_PURPOSE_SSL_CLIENT``

The above guidelines recommend against the global ``FFI`` class used by the ffi
extension. Using ``FFI\FFI`` would be preferred.
The above guidelines recommend against the global ``FFI`` class used by the
``ffi`` extension. Using ``FFI\FFI`` would be preferred.

Existing Non-Namespaced Symbols and Consistency
===============================================

Core, standard, spl
-------------------
When adding new symbols to existing extensions it is RECOMMENDED to be
consistent with existing symbols, rather than to follow the namespacing
guidelines.

PHP has three extensions that together form the core of the standard library.
The "Core" extension is part of the Zend Engine, and defines a relatively small
number of functions and classes. It contains core types like ``stdClass`` and
``Iterator``, as well as introspection functions like ``get_object_vars()``. The
"standard" extension contains the majority of the standard library functions,
including ``array_*()`` and ``str_*()`` functions. The "spl" extension was
historically the "object-oriented" part of the standard library, containing
data-structures like ``ArrayObject``, exceptions and iterators.
For example, the ``array_is_list()`` function added in PHP 8.1 MUST indeed be
called ``array_is_list()`` and MUST NOT have been introduced as
``Array\is_list()`` or similar. Unless and until existing ``array_*()``
functions are aliased under an ``Array\*`` namespace, new additions MUST
continue to be of the form ``array_*()`` to maintain horizontal consistency.

The distinction between these three extensions is somewhat murky from an
end-user perspective, and largely historical. Symbols have moved between these
extensions, e.g. the ``Iterator`` interface originated in spl, but now lives in
Core.
This is a somewhat loose guideline, and applies more strongly to functions than
classes. In particular, when new object-oriented elements are introduced into an
extension that has historically been procedural, these MAY be namespaced. For
example, if ``OpenSSLCertificate`` had only been introduced in PHP 8.1, it could
have been named ``OpenSSL\Certificate``.

Because these extensions combine a lot of unrelated or only tangentially related
functionality, symbols should not be namespaced under the ``Core``, ``Standard``
or ``Spl`` namespaces. Instead, these extensions should be considered as a
collection of different components, and should be namespaced according to these.
For the Core, Standard, and Spl extensions, the previous considerations on
component subdivision apply. The fact that string and array functions are not
namespaced does not preclude new namespaced components in these extensions.

For example, ``str_contains()`` could become ``Str\contains()``, ``fopen()``
could become ``File\open()``, and ``password_hash()`` could become
``Password\hash()``. (These are non-normative examples, the RFC does not propose
using these specific namespaces.)
Namespace Collisions
====================

Existing non-namespaces symbols and consistency
-----------------------------------------------
As a matter of courtesy, top-level namespaces used by extensions SHOULD avoid
collisions with existing, commonly used open-source libraries or extensions (or
happen with the agreement of the parties involved). This document does not try
to provide a hard guideline on what constitutes a sufficiently important
library. The application of common sense is recommended.

When adding new symbols to existing extensions, it is more important to be
consistent with existing symbols than to follow the namespacing guidelines.
************************
Implementation Details
************************

For example, the ``array_is_list()`` function added in PHP 8.1 should indeed be
called ``array_is_list()`` and should not be introduced as ``Array\is_list()``
or similar. Unless and until existing ``array_*()`` functions are aliased under
an ``Array\*`` namespace, new additions should continue to be of the form
``array_*()`` to maintain horizontal consistency.
#. Document your code in source files and the manual. (tm)

This is a somewhat loose guideline, and applies more strongly to functions than
classes. In particular, when new object-oriented elements are introduced into an
extension that has historically been procedural, these may be namespaced. For
example, if ``OpenSSLCertificate`` had only been introduced in PHP 8.1, it
should have been named ``OpenSSL\Certificate``.
#. PHP is implemented in C11.

For the Core/standard/spl extensions, the previous considerations on component
subdivision apply. The fact that string and array functions are not namespaced
does not preclude new namespaced components in these extensions.
For instance, the optional fixed-width integers from ``stdint.h``
(``int8_t``, ``int16_t``, ``int32_t``, ``int64_t`` and their unsigned
counterparts) are supposed to be available.

Namespace collisions
--------------------
#. Functions that are given pointers to resources SHOULD NOT free them, unless
this is documented.
Comment on lines +244 to +245
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This really depends on the function and logic. I think this whole think should be removed as well as it's context dependent.


The disadvantage of not using a vendor namespace is that namespace collisions
are more likely. A mitigating factor is the pervasive use of vendor namespaces
in the userland ecosystem (in which case the collision would have to be between
a vendor namespace and a component namespace, which is less likely).
For instance, ``function int mail(char *to, char *from)`` should NOT free
``to`` and/or ``from``.

As a matter of courtesy, top-level namespaces used by extensions should avoid
collisions with existing, commonly used open-source libraries or extensions (or
happen with the agreement of the parties involved). This RFC does not try to
provide a hard guideline on what constitutes a sufficiently important library.
The application of common sense is recommended.
Exceptions:

- The function's designated behavior is freeing that resource. E.g.
``efree()``.

- The function is given a boolean argument, that controls whether or not the
function may free its arguments (if ``true``, the function must free its
arguments; if ``false``, it must not).

- Low-level parser routines, that are tightly integrated with the token
cache and the bison code for minimum memory copying overhead.

#. Functions that are tightly integrated with other functions within the same
module, and rely on each other's non-trivial behavior, MUST be documented as
such and declared ``static``.

#. You SHOULD use definitions and macros whenever possible, so that constants
have meaningful names and can be easily manipulated. Any use of a numeric
constant to specify different behavior or actions SHOULD be done through a
``#define``.

#. When writing functions that deal with strings, you SHOULD use
``zend_string``, which holds the value and the length property of each
string.

Write your functions in such a way so that they'll take advantage of the
length property by using ``ZSTR_LEN()``, both for efficiency, and in order
for them to be binary-safe.

#. You SHOULD use the ``smart_str_*`` family of functions for string creation,
instead of relying on the C-library versions, such as ``strncat()``.
Comment on lines +279 to +280
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

smart_str_* should be used only if the string is constructed with multiple variable pieces. Otherwise basic creation should be done using zend_string_alloc and similar (e.g. short concatenations using zend_string_concat2 and zend_string_concat3).

That said I'm not really sure why this is in coding standard. This should really be part of some extension documentation like in doc/ or php internals book.


#. You SHOULD use ``PHP_*`` macros in the PHP source, and ``ZEND_*`` macros in
the Zend part of the source. Although the ``PHP_*`` macros are mostly aliased
to the ``ZEND_*`` macros it gives a better understanding on what kind of
macro you're calling.

#. You MUST NOT define functions that are not available. For instance, if a
library is missing a function, do not define the PHP version of the function,
and do not raise a run-time error about the function not existing. End users
should use ``function_exists()`` to test for the existence of a function.

#. You SHOULD use ``emalloc()``, ``efree()``, ``estrdup()``, instead of their
standard C library counterparts. These functions implement an internal
"safety-net" mechanism that ensures the deallocation of any unfreed memory at
the end of a request. They also provide useful allocation and overflow
information while running in debug mode.

In almost all cases, memory returned to the engine must be allocated using
``emalloc()``.

The use of ``malloc()`` SHOULD be limited to cases where a third-party
library may need to control or free the memory, or when the memory in
question needs to survive between multiple requests.

#. The return type of "is" or "has" style functions SHOULD be ``bool`` which
return a "yes"/"no" answer. `zend_result` is an appropriate return value for
functions that perform some operation that may succeed or fail.

Variable Names
==============

Variable names MUST be meaningful. One letter variable names SHOULD be avoided,
except for places where the variable has no real meaning or a trivial meaning
(e.g. ``for (i=0; i<100; i++) ...``).

Variable names MUST be in lowercase. Use underscores to separate between words.

Internal Function Naming Conventions
====================================

The main module source file MUST be named ``modulename.c``.

Header files that are used by other sources must be named ``php_modulename.h``.

Functions that are part of the external API MUST be named
``php_modulename_function()`` to avoid symbol collision. They MUST be in
lowercase, with words underscore delimited. Exposed API MUST be defined in
``php_modulename.h``:

.. code::
PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS);
Unexposed module function MUST be ``static`` and MUST NOT be defined in
`php_modulename.h`:

.. code::
static int php_session_destroy()
Syntax and indentation
======================

You SHOULD Use K&R-style. When you write code that goes into the core of PHP or
one of its standard modules, please maintain the K&R style.

Be generous with whitespace and braces. Keep one empty line between the variable
declaration section and the statements in a block, as well as between logical
statement groups in a block. Maintain at least one empty line between two
functions. Always prefer:

.. code::
if (foo) {
bar;
}
to:

.. code::
if(foo)bar;
You MUST use the tab character when indenting. A tab is expected to represent
four spaces. It is important to maintain consistency in indentation so that
definitions, comments, and control structures line up correctly.

Preprocessor statements (``#if`` and such) MUST start at column one. To indent
preprocessor directives you should put the ``#`` at the beginning of a line,
followed by any number of spaces.

The length of constant string literals SHOULD be calculated via ``strlen()``
instead of using ``sizeof()-1`` as it is clearer and any modern compiler will
optimize it away. Legacy usages of the latter style exists within the codebase
but SHOULD NOT be refactored, unless larger refactoring around that code is
taking place.

Testing
=======

Extensions SHOULD be well tested using ``*.phpt`` tests. Read more at
`qa.php.net documentation <https://qa.php.net/write-test.php>`_.

Experimental Functions
======================

New extensions MUST start out as third-party extensions, or in an experimental
branch, until an RFC is passed to add them to the core distribution.
Comment on lines +387 to +388
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would scrap the whole section as it's just given that you cannot introduce a new extension without the RFC so the rest are just implications that don't need to be specified here.


Aliases & Legacy Documentation
==============================

You may also have some deprecated aliases with close to duplicate names, for
example, ``somedb_select_result`` and ``somedb_selectresult``. For documentation
purposes, these will only be documented by the most current name, with the
aliases listed in the documentation for the parent function. For ease of
reference, user-functions with completely different names, that alias to the
same function (such as ``highlight_file`` and ``show_source``), will be
separately documented.

Backwards compatible functions and names SHOULD be maintained as long as the
code can be reasonably be kept as part of the codebase. See the `README in the
PHP documentation repository
<https://github.com/php/doc-base/blob/master/README.md>`_ for more information
on documentation.

Future Scope
------------
**************
Related RFCs
**************

This RFC only officially allows use of namespaces, and provides basic guidelines
for their use. However, it does not propose to migrate already existing
non-namespaced symbols to use namespaces. Such a migration should be the subject
of a separate RFC.
- From: `Class Naming RFC <https://wiki.php.net/rfc/class-naming>`_
- From: `Casing of acronyms in class and method names RFC
<https://wiki.php.net/rfc/class-naming-acronyms>`_
- From `Namespaces in Bundled Extensions RFC
<https://wiki.php.net/rfc/namespaces_in_bundled_extensions>`_.