diff --git a/wordpress-coding-standards/php.md b/wordpress-coding-standards/php.md index 9b600cd..018bb27 100644 --- a/wordpress-coding-standards/php.md +++ b/wordpress-coding-standards/php.md @@ -2,11 +2,14 @@ Some parts of the WordPress code structure for PHP markup are inconsistent in their style. WordPress is working to gradually improve this by helping users maintain a consistent style so the code can become clean and easy to read at a glance. -Keep the following points in mind when writing PHP code for WordPress, whether for core programming code, plugins, or themes. The guidelines are similar to Pear standards in many ways, but differ in some key respects. +Keep the following points in mind when writing PHP code for WordPress, whether for core programming code, plugins, or themes. The guidelines are similar to [Pear standards](https://pear.php.net/manual/en/standards.php) in many ways, but differ in some key respects. + +See also: [PHP Inline Documentation Standards](https://developer.wordpress.org/coding-standards/inline-documentation-standards/php/). + +## PHP + +### Single and Double Quotes -See also: PHP Documentation Standards. -
esc_attr()
so that single or double quotes do not end the attribute value and invalidate the HTML and cause a security issue. See Data Validation in the Codex for further details.
-switch
structures case
should indent one tab from the switch
statement and break
one tab from the case
statement.
+For `switch` structures `case` should indent one tab from the `switch` statement and `break` one tab from the `case` statement.
```php
switch ( $type ) {
@@ -67,8 +72,10 @@ switch ( $type ) {
}
```
-Rule of thumb: Tabs should be used at the beginning of the line for indentation, while spaces can be used mid-line for alignment.
-if
/endif
, while
/endwhile
)—especially in your templates where PHP code is embedded within HTML, for instance:
+Note that requiring the use of braces just means that _single-statement inline control structures_ are prohibited. You are free to use the [alternative syntax for control structures](https://www.php.net/manual/en/control-structures.alternative-syntax.php) (e.g. `if`/`endif`, `while`/`endwhile`)—especially in your templates where PHP code is embedded within HTML, for instance:
```php
@@ -118,16 +125,17 @@ Note that requiring the use of braces just means that single-statement inlin
```
-elseif
, not else if
else if
is not compatible with the colon syntax for if|elseif
blocks. For this reason, use elseif
for conditionals.
+### Use `elseif`, not `else if`
+
+`else if` is not compatible with the colon syntax for `if|elseif` blocks. For this reason, use `elseif` for conditionals.
-array( 1, 2, 3 )
) for declaring arrays is generally more readable than short array syntax ( [ 1, 2, 3 ]
), particularly for those with vision difficulties. Additionally, it's much more descriptive for beginners.
+Using long array syntax ( `array( 1, 2, 3 )` ) for declaring arrays is generally more readable than short array syntax ( `[ 1, 2, 3 ]` ), particularly for those with vision difficulties. Additionally, it's much more descriptive for beginners.
Arrays must be declared using long array syntax.
-remove_action()
/ remove_filter()
(see #46635 for a proposal to address this).
+Closures must not be passed as filter or action callbacks, as they cannot be removed by `remove_action()` / `remove_filter()` (see [#46635](https://core.trac.wordpress.org/ticket/46635 "Improve identifying of non–trivial callbacks in hooks") for a proposal to address this).
-preg_
functions) should be used in preference to their POSIX counterparts. Never use the /e
switch, use preg_replace_callback
instead.
+### Regular Expressions
-It's most convenient to use single-quoted strings for regular expressions since, contrary to double-quoted strings, they have only two metasequences: \'
and \\
.
+Perl compatible regular expressions ([PCRE](https://www.php.net/pcre), `preg_` functions) should be used in preference to their POSIX counterparts. Never use the `/e` switch, use `preg_replace_callback` instead.
+It's most convenient to use single-quoted strings for regular expressions since, contrary to double-quoted strings, they have only two metasequences: `\'` and `\\`.
+
+### Opening and Closing PHP Tags
-if
, elseif
, foreach
, for
, and switch
blocks.
+Put spaces on both sides of the opening and closing parentheses of `if`, `elseif`, `foreach`, `for`, and `switch` blocks.
```php
foreach ( $foo as $bar ) { ...
@@ -266,7 +279,7 @@ When performing logical comparisons, do it like so:
if ( ! $foo ) { ...
```
-Type casts must be lowercase. Always prefer the short form of type casts, (int)
instead of (integer)
and (bool)
rather than (boolean)
. For float casts use (float)
.:
+[Type casts](https://www.php.net/manual/en/language.types.type-juggling.php#language.types.typecasting) must be lowercase. Always prefer the short form of type casts, `(int)` instead of `(integer)` and `(bool)` rather than `(boolean)`. For float casts use `(float)`.:
```php
foreach ( (array) $foo as $bar ) { ...
@@ -287,7 +300,7 @@ $x = $foo[ $bar ]; // correct
$x = $foo[$bar]; // incorrect
```
-In a switch
block, there must be no space before the colon for a case statement.
+In a `switch` block, there must be no space before the colon for a case statement.
```php
switch ( $foo ) {
@@ -312,12 +325,13 @@ if ( $foo && ( $bar || $baz ) ) { ...
my_function( ( $x - 1 ) * 5, $y );
```
-UPDATE
or WHERE
.
+### Formatting SQL statements
-Functions that update the database should expect their parameters to lack SQL slash escaping when passed. Escaping should be done as close to the time of the query as possible, preferably by using $wpdb->prepare()
+When formatting SQL statements you may break it into several lines and indent if it is sufficiently complex to warrant it. Most statements work well as one line though. Always capitalize the SQL parts of the statement like `UPDATE` or `WHERE`.
-$wpdb->prepare()
is a method that handles escaping, quoting, and int-casting for SQL queries. It uses a subset of the sprintf()
style of formatting. Example :
+Functions that update the database should expect their parameters to lack SQL slash escaping when passed. Escaping should be done as close to the time of the query as possible, preferably by using `$wpdb->prepare()`
+
+`$wpdb->prepare()` is a method that handles escaping, quoting, and int-casting for SQL queries. It uses a subset of the `sprintf()` style of formatting. Example :
```php
$var = "dangerous'"; // raw data that may or may not need to be escaped
@@ -326,15 +340,19 @@ $id = some_foo_number(); // data we expect to be an integer, but we're not certa
$wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_title = %s WHERE ID = %d", $var, $id ) );
```
-%s
is used for string placeholders and %d
is used for integer placeholders. Note that they are not 'quoted'! $wpdb->prepare()
will take care of escaping and quoting for us. The benefit of this is that we don't have to remember to manually use esc_sql()
, and also that it is easy to see at a glance whether something has been escaped or not, because it happens right when the query happens.
+`%s` is used for string placeholders and `%d` is used for integer placeholders. Note that they are not 'quoted'! `$wpdb->prepare()` will take care of escaping and quoting for us. The benefit of this is that we don't have to remember to manually use [`esc_sql()`](https://developer.wordpress.org/reference/functions/esc_sql/), and also that it is easy to see at a glance whether something has been escaped or not, because it happens right when the query happens.
+
+See [Data Validation](https://developer.wordpress.org/plugins/security/data-validation/) in the Plugin Handbook for further details.
+
+### Database Queries
-See Data Validation in the Codex for more information.
-camelCase
). Separate words via underscores. Don't abbreviate variable names unnecessarily; let the code be unambiguous and self-documenting.
+If you must touch the database, get in touch with some developers by posting a message to the [wp-hackers mailing list](https://codex.wordpress.org/Mailing_Lists#Hackers). They may want to consider creating a function for the next WordPress version to cover the functionality you wanted.
+
+### Naming Conventions
+
+Use lowercase letters in variable, action/filter, and function names (never `camelCase`). Separate words via underscores. Don't abbreviate variable names unnecessarily; let the code be unambiguous and self-documenting.
```php
function some_name( $some_variable ) { [...] }
@@ -359,21 +377,21 @@ Files should be named descriptively using lowercase letters. Hyphens should sepa
my-plugin-name.php
```
-Class file names should be based on the class name with class-
prepended and the underscores in the class name replaced with hyphens, for example WP_Error
becomes:
+Class file names should be based on the class name with `class-` prepended and the underscores in the class name replaced with hyphens, for example `WP_Error` becomes:
```php
class-wp-error.php
```
-This file-naming standard is for all current and new files with classes. There is one exception for three files that contain code that got ported into BackPress: class.wp-dependencies.php, class.wp-scripts.php, class.wp-styles.php. Those files are prepended with class.
, a dot after the word class instead of a hyphen.
+This file-naming standard is for all current and new files with classes. There is one exception for three files that contain code that got ported into BackPress: `class.wp-dependencies.php`, `class.wp-scripts.php`, `class.wp-styles.php`. Those files are prepended with `class.`, a dot after the word class instead of a hyphen.
-Files containing template tags in wp-includes
should have -template
appended to the end of the name so that they are obvious.
+Files containing template tags in `wp-includes` should have `-template` appended to the end of the name so that they are obvious.
```php
general-template.php
```
-true
and false
when calling functions.
+### Self-Explanatory Flag Values for Function Arguments
+
+Prefer string values to just `true` and `false` when calling functions.
```php
// Incorrect
@@ -421,7 +440,7 @@ eat( 'mushrooms', 'slowly' );
eat( 'dogfood', 'quickly' );
```
-When more words are needed to describe the function parameters, an $args
array may be a better pattern.
+When more words are needed to describe the function parameters, an `$args` array may be a better pattern.
```php
// Even Better
@@ -431,20 +450,23 @@ function eat( $what, $args ) {
eat ( 'noodles', array( 'speed' => 'moderate' ) );
```
-{$new_status}_{$post->post_type}
(publish_post).
+Dynamic hooks are hooks that include dynamic values in their tag name, e.g. `{$new_status}_{$post->post_type}` (publish_post).
-Variables used in hook tags should be wrapped in curly braces {
and }
, with the complete outer tag name wrapped in double quotes. This is to ensure PHP can correctly parse the given variables' types within the interpolated string.
+Variables used in hook tags should be wrapped in curly braces `{` and `}`, with the complete outer tag name wrapped in double quotes. This is to ensure PHP can correctly parse the given variables' types within the interpolated string.
```php
do_action( "{$new_status}_{$post->post_type}", $post->ID, $post );
```
-Where possible, dynamic values in tag names should also be as succinct and to the point as possible. $user_id
is much more self-documenting than, say, $this->id
.
-! empty()
, as testing for false here is generally more intuitive.)
+Where possible, dynamic values in tag names should also be as succinct and to the point as possible. `$user_id` is much more self-documenting than, say, `$this->id`.
+
+### Ternary Operator
+
+[Ternary operators](https://www.php.net/manual/en/language.operators.comparison.php#language.operators.comparison.ternary) are fine, but always have them test if the statement is true, not false. Otherwise, it just gets confusing. (An exception would be using `! empty()`, as testing for false here is generally more intuitive.)
The short ternary operator must not be used.
@@ -456,7 +478,7 @@ $musictype = ( 'jazz' === $music ) ? 'cool' : 'blah';
// (if field is not empty ) ? (do this) : (else, do this);
```
-true
. If the statement were the other way around ( $the_force = true )
, the assignment would be perfectly valid, returning 1
, causing the if statement to evaluate to true
, and you could be chasing that bug for a while.
+In the above example, if you omit an equals sign (admit it, it happens even to the most seasoned of us), you'll get a parse error, because you can't assign to a constant like `true`. If the statement were the other way around `( $the_force = true )`, the assignment would be perfectly valid, returning `1`, causing the if statement to evaluate to `true`, and you could be chasing that bug for a while.
A little bizarre, it is, to read. Get used to it, you will.
-This applies to ==, !=, ===, and !==. Yoda conditions for <, >, <= or >= are significantly more difficult to read and are best avoided.
-switch
statement, it's okay to have multiple empty cases fall through to a common block. If a case contains a block, then falls through to the next block, however, this must be explicitly commented.
+In a `switch` statement, it's okay to have multiple empty cases fall through to a common block. If a case contains a block, then falls through to the next block, however, this must be explicitly commented.
```php
switch ( $foo ) {
@@ -542,28 +566,36 @@ switch ( $foo ) {
}
```
-The goto
statement must never be used.
+The `goto` statement must never be used.
-The eval()
construct is very dangerous, and is impossible to secure. Additionally, the create_function()
function, which internally performs an eval()
, is deprecated in PHP 7.2. Both of these must not be used.
+The `eval()` construct is _very dangerous_, and is impossible to secure. Additionally, the `create_function()` function, which internally performs an `eval()`, is deprecated in PHP 7.2. Both of these must not be used.
+
+### Error Control Operator `@`
+
+As noted in the [PHP docs](https://www.php.net/manual/en/language.operators.errorcontrol.php):
+
+> PHP supports one error control operator: the at sign (@). When prepended to an expression in PHP, any error messages that might be generated by that expression will be ignored.
-@
PHP supports one error control operator: the at sign (@). When prepended to an expression in PHP, any error messages that might be generated by that expression will be ignored.While this operator does exist in Core, it is often used lazily instead of doing proper error checking. Its use is highly discouraged, as even the PHP docs also state: -
Warning: Currently the "@" error-control operator prefix will even disable error reporting for critical errors that will terminate script execution. Among other things, this means that if you use "@" to suppress errors from a certain function and either it isn't available or has been mistyped, the script will die right there with no indication as to why.-
extract()
extract()
is a terrible function that makes code harder to debug and harder to understand. We should discourage it's [sic] use and remove all of our uses of it.
-
-Joseph Scott has a good write-up of why it's bad.
-@
). See #wordpress-dev.