Files
molenda.net/eeeeee/php_text.txt
T
Sebastian Molenda ab96d82fcf init
2026-05-12 21:10:38 +02:00

16632 lines
570 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Booleans
The bool type only has two values, and is used to express
a truth value. It can be either or .
Syntax
To specify a bool literal, use the constants or
. Both are case-insensitive.
Typically, the result of an operator
which returns a bool value is passed on to a
control structure.
Converting to boolean
To explicitly convert a value to bool, use the
(bool) cast. Generally this is not necessary because when
a value is used in a logical context it will be automatically interpreted
as a value of type bool. For more information see the
Type Juggling page.
When converting to bool, the following values are considered
:
the boolean itself
the integer
0 (zero)
the floats
0.0 and -0.0 (zero)
the empty string "",
and the string "0"
an array with zero elements
the unit type NULL (including
unset variables)
Internal objects that overload their casting behaviour to bool.
For example: SimpleXML objects
created from empty elements without attributes.
Every other value is considered
(including resource
and NAN).
-1 is considered , like any other non-zero
(whether negative or positive) number!
Casting to Boolean
Integers
An int is a number of the set
= {..., -2, -1, 0, 1, 2, ...}.
Floating point numbers
Arbitrary precision / BCMath
Arbitrary length integer / GMP
Syntax
Ints can be specified in decimal (base 10), hexadecimal
(base 16), octal (base 8) or binary (base 2) notation.
The negation operator
can be used to denote a negative int.
To use octal notation, precede the number with a 0 (zero).
As of PHP 8.1.0, octal notation can also be preceded with 0o or 0O.
To use hexadecimal notation precede the number with 0x.
To use binary notation precede the number with 0b.
As of PHP 7.4.0, integer literals may contain underscores (_) between digits,
for better readability of literals. These underscores are removed by PHP's scanner.
Integer literals
Formally, the structure for int literals is as of PHP 8.1.0
(previously, the 0o or 0O octal
prefixes were not allowed, and prior to PHP 7.4.0 the underscores were
not allowed):
The size of an int is platform-dependent, although a maximum
value of about two billion is the usual value (that's 32 bits signed).
64-bit platforms usually have a maximum value of about 9E18.
PHP does not support unsigned ints.
int size can be determined
using the constant PHP_INT_SIZE, maximum value using
the constant PHP_INT_MAX,
and minimum value using the constant PHP_INT_MIN.
Integer overflow
If PHP encounters a number beyond the bounds of the int
type, it will be interpreted as a float instead. Also, an
operation which results in a number beyond the bounds of the
int type will return a float instead.
Integer overflow
Integer division
There is no int division operator in PHP, to achieve this
use the intdiv function.
1/2 yields the float 0.5.
The value can be cast to an int to round it towards zero, or
the round function provides finer control over rounding.
Divisions
Converting to integer
To explicitly convert a value to int, use the (int) cast.
However, in most cases the cast is not needed, since a value will be automatically
converted if an operator, function or control structure requires an
int argument. A value can also be converted to
int with the intval function.
If a resource is converted to an int, then
the result will be the unique resource number assigned to the
resource by PHP at runtime.
See also Type Juggling.
From booleans
will yield 0 (zero), and will yield
1 (one).
From floating point numbers
When converting from float to int, the number
will be rounded towards zero.
As of PHP 8.1.0, a deprecation notice is emitted when implicitly converting a non-integral to which loses precision.
Casting from Float
If the float is beyond the boundaries of int (usually
+/- 2.15e+9 = 2^31 on 32-bit platforms and
+/- 9.22e+18 = 2^63 on 64-bit platforms),
the result is undefined, since the float doesn't
have enough precision to give an exact int result.
No warning, not even a notice will be issued when this happens!
NaN, Inf and -Inf will always be zero when cast to int.
Never cast an unknown fraction to int, as this can
sometimes lead to unexpected results.
See also the warning about float
precision.
From strings
If the string is
numeric
or leading numeric then it will resolve to the
corresponding integer value, otherwise it is converted to zero
(0).
From NULL
is always converted to zero (0).
From other types
The behaviour of converting to int is undefined for other
types. Do not rely on any observed behaviour, as it
can change without notice.
Callables
A callable is a reference to a function or method that is passed to
another function as an argument.
They are represented with the callable type declaration.
Some functions accept callback functions as a parameter, e.g.
array_map, usort, or
preg_replace_callback.
Creation of callables
A callable is a type that represents something that can be invoked.
Callables can be passed as arguments to functions or methods which
expect a callback parameter or they can be invoked directly.
The callable type cannot be used as a type declaration for class
properties. Instead, use a Closure type declaration.
Callables can be created in several different ways:
Closure object
containing the name of a function or a method
containing a class name or an object
in index 0 and the method name in index 1
implementing the __invoke()
magic method
A Closure object can be created using
anonymous function syntax,
arrow function syntax,
first-class callable
syntax, or the Closure::fromCallable method.
The first-class
callable syntax is only available as of PHP 8.1.0.
Callback example using a Closure
A callable can also be a string containing the name of a function or
a static method.
Any built-in or user-defined function can be used, except language constructs
such as: array, echo,
empty, eval,
isset,
list, print or
unset.
Static class methods can be used without instantiating an
object of that class by either, creating an array with
the class name at index 0 and the method name at index 1, or by using
the special syntax with the scope resolution operator
::, as in 'ClassName::methodName'.
A method of an instantiated object can be a callable
when provided as an array with the object at index 0 and
the method name at index 1.
The main difference between a Closure object and the
callable type is that a Closure object is
scope-independent and can always be invoked, whereas a callable type may be
scope-dependent and may not be directly invoked.
Closure is the preferred way to create callables.
While Closure objects are bound to the scope
where they are created, callables referencing class methods as strings
or arrays are resolved in the scope where they are called.
To create a callable from a private or protected method, which can then be
invoked from outside the class scope, use
Closure::fromCallable or the
first-class callable
syntax.
PHP allows the creation of callables which can be used as a callback argument
but cannot be called directly.
These are context-dependent callables which reference a class method in the
inheritance hierarchy of a class, e.g.
'parent::method' or ["static", "method"].
As of PHP 8.2.0, context-dependent callables
are deprecated. Remove the context dependency by replacing
'parent::method' with
parent::class . '::method' or use the
first-class callable
syntax.
Calling various types of callables with call_user_function
Never
never is a return-only type indicating the function
does not terminate. This means that it either calls exit,
throws an exception, or is an infinite loop.
Therefore, it cannot be part of a
union type
declaration. Available as of PHP 8.1.0.
never is, in type theory parlance, the bottom type.
Meaning it is the subtype of every other type and can replace any other
return type during inheritance.
Floating point numbers
Floating point numbers (also known as "floats", "doubles", or "real numbers")
can be specified using any of the following syntaxes:
Formally as of PHP 7.4.0 (previously, underscores have not been allowed):
The size of a float is platform-dependent, although a maximum of approximately 1.8e308
with a precision of roughly 14 decimal digits is a common value (the 64 bit IEEE
format).
Floating point precision
Floating point numbers have limited precision. Although it depends on the
system, PHP typically uses the IEEE 754 double precision format, which will
give a maximum relative error due to rounding in the order of 1.11e-16.
Non elementary arithmetic operations may give larger errors, and, of course,
error propagation must be considered when several operations are
compounded.
Additionally, rational numbers that are exactly representable as floating
point numbers in base 10, like 0.1 or
0.7, do not have an exact representation as floating
point numbers in base 2, which is used internally, no matter the size of
the mantissa. Hence, they cannot be converted into their internal binary
counterparts without a small loss of precision. This can lead to confusing
results: for example, floor((0.1+0.7)*10) will usually
return 7 instead of the expected 8,
since the internal representation will be something like
7.9999999999999991118....
So never trust floating number results to the last digit, and do not compare
floating point numbers directly for equality. If higher precision is
necessary, the arbitrary precision math functions
and gmp functions are available.
For a "simple" explanation, see the floating point guide
that's also titled "Why dont my numbers add up?"
Converting to float
From strings
If the string is
numeric
or leading numeric then it will resolve to the
corresponding float value, otherwise it is converted to zero
(0).
From other types
For values of other types, the conversion is performed by converting the
value to int first and then to float. See
Converting to integer
for more information.
As certain types have undefined behavior when converting to
int, this is also the case when converting to
float.
Comparing floats
As noted in the warning above, testing floating point values for equality is
problematic, due to the way that they are represented internally. However,
there are ways to make comparisons of floating point values that work around
these limitations.
To test floating point values for equality, an upper bound on the relative
error due to rounding is used. This value is known as the machine epsilon,
or unit roundoff, and is the smallest acceptable difference in calculations.
$a and $b are equal to 5 digits of
precision.
Comparing Floats
NaN
Some numeric operations can result in a value represented by the constant
NAN. This result represents an undefined or
unrepresentable value in floating-point calculations. Any loose or strict
comparisons of this value against any other value, including itself, but except , will
have a result of .
Because NAN represents any number of different values,
NAN should not be compared to other values, including
itself, and instead should be checked for using is_nan.
Enumerations
Basic Enumerations
Enumerations are a restricting layer on top of classes and class constants,
intended to provide a way to define a closed set of possible values for a type.
For a full discussion, see the
Enumerations chapter.
Casting
If an enum is converted to an object, it is not
modified. If an enum is converted to an array,
an array with a single name key (for Pure enums) or
an array with both name and value keys
(for Backed enums) is created. All other cast types will result in an error.
Arrays
For a list of all array functions, see the array functions chapter in the documentation.
An array in PHP is actually an ordered map. A map is a type that
associates values to keys. This type
is optimized for several different uses; it can be treated as an array,
list (vector), hash table (an implementation of a map), dictionary,
collection, stack, queue, and probably more. As array values can
be other arrays, trees and multidimensional arrays
are also possible.
Explanation of those data structures is beyond the scope of this manual, but
at least one example is provided for each of them. For more information, look
towards the considerable literature that exists about this broad topic.
Syntax
Specifying with array
An array can be created using the array
language construct. It takes any number of comma-separated
key => value pairs
as arguments.
The comma after the last array element is optional and can be omitted. This is usually done
for single-line arrays, i.e. array(1, 2) is preferred over
array(1, 2, ). For multi-line arrays on the other hand the trailing comma
is commonly used, as it allows easier addition of new elements at the end.
A short array syntax exists which replaces
array() with [].
A simple array
The key can either be an int
or a string. The value can be
of any type.
Additionally the following key casts will occur:
Strings containing valid decimal ints, unless the number is preceded by a + sign, will be cast to the
int type. E.g. the key "8" will actually be
stored under 8. On the other hand "08" will
not be cast, as it isn't a valid decimal integer.
Floats are also cast to ints, which means that the
fractional part will be truncated. E.g. the key 8.7 will actually
be stored under 8.
Bools are cast to ints, too, i.e. the key
will actually be stored under 1
and the key under 0.
Null will be cast to the empty string, i.e. the key
null will actually be stored under "".
Arrays and objects can not be used as keys.
Doing so will result in a warning: Illegal offset type.
Strings containing valid decimal ints, unless the number is preceded by a + sign, will be cast to the
int type. E.g. the key "8" will actually be
stored under 8. On the other hand "08" will
not be cast, as it isn't a valid decimal integer.
Floats are also cast to ints, which means that the
fractional part will be truncated. E.g. the key 8.7 will actually
be stored under 8.
Bools are cast to ints, too, i.e. the key
will actually be stored under 1
and the key under 0.
Null will be cast to the empty string, i.e. the key
null will actually be stored under "".
Arrays and objects can not be used as keys.
Doing so will result in a warning: Illegal offset type.
If multiple elements in the array declaration use the same key, only the last one
will be used as all others are overwritten.
Type Casting and Overwriting example
As all the keys in the above example are cast to 1, the value will be overwritten
on every new element and the last assigned value "d" is the only one left over.
PHP arrays can contain int and string keys at the same time
as PHP does not distinguish between indexed and associative arrays.
Mixed int and string keys
The key is optional. If it is not specified, PHP will
use the increment of the largest previously used int key.
Indexed arrays without key
It is possible to specify the key only for some elements and leave it out for others:
Keys not on all elements
As you can see the last value "d" was assigned the key
7. This is because the largest integer key before that
was 6.
Complex Type Casting and Overwriting example
This example includes all variations of type casting of keys and overwriting
of elements.
Negative index example
When assigning a negative integer key n, PHP will take care to
assign the next key to n+1.
Prior to PHP 8.3.0, assigning a negative integer key n would
assign the next key to 0, the previous example would
therefore output:
Accessing array elements with square bracket syntax
Array elements can be accessed using the array[key] syntax.
Accessing array elements
Prior to PHP 8.0.0, square brackets and curly braces could be used interchangeably
for accessing array elements (e.g. $array[42] and $array{42}
would both do the same thing in the example above).
The curly brace syntax was deprecated as of PHP 7.4.0 and no longer supported as of PHP 8.0.0.
Array dereferencing
Attempting to access an array key which has not been defined is
the same as accessing any other undefined variable:
an E_WARNING-level error message
(E_NOTICE-level prior to PHP 8.0.0) will be
issued, and the result will be .
Array dereferencing a scalar value which is not a string
yields . Prior to PHP 7.4.0, that did not issue an error message.
As of PHP 7.4.0, this issues E_NOTICE;
as of PHP 8.0.0, this issues E_WARNING.
Creating/modifying with square bracket syntax
An existing array can be modified by explicitly setting values
in it.
This is done by assigning values to the array, specifying the
key in brackets. The key can also be omitted, resulting in an empty pair of
brackets ([]).
If $arr doesn't exist yet or is set to or , it will be created, so this is
also an alternative way to create an array. This practice is
however discouraged because if $arr already contains
some value (e.g. string from request variable) then this
value will stay in the place and [] may actually stand
for string access
operator. It is always better to initialize a variable by a direct
assignment.
As of PHP 7.1.0, applying the empty index operator on a string throws a fatal
error. Formerly, the string was silently converted to an array.
As of PHP 8.1.0, creating a new array from value is deprecated.
Creating a new array from and undefined values is still allowed.
To change a certain
value, assign a new value to that element using its key. To remove a
key/value pair, call the unset function on it.
Using Square Brackets with Arrays
As mentioned above, if no key is specified, the maximum of the existing
int indices is taken, and the new key will be that maximum
value plus 1 (but at least 0). If no int indices exist yet, the key will
be 0 (zero).
Note that the maximum integer key used for this need not
currently exist in the array. It need only have
existed in the array at some time since the last time the
array was re-indexed. The following example illustrates:
Array destructuring
Arrays can be destructured using the [] (as of PHP 7.1.0) or
list language constructs. These
constructs can be used to destructure an array into distinct variables.
Array Destructuring
Array destructuring can be used in to destructure
a multi-dimensional array while iterating over it.
Array Destructuring in Foreach
Array elements will be ignored if the variable is not provided. Array
destructuring always starts at index 0.
Ignoring Elements
As of PHP 7.1.0, associative arrays can be destructured too. This also
allows for easier selection of the right element in numerically indexed
arrays as the index can be explicitly specified.
Destructuring Associative Arrays
Array destructuring can be used for easy swapping of two variables.
Swapping Two Variable
The spread operator (...) is not supported in assignments.
Attempting to access an array key which has not been defined is
the same as accessing any other undefined variable:
an E_WARNING-level error message
(E_NOTICE-level prior to PHP 8.0.0) will be
issued, and the result will be .
Destructuring a scalar value assigns to all variables.
Useful functions
There are quite a few useful functions for working with arrays. See the
array functions section.
The unset function allows removing keys from an
array. Be aware that the array will not be
reindexed. If a true "remove and shift" behavior is desired, the
array can be reindexed using the
array_values function.
Unsetting Intermediate Elements
The control
structure exists specifically for arrays. It provides an easy
way to traverse an array.
Array do's and don'ts
Why is $foo[bar] wrong?
Always use quotes around a string literal array index. For example,
$foo['bar'] is correct, while
$foo[bar] is not. But why? It is common to encounter this
kind of syntax in old scripts:
This is wrong, but it works. The reason is that this code has an undefined
constant (bar) rather than a string ('bar' - notice the
quotes). It works because PHP automatically converts a
bare string (an unquoted string which does
not correspond to any known symbol) into a string which
contains the bare string. For instance, if there is no defined
constant named bar, then PHP will substitute in the
string 'bar' and use that.
The fallback to treat an undefined constant as bare string issues an error
of level E_NOTICE.
This has been deprecated as of PHP 7.2.0, and issues an error
of level E_WARNING.
As of PHP 8.0.0, it has been removed and throws an
Error exception.
This does not mean to always quote the key. Do not
quote keys which are constants or
variables, as this will prevent
PHP from interpreting them.
Key Quoting
More examples to demonstrate this behaviour:
More Examples
As stated in the syntax
section, what's inside the square brackets ('[' and
']') must be an expression. This means that code like
this works:
This is an example of using a function return value as the array index. PHP
also knows about constants:
Note that E_ERROR is also a valid identifier, just like
bar in the first example. But the last example is in fact
the same as writing:
because E_ERROR equals 1, etc.
So why is it bad then?
At some point in the future, the PHP team might want to add another
constant or keyword, or a constant in other code may interfere. For
example, it is already wrong to use the words empty and
default this way, since they are
reserved keywords.
To reiterate, inside a double-quoted string, it's valid to
not surround array indexes with quotes so "$foo[bar]"
is valid. See the above examples for details on why as well as the section
on variable parsing in
strings.
Converting to array
For any of the types int, float,
string, bool and resource,
converting a value to an array results in an array with a single
element with index zero and the value of the scalar which was converted. In
other words, (array) $scalarValue is exactly the same as
array($scalarValue).
If an object is converted to an array, the result
is an array whose elements are the object's
properties. The keys are the member variable names, with a few notable
exceptions: integer properties are unaccessible;
private variables have the class name prepended to the variable
name; protected variables have a '*' prepended to the variable name. These
prepended values have NUL bytes on either side.
Uninitialized typed properties
are silently discarded.
Converting to an Array
These NUL can result in some unexpected behaviour:
Casting an Object to an Array
The above will appear to have two keys named 'AA', although one of them is
actually named '\0A\0A'.
Converting to an array results in an empty
array.
Comparing
It is possible to compare arrays with the array_diff
function and with
array operators.
Array unpacking
An array prefixed by ... will be expanded in place during array definition.
Only arrays and objects which implement Traversable can be expanded.
Array unpacking with ... is available as of PHP 7.4.0. This is also called
the spread operator.
It's possible to expand multiple times, and add normal elements before or after the ... operator:
Simple array unpacking
<?php
// Using short array syntax.
// Also, works with array() syntax.
$arr1 = [1, 2, 3];
$arr2 = [...$arr1]; // [1, 2, 3]
$arr3 = [0, ...$arr1]; // [0, 1, 2, 3]
$arr4 = [...$arr1, ...$arr2, 111]; // [1, 2, 3, 1, 2, 3, 111]
$arr5 = [...$arr1, ...$arr1]; // [1, 2, 3, 1, 2, 3]
function getArr() {
return ['a', 'b'];
}
$arr6 = [...getArr(), 'c' => 'd']; // ['a', 'b', 'c' => 'd']
var_dump($arr1, $arr2, $arr3, $arr4, $arr5, $arr6);
?>
Simple array unpacking
Unpacking an array with the ... operator follows the semantics of the array_merge function.
That is, later string keys overwrite earlier ones and integer keys are renumbered:
Array unpacking with duplicate key
<?php
// string key
$arr1 = ["a" => 1];
$arr2 = ["a" => 2];
$arr3 = ["a" => 0, ...$arr1, ...$arr2];
var_dump($arr3); // ["a" => 2]
// integer key
$arr4 = [1, 2, 3];
$arr5 = [4, 5, 6];
$arr6 = [...$arr4, ...$arr5];
var_dump($arr6); // [1, 2, 3, 4, 5, 6]
// Which is [0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6]
// where the original integer keys have not been retained.
?>
Array unpacking with duplicate key
Keys that are neither integers nor strings throw a TypeError.
Such keys can only be generated by a Traversable object.
Prior to PHP 8.1, unpacking an array which has a string key is not supported:
Examples
The array type in PHP is very versatile. Here are some examples:
Array Versatility
Using array()
Collection
Changing the values of the array directly is possible
by passing them by reference.
Changing element in the loop
This example creates a one-based array.
One-based index
Filling an array
Arrays are ordered. The order can be changed using various
sorting functions. See the array functions
section for more information. The count function can be
used to count the number of items in an array.
Sorting an array
Because the value of an array can be anything, it can also be
another array. This enables the creation of recursive and
multi-dimensional arrays.
Recursive and multi-dimensional arrays
Array assignment always involves value copying. Use the
reference operator to copy an
array by reference.
Array Copying
Type Juggling
PHP does not require explicit type definition in variable declaration.
In this case, the type of a variable is determined by the value it stores.
That is to say, if a string is assigned to variable
$var, then $var is of type
string. If afterwards an int value is assigned
to $var, it will be of type int.
PHP may attempt to convert the type of a value to another automatically
in certain contexts. The different contexts which exist are:
Numeric
String
Logical
Integral and string
Comparative
Function
Numeric
String
Logical
Integral and string
Comparative
Function
When a value needs to be interpreted as a different type, the value itself
does not change types.
To force a variable to be evaluated as a certain type, see the section on
Type casting. To change the
type of a variable, see the settype function.
Numeric contexts
This is the context when using an
arithmetical operator.
In this context if either operand is a float (or not
interpretable as an int), both operands are interpreted as
floats, and the result will be a float.
Otherwise, the operands will be interpreted as ints,
and the result will also be an int.
As of PHP 8.0.0, if one of the operands cannot be interpreted a
TypeError is thrown.
String contexts
This is the context when using echo,
print,
string interpolation,
or the string
concatenation operator.
In this context the value will be interpreted as string.
If the value cannot be interpreted a TypeError is thrown.
Prior to PHP 7.4.0, an E_RECOVERABLE_ERROR was raised.
Logical contexts
This is the context when using conditional statements, the
ternary operator,
or a logical operator.
In this context the value will be interpreted as bool.
Integral and string contexts
This is the context when using
bitwise operators.
In this context if all operands are of type string the result
will also be a string.
Otherwise, the operands will be interpreted as ints,
and the result will also be an int.
As of PHP 8.0.0, if one of the operands cannot be interpreted a
TypeError is thrown.
Comparative contexts
This is the context when using a
comparison operator.
The type conversions which occur in this context are explained in the
Comparison with Various Types
table.
Function contexts
This is the context when a value is passed to a typed parameter, property,
or returned from a function which declares a return type.
In this context the value must be a value of the type.
Two exceptions exist, the first one is: if the value is of type
int and the declared type is float, then the
integer is converted to a floating point number.
The second one is: if the declared type is a scalar
type, the value is convertable to a scalar type,
and the coercive typing mode is active
(the default), the value may be converted to an accepted scalar value.
See below for a description of this behaviour.
Internal functions
automatically coerce to scalar types,
this behaviour is DEPRECATED as of PHP 8.1.0.
Coercive typing with simple type declarations
bool type declaration: value is interpreted as bool.
int type declaration: value is interpreted as int
if the conversion is well-defined. For example the string is
numeric.
float type declaration: value is interpreted as float
if the conversion is well-defined. For example the string is
numeric.
string type declaration: value is interpreted as string.
Coercive typing with union types
When strict_types is not enabled, scalar type declarations
are subject to limited implicit type coercions.
If the exact type of the value is not part of the union, then the target type
is chosen in the following order of preference:
int
float
string
bool
If the type exists in the union and the value can be coerced to the
type under PHP's existing type-checking semantics, then the type is chosen.
Otherwise, the next type is tried.
int
float
string
bool
As an exception, if the value is a string and both int and float are part
of the union, the preferred type is determined by the existing
numeric string
semantics.
For example, for "42" int is chosen,
while for "42.0" float is chosen.
Types that are not part of the above preference list are not eligible
targets for implicit coercion. In particular no implicit coercions to
the null, false, and true
types occur.
Example of types being coerced into a type part of the union
Type Casting
Type casting converts the value to a chosen type by writing the type within
parentheses before the value to convert.
Type Casting
The casts allowed are:
(integer) is an alias of the (int) cast.
(boolean) is an alias of the (bool) cast.
(binary) is an alias of the (string) cast.
(double) and (real) are aliases of
the (float) cast.
These casts do not use the canonical type name and are deprecated as of PHP 8.5.0.
The (real) cast alias has been deprecated as of PHP 7.4.0
and removed as of PHP 8.0.0.
The (unset) cast has been deprecated as of PHP 7.2.0.
Note that the (unset) cast is the same as assigning the
value NULL to the variable or call.
The (unset) cast is removed as of PHP 8.0.0.
The (binary) cast and b prefix exists
for forward support. Currently (binary) and
(string) are identical, however this may change and
should not be relied upon.
Whitespaces are ignored within the parentheses of a cast.
Therefore, the following two casts are equivalent:
<?php
$foo = (int) $bar;
$foo = ( int ) $bar;
?>
Casting literal strings and variables to binary
strings:
Instead of casting a variable to a string, it is also possible
to enclose the variable in double quotes.
Different Casting Mechanisms
It may not be obvious exactly what will happen when casting between certain
types. For more information, see these sections:
Converting to boolean
Converting to integer
Converting to float
Converting to string
Converting to array
Converting to object
Converting to resource
Converting to NULL
The type comparison tables
Because PHP supports indexing into strings via offsets
using the same syntax as array indexing, the following example
holds true for all PHP versions:
Using Array Offset with a String
See the section titled String
access by character for more information.
Type declarations
Type declarations can be added to function arguments, return values,
as of PHP 7.4.0, class properties, and as of PHP 8.3.0, class constants.
They ensure that the value is of the specified type at call time,
otherwise a TypeError is thrown.
Every single type that PHP supports, with the exception of
resource can be used within a user-land type declaration.
This page contains a changelog of availability of the different types
and documentation about usage of them in type declarations.
When a class implements an interface method or reimplements a method which
has already been defined by a parent class, it has to be compatible with the
aforementioned definition.
A method is compatible if it follows the
variance rules.
Atomic Types Usage Notes
Atomic types have straight forward behaviour with some minor caveats which
are described in this section.
Scalar types
Name aliases for scalar types (bool, int,
float, string) are not supported.
Instead, they are treated as class or interface names.
For example, using boolean as a type declaration
will require the value to be an the class or interface
boolean, rather than of type bool:
void
Returning by reference from a void function is deprecated as of PHP 8.1.0,
because such a function is contradictory.
Previously, it already emitted the following
E_NOTICE when called:
Only variable references should be returned by reference.
<?php
function &test(): void {}
?>
Callable types
This type cannot be used as a class property type declaration.
It is not possible to specify the signature of the function.
Type declarations on pass-by-reference Parameters
If a pass-by-reference parameter has a type declaration, the type of the
variable is only checked on function entry, at the
beginning of the call, but not when the function returns.
This means that a function can change the type of variable reference.
Typed pass-by-reference Parameters
Composite Types Usage Notes
Composite type declarations are subject to a couple of restrictions and
will perform a redundancy check at compile time to prevent simple bugs.
Prior to PHP 8.2.0, and the introduction of DNF types,
it was not possible to combine intersection types with union types.
Union types
It is not possible to combine the two singleton types false
and true together in a union type.
Use bool instead.
Prior to PHP 8.2.0, as false and null
could not be used as standalone types, a union type comprised of only
these types was not permitted. This comprises the following types:
false, false|null,
and ?false.
Nullable type syntactic sugar
A single base type declaration can be marked nullable by prefixing the
type with a question mark (?).
Thus ?T and T|null are identical.
This syntax is supported as of PHP 7.1.0, and predates generalized union
types support.
It is also possible to achieve nullable arguments by making
null the default value.
This is not recommended as if the default value is changed in a child
class a type compatibility violation will be raised as the
null type will need to be added to the type declaration.
This behavior is also deprecated since PHP 8.4.
Old way to make arguments nullable
Duplicate and redundant types
To catch simple bugs in composite type declarations, redundant types that
can be detected without performing class loading will result in a
compile-time error. This includes:
Each name-resolved type may only occur once. Types such as
int|string|INT or
CountableTraversableCOUNTABLE
result in an error.
Using mixed or never results in an error.
For union types:
If bool is used, false or true
cannot be used additionally.
If object is used, class types cannot be used additionally.
If iterable is used, array
and Traversable cannot be used additionally.
For intersection types:
Using a type which is not a class-type results in an error.
Using either self, parent, or
static results in an error.
For DNF types:
If a more generic type is used, the more restrictive one is redundant.
Using two identical intersection types.
Each name-resolved type may only occur once. Types such as
int|string|INT or
CountableTraversableCOUNTABLE
result in an error.
Using mixed or never results in an error.
For union types:
If bool is used, false or true
cannot be used additionally.
If object is used, class types cannot be used additionally.
If iterable is used, array
and Traversable cannot be used additionally.
For intersection types:
Using a type which is not a class-type results in an error.
Using either self, parent, or
static results in an error.
For DNF types:
If a more generic type is used, the more restrictive one is redundant.
Using two identical intersection types.
This does not guarantee that the type is “minimal”, because doing so would
require loading all used class types.
For example, if A and B are class
aliases, then A|B remains a legal union type, even
though it could be reduced to either A or
B.
Similarly, if class B extends A {}, then A|B
is also a legal union type, even though it could be reduced to just
A.
<?php
function foo(): int|INT {} // Disallowed
function foo(): bool|false {} // Disallowed
function foo(): int&Traversable {} // Disallowed
function foo(): self&Traversable {} // Disallowed
use A as B;
function foo(): A|B {} // Disallowed ("use" is part of name resolution)
function foo(): A&B {} // Disallowed ("use" is part of name resolution)
class_alias('X', 'Y');
function foo(): X|Y {} // Allowed (redundancy is only known at runtime)
function foo(): X&Y {} // Allowed (redundancy is only known at runtime)
?>
Basic class type declaration
Basic interface type declaration
Basic return type declaration
Returning an object
Nullable argument type declaration
Nullable return type declaration
Class property type declaration
Strict typing
By default, PHP will coerce values of the wrong type into the expected
scalar type declaration if possible. For example, a function that is given
an int for a parameter that expects a string
will get a variable of type string.
It is possible to enable strict mode on a per-file basis. In strict
mode, only a value corresponding exactly to the type declaration will be
accepted, otherwise a TypeError will be thrown.
The only exception to this rule is that an int value will
pass a float type declaration.
Function calls from within internal functions will not be affected by
the strict_types declaration.
To enable strict mode, the statement is used with the
strict_types declaration:
Strict typing applies to function calls made from
within the file with strict typing enabled, not to
the functions declared within that file. If a file without strict
typing enabled makes a call to a function that was defined in a file
with strict typing, the caller's preference (coercive typing) will be
respected, and the value will be coerced.
Strict typing is only defined for scalar type declarations.
Strict typing for arguments values
Coercive typing for argument values
Strict typing for return values
Mixed
The mixed type accepts every value. It is equivalent to the
union type
object|resource|array|string|float|int|bool|null.
Available as of PHP 8.0.0.
mixed is, in type theory parlance, the top type.
Meaning every other type is a subtype of it.
Objects
Object Initialization
To create a new object, use the new statement
to instantiate a class:
Object Construction
For a full discussion, see the
Classes and Objects chapter.
Converting to object
If an object is converted to an object, it is not
modified. If a value of any other type is converted to an
object, a new instance of the stdClass
built-in class is created. If the value was , the new instance will be
empty. An array converts to an object with properties
named by keys and corresponding values. Note that in this case before PHP 7.2.0 numeric keys
have been inaccessible unless iterated.
Casting to an Object
For any other value, a member variable named scalar will contain
the value.
(object) cast
NULL
The null type is PHP's unit type, i.e. it has only one value:
.
Undefined, and unset variables will resolve to the
value .
Syntax
There is only one value of type null, and that is the
case-insensitive constant .
Casting to
Casting a variable to null using (unset) $var
will not remove the variable or unset its value.
It will only return a value.
is_null
unset
Type System
PHP uses a nominal type system with a strong behavioral subtyping relation.
The subtyping relation is checked at compile time whereas the verification of
types is dynamically checked at run time.
PHP's type system supports various atomic types that can be composed together
to create more complex types. Some of these types can be written as
type declarations.
Atomic types
Some atomic types are built-in types which are tightly integrated with the
language and cannot be reproduced with user defined types.
The list of base types is:
Built-in types
Scalar types:
bool type
int type
float type
string type
array type
object type
resource type
never type
void type
Relative class types:
self, parent, and static
Singleton types
false
true
Unit types
null
User-defined types (generally referred to as class-types)
Interfaces
Classes
Enumerations
callable type
Built-in types
Scalar types:
bool type
int type
float type
string type
array type
object type
resource type
never type
void type
Relative class types:
self, parent, and static
Singleton types
false
true
Unit types
null
User-defined types (generally referred to as class-types)
Interfaces
Classes
Enumerations
callable type
Scalar types
A value is considered scalar if it is of type int,
float, string or bool.
User-defined types
It is possible to define custom types with
interfaces,
classes and
enumerations.
These are considered as user-defined types, or class-types.
For example, a class called Elephant can be defined,
then objects of type Elephant can be instantiated,
and a function can request a parameter of type Elephant.
Composite types
It is possible to combine multiple atomic types into composite types.
PHP allows types to be combined in the following ways:
Intersection of class-types (interfaces and class names).
Union of types.
Intersection types
An intersection type accepts values which satisfies multiple
class-type declarations, rather than a single one.
Individual types which form the intersection type are joined by the
& symbol. Therefore, an intersection type comprised
of the types T, U, and
V will be written as T&U&V.
Union types
A union type accepts values of multiple different types,
rather than a single one.
Individual types which form the union type are joined by the
| symbol. Therefore, a union type comprised
of the types T, U, and
V will be written as T|U|V.
If one of the types is an intersection type, it needs to be bracketed
with parenthesis for it to written in DNF:
T|(X&Y).
Type aliases
PHP supports two type aliases: mixed and
iterable which corresponds to the
union type
of object|resource|array|string|float|int|bool|null
and Traversable|array respectively.
PHP does not support user-defined type aliases.
Void
void is a return-only type declaration indicating the
function does not return a value, but the function may still terminate.
Therefore, it cannot be part of a
union type
declaration. Available as of PHP 7.1.0.
Even if a function has a return type of void it will
still return a value, this value is always .
Iterables
Iterable is a built-in compile time type alias for
array|Traversable.
From its introduction in PHP 7.1.0 and prior to PHP 8.2.0,
iterable was a built-in pseudo-type that acted as the
aforementioned type alias and can be used as a type declaration.
An iterable type can be used in and with
yield from within a
generator.
Functions declaring iterable as a return type may also be generators.
Iterable generator return type example
<?php
function gen(): iterable {
yield 1;
yield 2;
yield 3;
}
foreach(gen() as $value) {
echo $value, "\n";
}
?>
Iterable generator return type example
Strings
A string is a series of characters, where a character is
the same as a byte. This means that PHP only supports a 256-character set,
and hence does not offer native Unicode support. See
details of the string
type.
On 32-bit builds, a string can be as large as up to 2GB
(2147483647 bytes maximum)
Syntax
A string literal can be specified in four different ways:
single quoted
double quoted
heredoc syntax
nowdoc syntax
Single quoted
The simplest way to specify a string is to enclose it in single
quotes (the character ').
To specify a literal single quote, escape it with a backslash
(\). To specify a literal backslash, double it
(\\). All other instances of backslash will be treated
as a literal backslash: this means that the other escape sequences you
might be used to, such as \r or \n,
will be output literally as specified rather than having any special
meaning.
Unlike the double-quoted
and heredoc syntaxes,
variables and escape sequences
for special characters will not be expanded when they
occur in single quoted strings.
Syntax Variants
Double quoted
If the string is enclosed in double-quotes ("), PHP will
interpret the following escape sequences for special characters:
Escaped characters
As in single quoted strings, escaping any other character will
result in the backslash being printed too.
The most important feature of double-quoted strings is the fact
that variable names will be expanded. See
string interpolation for
details.
Heredoc
A third way to delimit strings is the heredoc syntax:
<<<. After this operator, an identifier is
provided, then a newline. The string itself follows, and then
the same identifier again to close the quotation.
The closing identifier may be indented by space or tab, in which case
the indentation will be stripped from all lines in the doc string.
Prior to PHP 7.3.0, the closing identifier must
begin in the first column of the line.
Also, the closing identifier must follow the same naming rules as any
other label in PHP: it must contain only alphanumeric characters and
underscores, and must start with a non-digit character or underscore.
Basic Heredoc example as of PHP 7.3.0
If the closing identifier is indented further than any lines of the body, then a ParseError will be thrown:
Closing identifier must not be indented further than any lines of the body
If the closing identifier is indented, tabs can be used as well, however,
tabs and spaces must not be intermixed regarding
the indentation of the closing identifier and the indentation of the body
(up to the closing identifier). In any of these cases, a ParseError will be thrown.
These whitespace constraints have been included because mixing tabs and
spaces for indentation is harmful to legibility.
Different indentation for body (spaces) closing identifier
The closing identifier for the body string is not required to be
followed by a semicolon or newline. For example, the following code
is allowed as of PHP 7.3.0:
Continuing an expression after a closing identifier
If the closing identifier was found at the start of a line, then
regardless of whether it was a part of another word, it may be considered
as the closing identifier and causes a ParseError.
Closing identifier in body of the string tends to cause ParseError
To avoid this problem, it is safe to follow the simple rule:
do not choose a word that appears in the body of the text
as a closing identifier.
Prior to PHP 7.3.0, it is very important to note that the line with the
closing identifier must contain no other characters, except a semicolon
(;).
That means especially that the identifier
may not be indented, and there may not be any spaces
or tabs before or after the semicolon. It's also important to realize that
the first character before the closing identifier must be a newline as
defined by the local operating system. This is \n on
UNIX systems, including macOS. The closing delimiter must also be
followed by a newline.
If this rule is broken and the closing identifier is not "clean", it will
not be considered a closing identifier, and PHP will continue looking for
one. If a proper closing identifier is not found before the end of the
current file, a parse error will result at the last line.
Invalid example, prior to PHP 7.3.0
Valid example, even prior to PHP 7.3.0
Heredocs containing variables can not be used for initializing class properties.
Heredoc text behaves just like a double-quoted string, without
the double quotes. This means that quotes in a heredoc do not need to be
escaped, but the escape codes listed above can still be used. Variables are
expanded, but the same care must be taken when expressing complex variables
inside a heredoc as with strings.
Heredoc string quoting example
It is also possible to use the Heredoc syntax to pass data to function
arguments:
Heredoc in arguments example
It's possible to initialize static variables and class
properties/constants using the Heredoc syntax:
Using Heredoc to initialize static values
The opening Heredoc identifier may optionally be
enclosed in double quotes:
Using double quotes in Heredoc
Nowdoc
Nowdocs are to single-quoted strings what heredocs are to double-quoted
strings. A nowdoc is specified similarly to a heredoc, but no
String interpolation is done inside a nowdoc. The construct is ideal for
embedding PHP code or other large blocks of text without the need for
escaping. It shares some features in common with the SGML
![CDATA[ ]] construct, in that it declares a
block of text which is not for parsing.
A nowdoc is identified with the same
sequence used for heredocs, but the identifier which follows is enclosed in
single quotes, e.g. 'EOT'. All the rules for
heredoc identifiers also apply to nowdoc identifiers, especially those
regarding the appearance of the closing identifier.
Nowdoc string quoting example
Nowdoc string quoting example with variables
Static data example
String interpolation
When a string is specified in double quotes or with heredoc,
variables can be substituted within it.
There are two types of syntax: a
basic one and an
advanced one.
The basic syntax is the most common and convenient. It provides a way to
embed a variable, an array value, or an object
property in a string with a minimum of effort.
Basic syntax
If a dollar sign ($) is encountered, the characters
that follow it which can be used in a variable name will be interpreted
as such and substituted.
String Interpolation
Formally, the structure for the basic variable substitution syntax is
as follows:
The ${ expression } syntax is deprecated as of
PHP 8.2.0, as it can be interpreted as
variable variables:
<?php
const foo = 'bar';
$foo = 'foo';
$bar = 'bar';
var_dump("${foo}");
var_dump("${(foo)}");
?>
Deprecated: Using ${var} in strings is deprecated, use {$var} instead in file on line 6
Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in file on line 9
string(3) "foo"
string(3) "bar"
string(3) "foo"
string(3) "bar"
The advanced
string interpolation syntax should be used instead.
If it is not possible to form a valid name the dollar sign remains
as verbatim in the string:
Interpolating the value of the first dimension of an array or property
The array key must be unquoted, and it is therefore not possible to
refer to a constant as a key with the basic syntax. Use the
advanced
syntax instead.
As of PHP 7.1.0 also negative numeric indices are
supported.
Negative numeric indices
For anything more complex, the
advanced
syntax must be used.
Advanced (curly) syntax
The advanced syntax permits the interpolation of
variables with arbitrary accessors.
Any scalar variable, array element or object property
(static or not) with a
string representation can be included via this syntax.
The expression is written the same way as it would appear outside the
string, and then wrapped in { and
}. Since { can not be escaped, this
syntax will only be recognised when the $ immediately
follows the {. Use {\$ to get a
literal {$. Some examples to make it clear:
Curly Syntax
As this syntax allows arbitrary expressions it is possible to use
variable variables
within the advanced syntax.
String access and modification by character
Characters within strings may be accessed and modified by
specifying the zero-based offset of the desired character after the
string using square array brackets, as in
$str[42]. Think of a string as an
array of characters for this purpose. The functions
substr and substr_replace
can be used when you want to extract or replace more than 1 character.
As of PHP 7.1.0, negative string offsets are also supported. These specify
the offset from the end of the string.
Formerly, negative offsets emitted E_NOTICE for reading
(yielding an empty string) and E_WARNING for writing
(leaving the string untouched).
Prior to PHP 8.0.0, strings could also be accessed using braces, as in
$str{42}, for the same purpose.
This curly brace syntax was deprecated as of PHP 7.4.0 and no longer supported as of PHP 8.0.0.
Writing to an out of range offset pads the string with spaces.
Non-integer types are converted to integer.
Illegal offset type emits E_WARNING.
Only the first character of an assigned string is used.
As of PHP 7.1.0, assigning an empty string throws a fatal error. Formerly,
it assigned a NULL byte.
Internally, PHP strings are byte arrays. As a result, accessing or
modifying a string using array brackets is not multi-byte safe, and
should only be done with strings that are in a single-byte encoding such
as ISO-8859-1.
As of PHP 7.1.0, applying the empty index operator on an empty string throws a fatal
error. Formerly, the empty string was silently converted to an array.
Some string examples
String offsets have to either be integers or integer-like strings,
otherwise a warning will be thrown.
Example of Illegal String Offsets
Accessing variables of other types (not including arrays or objects
implementing the appropriate interfaces) using [] or
{} silently returns .
Characters within string literals can be accessed
using [] or {}.
Accessing characters within string literals using the
{} syntax has been deprecated in PHP 7.4.
This has been removed in PHP 8.0.
Useful functions and operators
Strings may be concatenated using the '.' (dot) operator. Note
that the '+' (addition) operator will not work for this.
See String operators for
more information.
There are a number of useful functions for string manipulation.
See the string functions section for
general functions, and the Perl-compatible regular
expression functions for advanced find replace functionality.
There are also functions for URL strings, and
functions to encrypt/decrypt strings
(Sodium and
Hash).
Finally, see also the character type
functions.
Converting to string
A value can be converted to a string using the
(string) cast or the strval function.
String conversion is automatically done in the scope of an
expression where a string is needed. This happens when using the
echo or print functions, or when a
variable is compared to a string. The sections on
Types and
Type Juggling will make
the following clearer. See also the settype function.
A bool value is converted to the string
"1". bool is converted to
"" (the empty string). This allows conversion back and
forth between bool and string values.
An int or float is converted to a
string representing the number textually (including the
exponent part for floats). Floating point numbers can be
converted using exponential notation (4.1E+6).
As of PHP 8.0.0, the decimal point character is always
a period ("."). Prior to PHP 8.0.0,
the decimal point character is defined in the script's locale (category
LC_NUMERIC). See the setlocale function.
Arrays are always converted to the string
"Array"; because of this, echo and
print can not by themselves show the contents of an
array. To view a single element, use a construction such as
echo $arr['foo']. See below for tips on viewing the entire
contents.
In order to convert objects to string, the magic
method __toString must be used.
Resources are always converted to strings with the
structure "Resource id #1", where 1
is the resource number assigned to the resource by PHP at
runtime. While the exact structure of this string should not be relied on
and is subject to change, it will always be unique for a given resource
within the lifetime of a script being executed (ie a Web request or CLI
process) and won't be reused. To get a resource's type, use
the get_resource_type function.
is always converted to an empty string.
As stated above, directly converting an array,
object, or resource to a string does
not provide any useful information about the value beyond its type. See the
functions print_r and var_dump for
more effective means of inspecting the contents of these types.
Most PHP values can also be converted to strings for permanent
storage. This method is called serialization, and is performed by the
serialize function.
Details of the String Type
The string in PHP is implemented as an array of bytes and an
integer indicating the length of the buffer. It has no information about how
those bytes translate to characters, leaving that task to the programmer.
There are no limitations on the values the string can be composed of; in
particular, bytes with value 0 (“NUL bytes”) are allowed
anywhere in the string (however, a few functions, said in this manual not to
be “binary safe”, may hand off the strings to libraries that ignore data
after a NUL byte.)
This nature of the string type explains why there is no separate “byte” type
in PHP strings take this role. Functions that return no textual data for
instance, arbitrary data read from a network socket will still return
strings.
Given that PHP does not dictate a specific encoding for strings, one might
wonder how string literals are encoded. For instance, is the string
"á" equivalent to "\xE1" (ISO-8859-1),
"\xC3\xA1" (UTF-8, C form),
"\x61\xCC\x81" (UTF-8, D form) or any other possible
representation? The answer is that string will be encoded in whatever fashion
it is encoded in the script file. Thus, if the script is written in
ISO-8859-1, the string will be encoded in ISO-8859-1 and so on. However,
this does not apply if Zend Multibyte is enabled; in that case, the script
may be written in an arbitrary encoding (which is explicitly declared or is
detected) and then converted to a certain internal encoding, which is then
the encoding that will be used for the string literals.
Note that there are some constraints on the encoding of the script (or on the
internal encoding, should Zend Multibyte be enabled) this almost always
means that this encoding should be a compatible superset of ASCII, such as
UTF-8 or ISO-8859-1. Note, however, that state-dependent encodings where
the same byte values can be used in initial and non-initial shift states
may be problematic.
Of course, in order to be useful, functions that operate on text may have to
make some assumptions about how the string is encoded. Unfortunately, there
is much variation on this matter throughout PHPs functions:
Some functions assume that the string is encoded in some (any) single-byte
encoding, but they do not need to interpret those bytes as specific
characters. This is case of, for instance, substr,
strpos, strlen or
strcmp. Another way to think of these functions is
that operate on memory buffers, i.e., they work with bytes and byte
offsets.
Other functions are passed the encoding of the string, possibly they also
assume a default if no such information is given. This is the case of
htmlentities and the majority of the
functions in the mbstring extension.
Others use the current locale (see setlocale), but
operate byte-by-byte.
Finally, they may just assume the string is using a specific encoding,
usually UTF-8. This is the case of most functions in the
intl extension and in the
PCRE extension
(in the last case, only when the u modifier is used).
Ultimately, this means writing correct programs using Unicode depends on
carefully avoiding functions that will not work and that most likely will
corrupt the data and using instead the functions that do behave correctly,
generally from the intl and
mbstring extensions.
However, using functions that can handle Unicode encodings is just the
beginning. No matter the functions the language provides, it is essential to
know the Unicode specification. For instance, a program that assumes there is
only uppercase and lowercase is making a wrong assumption.
Singleton types
Singleton types are those which allow only one value.
PHP has support for two singleton types:
false as of PHP 8.0.0 and true
as of PHP 8.2.0.
Prior to PHP 8.2.0 the false type
could only be used as part of a
union type.
It is not possible to define custom singleton types. Consider using an
enumerations instead.
Relative class types
These types declarations can only be used within classes.
self
The value must be an the same class as the one
in which the type declaration is used.
parent
The value must be an a parent of the class
in which the type declaration is used.
static
static is a return-only type which requires that the
value returned must be an the same class as the one
the method is called in.
Available as of PHP 8.0.0.
Resources
A resource is a special variable, holding a reference to an
external resource. Resources are created and used by special functions. See
the appendix for a listing of all these
functions and the corresponding resource types.
See also the get_resource_type function.
Converting to resource
As resource variables hold special handles to opened files,
database connections, image canvas areas and the like, converting to a
resource makes no sense.
Freeing resources
Thanks to the reference-counting system being part of Zend Engine,
a resource with no more references to it is detected
automatically, and it is freed by the garbage collector. For this reason, it
is rarely necessary to free the memory manually.
Persistent database links are an exception to this rule. They are
not destroyed by the garbage collector. See the
persistent
connections section for more information.
Bitwise Operators
Bitwise operators allow evaluation and manipulation of specific
bits within an integer.
Bitwise Operators
Bit shifting in PHP is arithmetic.
Bits shifted off either end are discarded.
Left shifts have zeros shifted in on the right while the sign
bit is shifted out on the left, meaning the sign of an operand
is not preserved.
Right shifts have copies of the sign bit shifted in on the left,
meaning the sign of an operand is preserved.
Use parentheses to ensure the desired
precedence.
For example, $a & $b == true evaluates
the equivalency then the bitwise and; while
($a & $b) == true evaluates the bitwise and
then the equivalency.
If both operands for the &, | and
^ operators are strings, then the operation will be
performed on the ASCII values of the characters that make up the strings and
the result will be a string. In all other cases, both operands will be
converted to integers
and the result will be an integer.
If the operand for the ~ operator is a string, the
operation will be performed on the ASCII values of the characters that make
up the string and the result will be a string, otherwise the operand and the
result will be treated as integers.
Both operands and the result for the << and
>> operators are always treated as integers.
PHP's error_reporting ini setting uses bitwise values,
providing a real-world demonstration of turning
bits off. To show all errors, except for notices,
the php.ini file instructions say to use:
E_ALL & ~E_NOTICE
This works by starting with E_ALL:
00000000000000000111011111111111
Then taking the value of E_NOTICE...
00000000000000000000000000001000
... and inverting it via ~:
11111111111111111111111111110111
Finally, it uses AND (&) to find the bits turned
on in both values:
00000000000000000111011111110111
This works by starting with E_ALL:
00000000000000000111011111111111
Then taking the value of E_NOTICE...
00000000000000000000000000001000
... and inverting it via ~:
11111111111111111111111111110111
Finally, it uses AND (&) to find the bits turned
on in both values:
00000000000000000111011111110111
Another way to accomplish that is using XOR (^) to find
bits that are on in only one value or the other: E_ALL ^
E_NOTICE
error_reporting can also be used to demonstrate turning bits on.
The way to show just errors and recoverable errors is:
E_ERROR | E_RECOVERABLE_ERROR
This process combines E_ERROR
00000000000000000000000000000001
and
00000000000000000001000000000000
using the OR (|) operator
to get the bits turned on in either value:
00000000000000000001000000000001
This process combines E_ERROR
00000000000000000000000000000001
and
00000000000000000001000000000000
using the OR (|) operator
to get the bits turned on in either value:
00000000000000000001000000000001
Bitwise AND, OR and XOR operations on integers
<?php
/*
* Ignore the top section,
* it is just formatting to make output clearer.
*/
$format = '(%1$2d = %1$04b) = (%2$2d = %2$04b)'
. ' %3$s (%4$2d = %4$04b)' . "\n";
echo <<<EOH
--------- --------- -- ---------
result value op test
--------- --------- -- ---------
EOH;
/*
* Here are the examples.
*/
$values = array(0, 1, 2, 4, 8);
$test = 1 + 4;
echo "\n Bitwise AND \n";
foreach ($values as $value) {
$result = $value & $test;
printf($format, $result, $value, '&', $test);
}
echo "\n Bitwise Inclusive OR \n";
foreach ($values as $value) {
$result = $value | $test;
printf($format, $result, $value, '|', $test);
}
echo "\n Bitwise Exclusive OR (XOR) \n";
foreach ($values as $value) {
$result = $value ^ $test;
printf($format, $result, $value, '^', $test);
}
?>
--------- --------- -- ---------
result value op test
--------- --------- -- ---------
Bitwise AND
( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101)
( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101)
( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101)
( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101)
( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101)
Bitwise Inclusive OR
( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101)
( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101)
( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101)
( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101)
(13 = 1101) = ( 8 = 1000) | ( 5 = 0101)
Bitwise Exclusive OR (XOR)
( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101)
( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101)
( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101)
( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101)
(13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101)
Bitwise AND, OR and XOR operations on integers
Bitwise XOR operations on strings
<?php
echo 12 ^ 9, PHP_EOL; // Outputs '5'
echo "12" ^ "9", PHP_EOL; // Outputs the Backspace character (ascii 8)
// ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8
echo "hallo" ^ "hello", PHP_EOL; // Outputs the ascii values #0 #4 #0 #0 #0
// 'a' ^ 'e' = #4
echo 2 ^ "3", PHP_EOL; // Outputs 1
// 2 ^ ((int) "3") == 1
echo "2" ^ 3, PHP_EOL; // Outputs 1
// ((int) "2") ^ 3 == 1
?>
Bitwise XOR operations on strings
Bit shifting on integers
<?php
/*
* Here are the examples.
*/
echo "\n--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---\n";
$val = 4;
$places = 1;
$res = $val >> $places;
p($res, $val, '>>', $places, 'copy of sign bit shifted into left side');
$val = 4;
$places = 2;
$res = $val >> $places;
p($res, $val, '>>', $places);
$val = 4;
$places = 3;
$res = $val >> $places;
p($res, $val, '>>', $places, 'bits shift out right side');
$val = 4;
$places = 4;
$res = $val >> $places;
p($res, $val, '>>', $places, 'same result as above; can not shift beyond 0');
echo "\n--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---\n";
$val = -4;
$places = 1;
$res = $val >> $places;
p($res, $val, '>>', $places, 'copy of sign bit shifted into left side');
$val = -4;
$places = 2;
$res = $val >> $places;
p($res, $val, '>>', $places, 'bits shift out right side');
$val = -4;
$places = 3;
$res = $val >> $places;
p($res, $val, '>>', $places, 'same result as above; can not shift beyond -1');
echo "\n--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---\n";
$val = 4;
$places = 1;
$res = $val << $places;
p($res, $val, '<<', $places, 'zeros fill in right side');
$val = 4;
$places = (PHP_INT_SIZE * 8) - 4;
$res = $val << $places;
p($res, $val, '<<', $places);
$val = 4;
$places = (PHP_INT_SIZE * 8) - 3;
$res = $val << $places;
p($res, $val, '<<', $places, 'sign bits get shifted out');
$val = 4;
$places = (PHP_INT_SIZE * 8) - 2;
$res = $val << $places;
p($res, $val, '<<', $places, 'bits shift out left side');
echo "\n--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---\n";
$val = -4;
$places = 1;
$res = $val << $places;
p($res, $val, '<<', $places, 'zeros fill in right side');
$val = -4;
$places = (PHP_INT_SIZE * 8) - 3;
$res = $val << $places;
p($res, $val, '<<', $places);
$val = -4;
$places = (PHP_INT_SIZE * 8) - 2;
$res = $val << $places;
p($res, $val, '<<', $places, 'bits shift out left side, including sign bit');
/*
* Ignore this bottom section,
* it is just formatting to make output clearer.
*/
function p($res, $val, $op, $places, $note = '') {
$format = '%0' . (PHP_INT_SIZE * 8) . "b\n";
printf("Expression: %d = %d %s %d\n", $res, $val, $op, $places);
echo " Decimal:\n";
printf(" val=%d\n", $val);
printf(" res=%d\n", $res);
echo " Binary:\n";
printf(' val=' . $format, $val);
printf(' res=' . $format, $res);
if ($note) {
echo " NOTE: $note\n";
}
echo "\n\n";
}
?>
--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---
Expression: 2 = 4 >> 1
Decimal:
val=4
res=2
Binary:
val=00000000000000000000000000000100
res=00000000000000000000000000000010
NOTE: copy of sign bit shifted into left side
Expression: 1 = 4 >> 2
Decimal:
val=4
res=1
Binary:
val=00000000000000000000000000000100
res=00000000000000000000000000000001
Expression: 0 = 4 >> 3
Decimal:
val=4
res=0
Binary:
val=00000000000000000000000000000100
res=00000000000000000000000000000000
NOTE: bits shift out right side
Expression: 0 = 4 >> 4
Decimal:
val=4
res=0
Binary:
val=00000000000000000000000000000100
res=00000000000000000000000000000000
NOTE: same result as above; can not shift beyond 0
--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---
Expression: -2 = -4 >> 1
Decimal:
val=-4
res=-2
Binary:
val=11111111111111111111111111111100
res=11111111111111111111111111111110
NOTE: copy of sign bit shifted into left side
Expression: -1 = -4 >> 2
Decimal:
val=-4
res=-1
Binary:
val=11111111111111111111111111111100
res=11111111111111111111111111111111
NOTE: bits shift out right side
Expression: -1 = -4 >> 3
Decimal:
val=-4
res=-1
Binary:
val=11111111111111111111111111111100
res=11111111111111111111111111111111
NOTE: same result as above; can not shift beyond -1
--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---
Expression: 8 = 4 << 1
Decimal:
val=4
res=8
Binary:
val=00000000000000000000000000000100
res=00000000000000000000000000001000
NOTE: zeros fill in right side
Expression: 1073741824 = 4 << 28
Decimal:
val=4
res=1073741824
Binary:
val=00000000000000000000000000000100
res=01000000000000000000000000000000
Expression: -2147483648 = 4 << 29
Decimal:
val=4
res=-2147483648
Binary:
val=00000000000000000000000000000100
res=10000000000000000000000000000000
NOTE: sign bits get shifted out
Expression: 0 = 4 << 30
Decimal:
val=4
res=0
Binary:
val=00000000000000000000000000000100
res=00000000000000000000000000000000
NOTE: bits shift out left side
--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---
Expression: -8 = -4 << 1
Decimal:
val=-4
res=-8
Binary:
val=11111111111111111111111111111100
res=11111111111111111111111111111000
NOTE: zeros fill in right side
Expression: -2147483648 = -4 << 29
Decimal:
val=-4
res=-2147483648
Binary:
val=11111111111111111111111111111100
res=10000000000000000000000000000000
Expression: 0 = -4 << 30
Decimal:
val=-4
res=0
Binary:
val=11111111111111111111111111111100
res=00000000000000000000000000000000
NOTE: bits shift out left side, including sign bit
--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---
Expression: 2 = 4 >> 1
Decimal:
val=4
res=2
Binary:
val=0000000000000000000000000000000000000000000000000000000000000100
res=0000000000000000000000000000000000000000000000000000000000000010
NOTE: copy of sign bit shifted into left side
Expression: 1 = 4 >> 2
Decimal:
val=4
res=1
Binary:
val=0000000000000000000000000000000000000000000000000000000000000100
res=0000000000000000000000000000000000000000000000000000000000000001
Expression: 0 = 4 >> 3
Decimal:
val=4
res=0
Binary:
val=0000000000000000000000000000000000000000000000000000000000000100
res=0000000000000000000000000000000000000000000000000000000000000000
NOTE: bits shift out right side
Expression: 0 = 4 >> 4
Decimal:
val=4
res=0
Binary:
val=0000000000000000000000000000000000000000000000000000000000000100
res=0000000000000000000000000000000000000000000000000000000000000000
NOTE: same result as above; can not shift beyond 0
--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---
Expression: -2 = -4 >> 1
Decimal:
val=-4
res=-2
Binary:
val=1111111111111111111111111111111111111111111111111111111111111100
res=1111111111111111111111111111111111111111111111111111111111111110
NOTE: copy of sign bit shifted into left side
Expression: -1 = -4 >> 2
Decimal:
val=-4
res=-1
Binary:
val=1111111111111111111111111111111111111111111111111111111111111100
res=1111111111111111111111111111111111111111111111111111111111111111
NOTE: bits shift out right side
Expression: -1 = -4 >> 3
Decimal:
val=-4
res=-1
Binary:
val=1111111111111111111111111111111111111111111111111111111111111100
res=1111111111111111111111111111111111111111111111111111111111111111
NOTE: same result as above; can not shift beyond -1
--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---
Expression: 8 = 4 << 1
Decimal:
val=4
res=8
Binary:
val=0000000000000000000000000000000000000000000000000000000000000100
res=0000000000000000000000000000000000000000000000000000000000001000
NOTE: zeros fill in right side
Expression: 4611686018427387904 = 4 << 60
Decimal:
val=4
res=4611686018427387904
Binary:
val=0000000000000000000000000000000000000000000000000000000000000100
res=0100000000000000000000000000000000000000000000000000000000000000
Expression: -9223372036854775808 = 4 << 61
Decimal:
val=4
res=-9223372036854775808
Binary:
val=0000000000000000000000000000000000000000000000000000000000000100
res=1000000000000000000000000000000000000000000000000000000000000000
NOTE: sign bits get shifted out
Expression: 0 = 4 << 62
Decimal:
val=4
res=0
Binary:
val=0000000000000000000000000000000000000000000000000000000000000100
res=0000000000000000000000000000000000000000000000000000000000000000
NOTE: bits shift out left side
--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---
Expression: -8 = -4 << 1
Decimal:
val=-4
res=-8
Binary:
val=1111111111111111111111111111111111111111111111111111111111111100
res=1111111111111111111111111111111111111111111111111111111111111000
NOTE: zeros fill in right side
Expression: -9223372036854775808 = -4 << 61
Decimal:
val=-4
res=-9223372036854775808
Binary:
val=1111111111111111111111111111111111111111111111111111111111111100
res=1000000000000000000000000000000000000000000000000000000000000000
Expression: 0 = -4 << 62
Decimal:
val=-4
res=0
Binary:
val=1111111111111111111111111111111111111111111111111111111111111100
res=0000000000000000000000000000000000000000000000000000000000000000
NOTE: bits shift out left side, including sign bit
Bit shifting on integers
Use functions from the gmp extension for
bitwise manipulation on numbers beyond PHP_INT_MAX.
pack
unpack
gmp_and
gmp_or
gmp_xor
gmp_testbit
gmp_clrbit
Type Operators
instanceof is used to determine whether a PHP variable
is an instantiated object of a certain
class:
Using instanceof with classes
<?php
class MyClass
{
}
class NotMyClass
{
}
$a = new MyClass;
var_dump($a instanceof MyClass);
var_dump($a instanceof NotMyClass);
?>
bool(true)
bool(false)
Using instanceof with classes
instanceof can also be used to determine whether a variable
is an instantiated object of a class that inherits from a parent class:
Using instanceof with inherited classes
<?php
class ParentClass
{
}
class MyClass extends ParentClass
{
}
$a = new MyClass;
var_dump($a instanceof MyClass);
var_dump($a instanceof ParentClass);
?>
bool(true)
bool(true)
Using instanceof with inherited classes
To check if an object is not an instanceof a class, the
logical not
operator can be used.
Using instanceof to check if object is not an
instanceof a class
<?php
class MyClass
{
}
$a = new MyClass;
var_dump(!($a instanceof stdClass));
?>
bool(true)
Using instanceof to check if object is not an
instanceof a class
Lastly, instanceof can also be used to determine whether
a variable is an instantiated object of a class that implements an
interface:
Using instanceof with interfaces
<?php
interface MyInterface
{
}
class MyClass implements MyInterface
{
}
$a = new MyClass;
var_dump($a instanceof MyClass);
var_dump($a instanceof MyInterface);
?>
bool(true)
bool(true)
Using instanceof with interfaces
Although instanceof is usually used with a literal classname,
it can also be used with another object or a string variable:
Using instanceof with other variables
<?php
interface MyInterface
{
}
class MyClass implements MyInterface
{
}
$a = new MyClass;
$b = new MyClass;
$c = 'MyClass';
$d = 'NotMyClass';
var_dump($a instanceof $b); // $b is an object of class MyClass
var_dump($a instanceof $c); // $c is a string 'MyClass'
var_dump($a instanceof $d); // $d is a string 'NotMyClass'
?>
bool(true)
bool(true)
bool(false)
Using instanceof with other variables
instanceof does not throw any error if the variable being tested is not
an object, it simply returns . Constants, however, were not allowed
prior to PHP 7.3.0.
Using instanceof to test other variables
<?php
$a = 1;
$b = NULL;
$c = fopen('/tmp/', 'r');
var_dump($a instanceof stdClass); // $a is an integer
var_dump($b instanceof stdClass); // $b is NULL
var_dump($c instanceof stdClass); // $c is a resource
var_dump(FALSE instanceof stdClass);
?>
bool(false)
bool(false)
bool(false)
PHP Fatal error: instanceof expects an object instance, constant given
Using instanceof to test other variables
As of PHP 7.3.0, constants are allowed on the left-hand-side of the
instanceof operator.
Using instanceof to test constants
<?php
var_dump(FALSE instanceof stdClass);
?>
bool(false)
Using instanceof to test constants
As of PHP 8.0.0, instanceof can now be used with arbitrary expressions.
The expression must be wrapped in parentheses and produce a string.
Using instanceof with an arbitrary expression
<?php
class ClassA extends \stdClass {}
class ClassB extends \stdClass {}
class ClassC extends ClassB {}
class ClassD extends ClassA {}
function getSomeClass(): string
{
return ClassA::class;
}
var_dump(new ClassA instanceof ('std' . 'Class'));
var_dump(new ClassB instanceof ('Class' . 'B'));
var_dump(new ClassC instanceof ('Class' . 'A'));
var_dump(new ClassD instanceof (getSomeClass()));
?>
bool(true)
bool(true)
bool(false)
bool(true)
Using instanceof with an arbitrary expression
The instanceof operator has a functional variant
with the is_a function.
get_class
is_a
Logical Operators
Logical Operators
The reason for the two different variations of "and" and "or"
operators is that they operate at different precedences. (See
Operator
Precedence.)
Logical operators illustrated
Arithmetic Operators
Remember basic arithmetic from school? These work just
like those.
Arithmetic Operators
The division operator / returns a float
value unless the two operands are int (or
numeric strings
which are type juggled to int) and the numerator is a multiple
of the divisor, in which case an integer value will be returned.
For integer division, see intdiv.
Operands of modulo are converted to int
before processing. For floating-point modulo, see
fmod.
The result of the modulo operator % has the same sign
as the dividend — that is, the result of $a % $b
will have the same sign as $a. For example:
The Modulo Operator
<?php
var_dump(5 % 3);
var_dump(5 % -3);
var_dump(-5 % 3);
var_dump(-5 % -3);
?>
int(2)
int(2)
int(-2)
int(-2)
The Modulo Operator
Math functions
Array Operators
Array Operators
The + operator returns the right-hand array appended
to the left-hand array; for keys that exist in both arrays, the elements
from the left-hand array will be used, and the matching elements from the
right-hand array will be ignored.
Array Append Operator
<?php
$a = array("a" => "apple", "b" => "banana");
$b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");
$c = $a + $b; // Union of $a and $b
echo "Union of \$a and \$b: \n";
var_dump($c);
$c = $b + $a; // Union of $b and $a
echo "Union of \$b and \$a: \n";
var_dump($c);
$a += $b; // Union of $a += $b is $a and $b
echo "Union of \$a += \$b: \n";
var_dump($a);
?>
Union of $a and $b:
array(3) {
["a"]=>
string(5) "apple"
["b"]=>
string(6) "banana"
["c"]=>
string(6) "cherry"
}
Union of $b and $a:
array(3) {
["a"]=>
string(4) "pear"
["b"]=>
string(10) "strawberry"
["c"]=>
string(6) "cherry"
}
Union of $a += $b:
array(3) {
["a"]=>
string(5) "apple"
["b"]=>
string(6) "banana"
["c"]=>
string(6) "cherry"
}
Array Append Operator
Elements of arrays are equal for the comparison if they have the
same key and value.
Comparing arrays
<?php
$a = array("apple", "banana");
$b = array(1 => "banana", "0" => "apple");
var_dump($a == $b); // bool(true)
var_dump($a === $b); // bool(false)
?>
Comparing arrays
Array type
Array functions
Execution Operators
PHP supports one execution operator: backticks (``). Note that
these are not single-quotes! PHP will attempt to execute the
contents of the backticks as a shell command; the output will be
returned (i.e., it won't simply be dumped to output; it can be
assigned to a variable). Use of the backtick operator is identical
to shell_exec.
Backtick Operator
<?php
$output = `ls -al`;
echo "<pre>$output</pre>";
?>
Backtick Operator
The backtick operator is disabled when
shell_exec is disabled.
Unlike some other languages, backticks have no special meaning
within double-quoted strings.
Program Execution functions
popen
proc_open
Using PHP from the commandline
Functional Operators
PHP 8.5 and later supports one operator that works directly on callables. The |>
operator, or “pipe,” accepts a single-parameter callable on the right and passes
the left-side value to it, evaluating to the callable's result. The callable
on the right may be any valid PHP callable: a Closure,
a first-class callable,
an object that implements __invoke(), etc.
That means the following two lines are logically equivalent.
Using |>
<?php
$result = "Hello World" |> strlen(...);
echo $result, PHP_EOL;
$result = strlen("Hello World");
echo $result, PHP_EOL;
?>
11
11
Using |>
For a single call that is not especially useful. It becomes useful when multiple calls are chained together.
That is, the following two code fragments are logically equivalent:
Chaining | calls
<?php
$result = "PHP Rocks"
|> htmlentities(...)
|> str_split(...)
|> (fn($x) => array_map(strtoupper(...), $x))
|> (fn($x) => array_filter($x, fn($v) => $v != 'O'))
;
print_r($result);
$temp = "PHP Rocks";
$temp = htmlentities($temp);
$temp = str_split($temp);
$temp = array_map(strtoupper(...), $temp);
$temp = array_filter($temp, fn($v) => $v != 'O');
$result = $temp;
print_r($result);
?>
Array
(
[0] => P
[1] => H
[2] => P
[3] =>
[4] => R
[6] => C
[7] => K
[8] => S
)
Array
(
[0] => P
[1] => H
[2] => P
[3] =>
[4] => R
[6] => C
[7] => K
[8] => S
)
Chaining | calls
The left-hand side of the pipe may be any value or expression. The right-hand side
may be any valid PHP callable that takes a single parameter, or any expression
that evaluates to such a callable. Functions with more than one required parameter
are not allowed and will fail as if the function were called normally
with insufficient arguments. Functions that take a variable by reference are not allowed.
If the right-hand side does not evaluate to a valid callable it will throw an Error.
Be aware that, to avoid syntax ambiguity, arrow functions
MUST be wrapped in parentheses when used with a pipe operator, as in the examples above.
Failing to do so will result in a fatal error.
Closure
Comparison Operators
Comparison operators, as their name implies, allow you to compare
two values. You may also be interested in viewing
the type comparison tables,
as they show examples of various type related comparisons.
Comparison Operators
If both operands are
numeric strings,
or one operand is a number and the other one is a
numeric string,
then the comparison is done numerically.
These rules also apply to the
switch statement.
The type conversion does not take place when the comparison is
=== or !== as this involves
comparing the type as well as the value.
Prior to PHP 8.0.0, if a string is compared to a number
or a numeric string then the string was converted to a
number before performing the comparison. This can lead to surprising
results as can be seen with the following example:
<?php
var_dump(0 == "a");
var_dump("1" == "01");
var_dump("10" == "1e1");
var_dump(100 == "1e2");
switch ("a") {
case 0:
echo "0";
break;
case "a":
echo "a";
break;
}
?>
bool(true)
bool(true)
bool(true)
bool(true)
0
bool(false)
bool(true)
bool(true)
bool(true)
a
Comparison Operators
<?php
// Integers
echo 1 <=> 1, ' '; // 0
echo 1 <=> 2, ' '; // -1
echo 2 <=> 1, ' '; // 1
// Floats
echo 1.5 <=> 1.5, ' '; // 0
echo 1.5 <=> 2.5, ' '; // -1
echo 2.5 <=> 1.5, ' '; // 1
// Strings
echo "a" <=> "a", ' '; // 0
echo "a" <=> "b", ' '; // -1
echo "b" <=> "a", ' '; // 1
echo "a" <=> "aa", ' '; // -1
echo "zz" <=> "aa", ' '; // 1
// Arrays
echo [] <=> [], ' '; // 0
echo [1, 2, 3] <=> [1, 2, 3], ' '; // 0
echo [1, 2, 3] <=> [], ' '; // 1
echo [1, 2, 3] <=> [1, 2, 1], ' '; // 1
echo [1, 2, 3] <=> [1, 2, 4], ' '; // -1
// Objects
$a = (object) ["a" => "b"];
$b = (object) ["a" => "b"];
echo $a <=> $b, ' '; // 0
$a = (object) ["a" => "b"];
$b = (object) ["a" => "c"];
echo $a <=> $b, ' '; // -1
$a = (object) ["a" => "c"];
$b = (object) ["a" => "b"];
echo $a <=> $b, ' '; // 1
// not only values are compared; keys must match
$a = (object) ["a" => "b"];
$b = (object) ["b" => "b"];
echo $a <=> $b, ' '; // 1
?>
Comparison Operators
For various types, comparison is done according to the following
table (in order).
Comparison with Various Types
Boolean/null comparison
<?php
// Bool and null are compared as bool always
var_dump(1 == TRUE); // TRUE - same as (bool) 1 == TRUE
var_dump(0 == FALSE); // TRUE - same as (bool) 0 == FALSE
var_dump(100 < TRUE); // FALSE - same as (bool) 100 < TRUE
var_dump(-10 < FALSE);// FALSE - same as (bool) -10 < FALSE
var_dump(min(-100, -10, NULL, 10, 100)); // NULL - (bool) NULL < (bool) -100 is FALSE < TRUE
?>
Boolean/null comparison
Transcription of standard array comparison
<?php
// Arrays are compared like this with standard comparison operators as well as the spaceship operator.
function standard_array_compare($op1, $op2)
{
if (count($op1) < count($op2)) {
return -1; // $op1 < $op2
} elseif (count($op1) > count($op2)) {
return 1; // $op1 > $op2
}
foreach ($op1 as $key => $val) {
if (!array_key_exists($key, $op2)) {
return 1;
} elseif ($val < $op2[$key]) {
return -1;
} elseif ($val > $op2[$key]) {
return 1;
}
}
return 0; // $op1 == $op2
}
?>
Transcription of standard array comparison
Comparison of floating point numbers
Because of the way floats are represented internally, you
should not test two floats for equality.
See the documentation for float for more information.
Be aware that PHP's type juggling is not always obvious when comparing values of different types,
particularly comparing s to s or s to s. It is therefore generally
advisable to use === and !== comparisons rather than
== and != in most cases.
Incomparable Values
While identity comparison (=== and !==)
can be applied to arbitrary values, the other comparison operators should only be
applied to comparable values. The result of comparing incomparable values is
undefined, and should not be relied upon.
strcasecmp
strcmp
Array operators
Types
Ternary Operator
Another conditional operator is the "?:" (or ternary) operator.
Assigning a default value
<?php
// Example usage for: Ternary Operator
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
// The above is identical to this if/else statement
if (empty($_POST['action'])) {
$action = 'default';
} else {
$action = $_POST['action'];
}
?>
The expression (expr1) ? (expr2) : (expr3)
evaluates to expr2 if
expr1 evaluates to , and
expr3 if
expr1 evaluates to .
Assigning a default value
It is possible to leave out the middle part of the ternary operator.
Expression expr1 ?: expr3 evaluates to
the result of expr1 if expr1
evaluates to , and expr3 otherwise.
expr1 is only evaluated once in this case.
Please note that the ternary operator is an expression, and that it
doesn't evaluate to a variable, but to the result of an expression. This
is important to know if you want to return a variable by reference.
The statement return $var == 42 ? $a : $b; in a
return-by-reference function will therefore not work and a warning is
issued.
It is recommended to avoid "stacking" ternary expressions.
PHP's behaviour when using more than one unparenthesized ternary operator within a single
expression is non-obvious compared to other languages.
Indeed prior to PHP 8.0.0, ternary expressions were evaluated left-associative,
instead of right-associative like most other programming languages.
Relying on left-associativity is deprecated as of PHP 7.4.0.
As of PHP 8.0.0, the ternary operator is non-associative.
Non-obvious Ternary Behaviour
<?php
// on first glance, the following appears to output 'true'
echo (true ? 'true' : false ? 't' : 'f');
// however, the actual output of the above is 't' prior to PHP 8.0.0
// this is because ternary expressions are left-associative
// the following is a more obvious version of the same code as above
echo ((true ? 'true' : false) ? 't' : 'f');
// here, one can see that the first expression is evaluated to 'true', which
// in turn evaluates to (bool) true, thus returning the true branch of the
// second ternary expression.
?>
Non-obvious Ternary Behaviour
Chaining of short-ternaries (?:), however, is stable and behaves reasonably.
It will evaluate to the first argument that evaluates to a non-falsy value. Note that undefined
values will still raise a warning.
Short-ternary chaining
<?php
echo 0 ?: 1 ?: 2 ?: 3, PHP_EOL; //1
echo 0 ?: 0 ?: 2 ?: 3, PHP_EOL; //2
echo 0 ?: 0 ?: 0 ?: 3, PHP_EOL; //3
?>
Short-ternary chaining
Null Coalescing Operator
Another useful shorthand operator is the "??" (or null coalescing) operator.
Assigning a default value
<?php
// Example usage for: Null Coalesce Operator
$action = $_POST['action'] ?? 'default';
// The above is identical to this if/else statement
if (isset($_POST['action'])) {
$action = $_POST['action'];
} else {
$action = 'default';
}
?>
The expression (expr1) ?? (expr2) evaluates to
expr2 if expr1 is
, and expr1 otherwise.
Assigning a default value
In particular, this operator does not emit a notice or warning if the left-hand side
value does not exist, just like isset. This is especially
useful on array keys.
Please note that the null coalescing operator is an expression, and that it
doesn't evaluate to a variable, but to the result of an expression. This
is important to know if you want to return a variable by reference.
The statement return $foo ?? $bar; in a
return-by-reference function will therefore not work and a warning is
issued.
The null coalescing operator has low precedence. That means if mixing it
with other operators (such as string concatenation or arithmetic operators)
parentheses will likely be required.
Please note that the null coalescing operator allows for simple nesting:
Nesting null coalescing operator
<?php
$foo = null;
$bar = null;
$baz = 1;
$qux = 2;
echo $foo ?? $bar ?? $baz ?? $qux; // outputs 1
?>
Nesting null coalescing operator
Operator Precedence
The precedence of an operator specifies how "tightly" it binds two
expressions together. For example, in the expression 1 +
5 * 3, the answer is 16 and not
18 because the multiplication ("*") operator
has a higher precedence than the addition ("+") operator.
Parentheses may be used to force precedence, if necessary. For
instance: (1 + 5) * 3 evaluates to
18.
When operators have equal precedence their associativity decides
how the operators are grouped. For example "-" is left-associative, so
1 - 2 - 3 is grouped as (1 - 2) - 3
and evaluates to -4. "=" on the other hand is
right-associative, so $a = $b = $c is grouped as
$a = ($b = $c).
Operators of equal precedence that are non-associative cannot be used
next to each other, for example 1 < 2 > 1 is
illegal in PHP. The expression 1 <= 1 == 1 on the
other hand is legal, because the == operator has a lower
precedence than the <= operator.
Associativity is only meaningful for binary (and ternary) operators.
Unary operators are either prefix or postfix so this notion is not applicable.
For example !!$a can only be grouped as !(!$a).
Use of parentheses, even when not strictly necessary, can often increase
readability of the code by making grouping explicit rather than relying
on the implicit operator precedence and associativity.
The following table lists the operators in order of precedence, with
the highest-precedence ones at the top. Operators on the same line
have equal precedence, in which case associativity decides grouping.
Operator Precedence
Associativity
Operators
Additional Information
(n/a)
clone
new
clone and new
right
**
arithmetic
(n/a)
+
-
++
--
~
(int)
(float)
(string)
(array)
(object)
(bool)
@
arithmetic (unary + and -),
increment/decrement,
bitwise,
type casting
error control
left
instanceof
type
(n/a)
!
logical
left
*
/
%
arithmetic
left
+
-
.
arithmetic (binary + and -),
array
string (. prior to PHP 8.0.0)
left
bitwise
left
.
string (as of PHP 8.0.0)
left
|
pipe
non-associative
=
=
comparison
non-associative
==
!=
===
!==
=
comparison
left
bitwise
references
left
^
bitwise
left
|
bitwise
left
logical
left
||
logical
right
??
null coalescing
non-associative
? :
ternary
(left-associative prior to PHP 8.0.0)
right
=
+=
-=
*=
**=
/=
.=
%=
=
|=
^=
=
=
??=
assignment
(n/a)
yield from
yield from
(n/a)
yield
yield
(n/a)
print
print
left
and
logical
left
xor
logical
left
or
logical
(n/a)
throw
throw
Operator Precedence
Associativity
<?php
$a = 3 * 3 % 5; // (3 * 3) % 5 = 4
var_dump($a);
$a = 1;
$b = 2;
$a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5
var_dump($a, $b);
?>
Associativity
The ternary operator specifically requires the use of parenthesis to
disambiguate precedence.
Explicit Precedence
<?php
$a = true ? 0 : (true ? 1 : 2);
var_dump($a);
// this is not allowed since PHP 8
// $a = true ? 0 : true ? 1 : 2;
?>
Explicit Precedence
Operator precedence and associativity only determine how expressions
are grouped, they do not specify an order of evaluation. PHP does not
(in the general case) specify in which order an expression is evaluated
and code that assumes a specific order of evaluation should be avoided,
because the behavior can change between versions of PHP or depending on
the surrounding code.
Undefined order of evaluation
<?php
$a = 1;
echo $a + $a++; // may print either 2 or 3
$i = 1;
$array[$i] = $i++; // may set either index 1 or 2
?>
+, - and . precedence
<?php
$x = 4;
// this line might result in unexpected output:
echo "x minus one equals " . $x-1 . ", or so I hope\n";
// the desired precedence can be enforced by using parentheses:
echo "x minus one equals " . ($x-1) . ", or so I hope\n";
// this is not allowed, and throws a TypeError:
echo (("x minus one equals " . $x) - 1) . ", or so I hope\n";
?>
-1, or so I hope
-1, or so I hope
Fatal error: Uncaught TypeError: Unsupported operand types: string - int
Prior to PHP 8, +, - and . had the same precedence
<?php
$x = 4;
// this line might result in unexpected output:
echo "x minus one equals " . $x-1 . ", or so I hope\n";
// because it is evaluated like this line (prior to PHP 8.0.0):
echo (("x minus one equals " . $x) - 1) . ", or so I hope\n";
// the desired precedence can be enforced by using parentheses:
echo "x minus one equals " . ($x-1) . ", or so I hope\n";
?>
-1, or so I hope
-1, or so I hope
x minus one equals 3, or so I hope
Undefined order of evaluation
+, - and . precedence
Prior to PHP 8, +, - and . had the same precedence
Although = has a lower precedence than
most other operators, PHP will still allow expressions
similar to the following: if (!$a = foo()),
in which case the return value of foo() is
put into $a.
Error Control Operators
PHP supports one error control operator: the at sign (@).
When prepended to an expression in PHP, any diagnostic error that might
be generated by that expression will be suppressed.
If a custom error handler function is set with
set_error_handler, it will still be called even though
the diagnostic has been suppressed.
Prior to PHP 8.0.0, the error_reporting called inside the custom error handler
always returned 0 if the error was suppressed by the @ operator.
As of PHP 8.0.0, it returns the value of this (bitwise) expression:
E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE.
Any error message generated by the expression is available in the "message"
element of the array returned by error_get_last.
The result of that function will change on each error, so it needs to be checked early.
Intentional file error
<?php
$my_file = @file ('non_existent_file') or
die ("Failed opening file: error was '" . error_get_last()['message'] . "'");
?>
Intentional file error
Suppressing Expressions
<?php
// this works for any expression, not just functions:
$value = @$cache[$key];
// will not issue a notice if the index $key doesn't exist.
?>
Suppressing Expressions
The @-operator works only on
expressions.
A simple rule of thumb is: if one can take the value of something,
then one can prepend the @ operator to it.
For instance, it can be prepended to variables, functions calls,
certain language construct calls (e.g. include),
and so forth.
It cannot be prepended to function or class definitions,
or conditional structures such as if and
, and so forth.
Prior to PHP 8.0.0, it was possible for the @ operator
to disable critical errors that will terminate script execution.
For example, prepending @ to a call of a function
which did not exist, by being unavailable or mistyped, would cause
the script to terminate with no indication as to why.
error_reporting
Error Handling and Logging functions
String Operators
There are two string operators. The first is the
concatenation operator ('.'), which returns the concatenation of its
right and left arguments. The second is the concatenating assignment
operator ('.='), which appends the argument on the right side to
the argument on the left side. Please read Assignment
Operators for more information.
String Concatenating
<?php
$a = "Hello ";
$b = $a . "World!"; // now $b contains "Hello World!"
var_dump($b);
$a = "Hello ";
$a .= "World!"; // now $a contains "Hello World!"
var_dump($a);
?>
String Concatenating
String type
String functions
Incrementing/Decrementing Operators
PHP supports pre- and post-increment and decrement operators.
Those unary operators allow to increment or decrement the value by one.
Increment/decrement Operators
Examples of Increment/Decrement
<?php
echo 'Post-increment:', PHP_EOL;
$a = 5;
var_dump($a++);
var_dump($a);
echo 'Pre-increment:', PHP_EOL;
$a = 5;
var_dump(++$a);
var_dump($a);
echo 'Post-decrement:', PHP_EOL;
$a = 5;
var_dump($a--);
var_dump($a);
echo 'Pre-decrement:', PHP_EOL;
$a = 5;
var_dump(--$a);
var_dump($a);
?>
Post-increment:
int(5)
int(6)
Pre-increment:
int(6)
int(6)
Post-decrement:
int(5)
int(4)
Pre-decrement:
int(4)
int(4)
The increment and decrement operators have no effect on values
of type bool.
A E_WARNING is emitted as of PHP 8.3.0,
because this will implicitly cast the value to int in the future.
The decrement operator has no effect on values
of type null.
A E_WARNING is emitted as of PHP 8.3.0,
because this will implicitly cast the value to int in the future.
The decrement operator has no effect on non-
numeric string.
A E_WARNING is emitted as of PHP 8.3.0,
because a TypeError will be thrown in the future.
Internal objects that support overloading addition and/or subtraction
can also be incremented and/or decremented.
One such internal object is GMP.
Examples of Increment/Decrement
The increment and decrement operators have no effect on values
of type bool.
A E_WARNING is emitted as of PHP 8.3.0,
because this will implicitly cast the value to int in the future.
The decrement operator has no effect on values
of type null.
A E_WARNING is emitted as of PHP 8.3.0,
because this will implicitly cast the value to int in the future.
The decrement operator has no effect on non-
numeric string.
A E_WARNING is emitted as of PHP 8.3.0,
because a TypeError will be thrown in the future.
Internal objects that support overloading addition and/or subtraction
can also be incremented and/or decremented.
One such internal object is GMP.
PERL string increment feature
This feature is soft-deprecated as of PHP 8.3.0.
The str_increment function should be used instead.
It is possible to increment a non-
numeric string
in PHP. The string must be an alphanumerical ASCII string.
Which increments letters up to the next letter, when reaching the letter
Z the increment is carried to the value on the left.
For example, $a = 'Z'; $a++; turns $a
into 'AA'.
PERL string increment example
If the alphanumerical string can be interpreted as a
numeric string
it will be cast to an int or float.
This is particularly an issue with strings that look like a floating point
numbers written in exponential notation.
The str_increment function does not suffer from
these implicit type cast.
Alphanumerical string converted to float
This is because the value "5e0" is interpreted
as a float and cast to the value 5.0
before being incremented.
Assignment Operators
The basic assignment operator is "=". Your first inclination might
be to think of this as "equal to". Don't. It really means that the
left operand gets set to the value of the expression on the
right (that is, "gets set to").
The value of an assignment expression is the value assigned. That
is, the value of "$a = 3" is 3. This allows you to do some tricky
things:
Nested Assignments
<?php
$a = ($b = 4) + 5; // $a is equal to 9 now, and $b has been set to 4.
var_dump($a);
?>
Nested Assignments
In addition to the basic assignment operator, there are "combined
operators" for all of the binary
arithmetic, array union and string operators that allow you to use a value in an
expression and then set its value to the result of that expression. For
example:
Combined Assignments
<?php
$a = 3;
$a += 5; // sets $a to 8, as if we had said: $a = $a + 5;
$b = "Hello ";
$b .= "There!"; // sets $b to "Hello There!", just like $b = $b . "There!";
var_dump($a, $b);
?>
Combined Assignments
Note that the assignment copies the original variable to the new
one (assignment by value), so changes to one will not affect the
other. This may also have relevance if you need to copy something
like a large array inside a tight loop.
An exception to the usual assignment by value behaviour within PHP occurs
with objects, which are assigned by reference.
Objects may be explicitly copied via the clone keyword.
Assignment by Reference
Assignment by reference is also supported, using the
"$var = &$othervar;" syntax.
Assignment by reference means that both variables end up pointing at the
same data, and nothing is copied anywhere.
Assigning by reference
<?php
$a = 3;
$b = &$a; // $b is a reference to $a
print "$a\n"; // prints 3
print "$b\n"; // prints 3
$a = 4; // change $a
print "$a\n"; // prints 4
print "$b\n"; // prints 4 as well, since $b is a reference to $a, which has
// been changed
?>
Assigning by reference
The new
operator returns a reference automatically, as such assigning the result of
new by reference is an error.
new Operator By-Reference
<?php
class C {}
$o = &new C;
?>
Parse error: syntax error, unexpected token ";", expecting "("
new Operator By-Reference
More information on references and their potential uses can be found in
the References Explained
section of the manual.
Arithmetic Assignment Operators
Bitwise Assignment Operators
Other Assignment Operators
arithmetic operators
bitwise operators
null coalescing operator
New Classes and Interfaces
cURL
CURLStringFile
FileInfo
finfo
FTP
FTP\Connection
IMAP
IMAP\Connection
Intl
IntlDatePatternGenerator
LDAP
LDAP\Connection
LDAP\Result
LDAP\ResultEntry
PgSQL
PgSql\Connection
PgSql\Lob
PgSql\Result
PSpell
PSpell\Config
PSpell\Dictionary
Reflection
ReflectionFiber
New Functions
PHP Core
array_is_list
GD
imagecreatefromavif
imageavif
MySQLi
mysqli_result::fetch_column
mysqli_fetch_column
Process Control
pcntl_rfork
Reflection
ReflectionFunctionAbstract::getClosureUsedVariables
Standard
fsync
fdatasync
Sodium
XChaCha20
sodium_crypto_stream_xchacha20
sodium_crypto_stream_xchacha20_keygen
sodium_crypto_stream_xchacha20_xor
Ristretto255
Ristretto255 functions are available as of libsodium 1.0.18.
sodium_crypto_core_ristretto255_add
sodium_crypto_core_ristretto255_from_hash
sodium_crypto_core_ristretto255_is_valid_point
sodium_crypto_core_ristretto255_random
sodium_crypto_core_ristretto255_scalar_add
sodium_crypto_core_ristretto255_scalar_complement
sodium_crypto_core_ristretto255_scalar_invert
sodium_crypto_core_ristretto255_scalar_mul
sodium_crypto_core_ristretto255_scalar_negate
sodium_crypto_core_ristretto255_scalar_random
sodium_crypto_core_ristretto255_scalar_reduce
sodium_crypto_core_ristretto255_scalar_sub
sodium_crypto_core_ristretto255_sub
sodium_crypto_scalarmult_ristretto255
sodium_crypto_scalarmult_ristretto255_base
New Global Constants
cURL
CURLOPT_DOH_URL
CURLOPT_ISSUERCERT_BLOB
CURLOPT_PROXY_ISSUERCERT
CURLOPT_PROXY_ISSUERCERT_BLOB
CURLOPT_PROXY_SSLCERT_BLOB
CURLOPT_PROXY_SSLKEY_BLOB
CURLOPT_SSLCERT_BLOB
CURLOPT_SSLKEY_BLOB
GD
IMG_AVIF
IMG_WEBP_LOSSLESS
MySQLi
MYSQLI_REFRESH_REPLICA
This constant has been added as a replacement for
MYSQLI_REFRESH_SLAVE,
in line with an upstream change in MySQL.
The old constant is still available for backwards-compatibility reasons,
but may be deprecated/removed in the future.
PCNTL
PRIO_DARWIN_BG
PRIO_DARWIN_THREAD
POSIX
POSIX_RLIMIT_KQUEUES
POSIX_RLIMIT_NPTS
Sockets
The following socket options are now defined if they are supported:
SO_ACCEPTFILTER
SO_DONTTRUNC
SO_WANTMORE
SO_MARK
TCP_DEFER_ACCEPT
Sodium
SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES
SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES
SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_BYTES
SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES
SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES
SODIUM_CRYPTO_CORE_RISTRETTO255_HASHBYTES
SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES
SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES
Tokenizer
T_READONLY
Backward Incompatible Changes
PHP Core
$GLOBALS Access Restrictions
Access to the $GLOBALS array is now subject to
a number of restrictions.
Read and write access to individual array elements like
$GLOBALS['var'] continues to work as-is.
Read-only access to the entire $GLOBALS array also
continues to be supported.
However, write access to the entire $GLOBALS array
is no longer supported. For example, array_pop($GLOBALS)
will result in an error.
Usage of static Variables in Inherited Methods
When a method using static variables is inherited (but not overridden), the
inherited method will now share static variables with the parent method.
<?php
class A {
public static function counter() {
static $counter = 0;
$counter++;
return $counter;
}
}
class B extends A {}
var_dump(A::counter()); // int(1)
var_dump(A::counter()); // int(2)
var_dump(B::counter()); // int(3), previously int(1)
var_dump(B::counter()); // int(4), previously int(2)
?>
This means that static variables in methods now behave the same way as
static properties.
Optional parameters specified before required parameters
An optional parameter
specified before required parameters is now always treated as required,
even when called using
named arguments.
As of PHP 8.0.0, but prior to PHP 8.1.0, the below emits a deprecation notice
on the definition, but runs successfully when called. As of PHP 8.1.0, an error
of class ArgumentCountError is thrown, as it would be when
called with positional arguments.
<?php
function makeyogurt($container = "bowl", $flavour)
{
return "Making a $container of $flavour yogurt.\n";
}
try
{
echo makeyogurt(flavour: "raspberry");
}
catch (Error $e)
{
echo get_class($e), ' - ', $e->getMessage(), "\n";
}
?>
Deprecated: Required parameter $flavour follows optional parameter $container
in example.php on line 3
Making a bowl of raspberry yogurt.
Deprecated: Optional parameter $container declared before required parameter
$flavour is implicitly treated as a required parameter in example.php on line 3
ArgumentCountError - makeyogurt(): Argument #1 ($container) not passed
Note that a default value of can be used before required parameters to
specify a nullable type,
but the parameter will still be required.
Return Type Compatibility with Internal Classes
Most non-final internal methods now require overriding methods to declare
a compatible return type, otherwise a deprecated notice is emitted during
inheritance validation.
In case the return type cannot be declared for an overriding method due to
PHP cross-version compatibility concerns,
a ReturnTypeWillChange attribute can be added to silence
the deprecation notice.
New Keywords
readonly is a keyword now. However, it still may be used
as function name.
never is now a reserved word, so it cannot be used to name a class,
interface or trait, and is also prohibited from being used in namespaces.
Resource to Object Migration
Several s have been migrated to s.
Return value checks using is_resource should be replaced with checks for .
The FileInfo functions now accept and return
finfo objects instead of
fileinfo s.
The FTP functions now accept and return
FTP\Connection objects instead of
ftp s.
The IMAP functions now accept and return
IMAP\Connection objects instead of
imap s.
The LDAP functions now accept and return
LDAP\Connection objects instead of
ldap link s.
The LDAP functions now accept and return
LDAP\Result objects instead of
ldap result s.
The LDAP functions now accept and return
LDAP\ResultEntry objects instead of
ldap result entry s.
The PgSQL functions now accept and return
PgSql\Connection objects instead of
pgsql link s.
The PgSQL functions now accept and return
PgSql\Result objects instead of
pgsql result s.
The PgSQL functions now accept and return
PgSql\Lob objects instead of
pgsql large object s.
The PSpell functions now accept and return
PSpell\Dictionary objects instead of
pspell s.
The PSpell functions now accept and return
PSpell\Config objects instead of
pspell config s.
MySQLi
mysqli_fetch_fields, and
mysqli_fetch_field_direct will now always return
0 for the max_length.
This information can be computed by iterating over the result set,
and taking the maximum length. This is what PHP was doing
internally previously.
The MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH
option no longer has any effect.
The MYSQLI_STORE_RESULT_COPY_DATA
option no longer has any effect. Passing any value to the
mode parameter of
mysqli::store_result no longer has any effect.
mysqli::connect now returns instead of on success.
The default error handling mode has been changed from "silent" to "exceptions"
See the MySQLi reporting mode
page for more details on what this entails,
and how to explicitly set this attribute.
To restore the previous behaviour use:
mysqli_report(MYSQLI_REPORT_OFF);
Classes extending mysqli_stmt::execute
are now required to specify the additional optional parameter.
MySQLnd
The mysqlnd.fetch_data_copy
INI directive has been removed.
This should not result in user-visible behavior changes.
OpenSSL
EC private keys will now be exported in PKCS#8 format rather than
traditional format, just like all other keys.
openssl_pkcs7_encrypt and
openssl_cms_encrypt will now to default using
AES-128-CBC rather than RC2-40. The RC2-40 cipher is considered
insecure and not enabled by default by OpenSSL 3.
PHP Data Objects
PDO::ATTR_STRINGIFY_FETCHES now stringifies values
of type to "0" or
"1". Previously s were not stringified.
Calling PDOStatement::bindColumn with
PDO::PARAM_LOB will now constantly bind a stream
result when PDO::ATTR_STRINGIFY_FETCHES is not enabled.
Previously, the result would either be a stream or a string depending on
the used database driver and the time the binding is performed.
MySQL Driver
Integers and floats in result sets will now be returned using native
PHP types instead of s when using emulated prepared statements.
This matches the behavior of native prepared statements.
The previous behaviour can be restored by enabling the
PDO::ATTR_STRINGIFY_FETCHES option.
SQLite Driver
Integers and floats in results sets will now be returned using native
PHP types.
The previous behaviour can be restored by enabling the
PDO::ATTR_STRINGIFY_FETCHES option.
Phar
To comply with the ArrayAccess interface,
Phar::offsetUnset and
PharData::offsetUnset no longer return a .
Standard
version_compare no longer accepts undocumented operator abbreviations.
htmlspecialchars,
htmlentities,
htmlspecialchars_decode,
html_entity_decode,
and get_html_translation_table
now use ENT_QUOTES | ENT_SUBSTITUTE rather than
ENT_COMPAT by default.
This means that ' is escaped to
#039; while previously nothing was done.
Additionally, malformed UTF-8 will be replaced by a Unicode substitution
character, instead of resulting in an empty string.
debug_zval_dump now prints the refcount of a reference
wrappers with their refcount, instead of only prepending
to the value.
This more accurately models reference representation since PHP 7.0.
debug_zval_dump now prints interned
instead of a dummy refcount for interned strings and immutable arrays.
Standard PHP Library (SPL)
SplFixedArray, will now be JSON encoded like an
Other Changes
Changes in SAPI Modules
CLI
Using -a without the readline extension will now result in an error.
Previously, -a without readline had the same behavior as
calling php without any arguments, apart from printing an additional
"Interactive mode enabled" message.
This mode was not interactive.
PHPDBG
Remote functionality from phpdbg has been removed.
Changed Functions
Core
The order of properties used in , var_dump,
serialize, object comparison, etc. was changed.
Properties are now ordered naturally according to their declaration
and inheritance. Properties declared in a base class are going
to be before the child properties.
This order is consistent with internal layout of properties in
zend_object structure and repeats the order in
default_properties_table[] and properties_info_table[].
The old order was not documented and was caused by class inheritance implementation details.
Filter
The FILTER_FLAG_ALLOW_OCTAL flag of the
FILTER_VALIDATE_INT filter
now accept octal string with the leading octal prefix
("0o"/"0O").
GMP
All GMP functions now accept octal string with the leading octal prefix
("0o"/"0O").
PDO ODBC
PDO::getAttribute with
PDO::ATTR_SERVER_INFO and
PDO::ATTR_SERVER_VERSION
now return values instead of throwing PDOException.
Reflection
ReflectionProperty::setAccessible and
ReflectionMethod::setAccessible
no longer have an effect.
Properties and methods are now always considered accessible via Reflection.
Standard
syslog is now binary safe.
Other Changes to Extensions
GD
imagewebp can now do lossless WebP encoding
by passing IMG_WEBP_LOSSLESS as the quality.
This constant is only defined, if the used libgd supports
lossless WebP encoding.
MySQLi
mysqli_stmt::next_result and
mysqli::fetch_all
are now available when linking against libmysqlclient.
OpenSSL
The OpenSSL extension now requires at least OpenSSL version 1.0.2.
OpenSSL 3.0 is now supported. Be aware that many ciphers are no longer
enabled by default (part of the legacy provider), and that parameter
validation (e.g. minimum key sizes) is stricter now.
Phar
SHA256 is now used by default for signatures.
Added support for OpenSSL_SHA256 and OpenSSL_SHA512 signatures.
SNMP
Added support for SHA256 and SHA512 for the security protocol.
Standard
--with-password-argon2 now uses pkg-config to detect libargon2.
As such, an alternative libargon2 location should now be specified using
PKG_CONFIG_PATH.
Changes to INI File Handling
The log_errors_max_len
INI directive has been removed.
It no longer had an effect since PHP 8.0.0.
A leading dollar in a quoted string can now be escaped: "\${" will now be
interpreted as a string with contents ${.
Backslashes in double quoted strings are now more consistently treated as
escape characters. Previously, "foo\\" followed by
something other than a newline was not considered as a terminated string.
It is now interpreted as a string with contents foo\.
However, as an exception, the string "foo\"
followed by a newline will continue to be treated as a valid string with
contents foo\ rather than an unterminated string.
This exception exists to support naive uses of Windows file paths such as
"C:\foo\".
New Features
PHP Core
Integer Octal Literal Prefix
Octal integers can now use an explicit
0o/0O
prefix in integer literals,
similarly to binary and hexadecimal integer literals.
<?php
014; // Non-prefix octal literal
0o14; // Prefixed octal literal
?>
Array Unpacking with String Keys
Added support for array unpacking with strings keys.
<?php
$arr1 = [1, 'a' => 'b'];
$arr2 = [...$arr1, 'c' => 'd']; //[1, 'a' => 'b', 'c' => 'd']
?>
Named Argument After Argument Unpacking
It is now possible to specify named arguments after an argument unpack.
e.g.
foo(...$args, named: $arg).
full-path Key for File Uploads
File uploads now provide an additional full_path key,
which contains the full path (rather than just the basename) of the uploaded file.
This is intended for use in conjunction with "upload webkitdirectory".
Enumerations
Support for Enumerations has been added.
Fibers
Support for Fibers has been added.
First Class Callable Syntax
Closures for callables can now be created using the syntax myFunc(...),
which is identical to Closure::fromCallable('myFunc').
The ... is part of the syntax, and not an omission.
Intersection Types
Support for intersection types has been added.
Intersection types cannot be used together with
union types
Never type
A new return only type has been added.
This indicates that a function either exit,
throws an exception, or doesn't terminate.
in Initializers
It is now possible to use new ClassName() expressions as the
default value of a parameter, static variable, global constant initializers,
and as attribute arguments.
Objects can also be passed to define now.
Readonly properties
Support for readonly has been added.
Final class constants
Added support for the final modifier for class constants.
Also, interface constants become overridable by default.
CURL
Added the CURLOPT_DOH_URL option.
Added options for blob certificate when libcurl = 7.71.0:
CURLOPT_ISSUERCERT_BLOB
CURLOPT_PROXY_ISSUERCERT
CURLOPT_PROXY_ISSUERCERT_BLOB
CURLOPT_PROXY_SSLCERT_BLOB
CURLOPT_PROXY_SSLKEY_BLOB
CURLOPT_SSLCERT_BLOB
CURLOPT_SSLKEY_BLOB
Added CURLStringFile, which can be used to post
a file from a rather than a file:
<?php
$file = new CURLStringFile($data, 'filename.txt', 'text/plain');
curl_setopt($curl, CURLOPT_POSTFIELDS, ['file' => $file]);
?>
FPM
Added openmetrics status format. It can be used by Prometheus to fetch FPM
metrics.
Added new pool option for the dynamic process manager called
pm.max_spawn_rate. It allows to start a number of children
at a faster rate when dynamic pm is selected.
The default value is 32 which was the previous
hard coded value.
GD
Avif support is now available through
imagecreatefromavif and
imageavif,
if libgd has been built with Avif support.
Hash
The following functions hash,
hash_file, and hash_init
now support an additional optional options
argument, which can be used to pass algorithm specific data.
MurmurHash3
Added support for MurmurHash3 with streaming
support. The following variants are implemented:
murmur3a, 32-bit hash
murmur3c, 128-bit hash for x86
murmur3f, 128-bit hash for x64
The initial hash state can be passed through the seed
key in the options array, for example:
<?php
$h = hash("murmur3f", $data, options: ["seed" => 42]);
echo $h, "\n";
?>
A valid seed value is within the range from 0
to the platform defined UINT_MAX, usually
4294967295.
xxHash
Added support for xxHash.
The following variants are implemented:
xxh32, 32-bit hash
xxh64, 64-bit hash
xxh3, 64-bit hash
xxh128, 128-bit hash
The initial hash state can be passed through the seed
key in the options array, for example:
<?php
$h = hash("xxh3", $data, options: ["seed" => 42]);
echo $h, "\n";
?>
Secret usage is supported through passing the secret
key in the options array, too:
<?php
$h = hash("xxh3", $data, options: ["secret" => "at least 136 bytes long secret here"]);
echo $h, "\n";
?>
The quality of the custom secret is crucial for the quality of the resulting hash.
It is highly recommended for the secret to use the best possible entropy.
MySQLi
New INI directive mysqli.local_infile_directory
The mysqli.local_infile_directory
INI directive has been added, which can be used to specify a directory from
which files are allowed to be loaded. It is only meaningful if
mysqli.allow_local_infile
is not enabled, as all directories are allowed in that case.
Binding parameters in execute
It is now possible to bind parameters by passing them as an array to
mysqli_stmt::execute. All values will be bound as
strings. Only list arrays are allowed. This new feature is not available
when MySQLi is compiled with libmysqlclient.
<?php
$stmt = $mysqli->prepare('INSERT INTO users(id, name) VALUES(?,?)');
$stmt->execute([1, $username]);
?>
New method mysqli_result::fetch_column
mysqli_result::fetch_column
has been added to allow fetching a single scalar value from the result set.
The new method accepts an optional 0-based column
parameter of type specifying which column to fetch from.
<?php
$result = $mysqli->query('SELECT username FROM users WHERE id = 123');
echo $result->fetch_column();
?>
PDO
The PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY attribute
has been added, which can be used to specify a directory from which files
are allowed to be loaded.
It is only meaningful if PDO::MYSQL_ATTR_LOCAL_INFILE
is not enabled, as all directories are allowed in that case.
PDO_SQLite
SQLite's "file:" DSN syntax is now supported,
which allows specifying additional flags.
This feature is not available if open_basedir is set.
<?php
new PDO('sqlite:file:path/to/sqlite.db?mode=ro')
?>
POSIX
Added POSIX_RLIMIT_KQUEUES and POSIX_RLIMIT_NPTS.
These rlimits are only available on FreeBSD.
Standard
fputcsv now accepts a new
eol argument which allows to define a custom
End of Line sequence, the default remains the same and is "\n".
SPL
SplFileObject::fputcsv now accepts a new
eol argument which allows to define a custom
End of Line sequence, the default remains the same and is "\n".
Deprecated Features
PHP Core
Implementing Serializable without
__serialize and __unserialize
Either only the new methods should be implemented, if no support for
PHP prior to version 7.4 is provided, or both should be implemented.
Passing to non-nullable parameters of built-in functions
Scalar types for built-in functions are nullable by default.
This behaviour is deprecated to align with the behaviour of user-defined
functions, where scalar types need to be marked as nullable explicitly.
<?php
var_dump(str_contains("foobar", null));
// Deprecated: Passing null to parameter #2 ($needle) of type string
// is deprecated
?>
Implicit incompatible to conversions
The implicit conversion of to which
leads to a loss in precision is now deprecated.
This affects keys, type declarations in coercive mode,
and operators working on s.
<?php
$a = [];
$a[15.5]; // deprecated, as key value loses the 0.5 component
$a[15.0]; // ok, as 15.0 == 15
?>
Calling a static element on a trait
Calling a static method, or accessing a
static property directly on a trait is deprecated.
Static methods and properties should only be accessed on a class using the trait.
Returning a non- from __sleep
Returning a value which is not an from
__sleep() now generates a diagnostic.
Returning by reference from a void function
<?php
function &test(): void {}
?>
Such a function is contradictory, and already emits the following
E_NOTICE when called:
Only variable references should be returned by reference.
Autovivification from
Autovivification is the process of creating a new when
appending to a value.
Autovivification is prohibited from scalar values, however
was an exception. This is now deprecated.
<?php
$arr = false;
$arr[] = 2; // deprecated
?>
Autovivification from and undefined values is still allowed:
<?php
// From undefined
$arr[] = 'some value';
$arr['doesNotExist'][] = 2;
// From null
$arr = null;
$arr[] = 2;
?>
ctype
Verifying non-string arguments
Passing a non-string argument is deprecated.
In the future, the argument will be interpreted as a string instead
of an ASCII codepoint.
Depending on the intended behavior, the argument should either be
cast to or an explicit call to
chr should be made.
All ctype_*() functions are affected.
Date
date_sunrise and date_sunset
have been deprecated in favor of date_sun_info.
strptime has been deprecated.
Use date_parse_from_format instead (for locale-independent parsing),
or IntlDateFormatter::parse (for locale-dependent parsing).
strftime and gmstrftime have been deprecated.
Use date instead (for locale-independent formatting),
or IntlDateFormatter::format (for locale-dependent formatting).
Filter
The FILTER_SANITIZE_STRING and
FILTER_SANITIZE_STRIPPED filters are deprecated.
The filter.default
INI directive is deprecated.
GD
The num_points of imagepolygon,
imageopenpolygon and imagefilledpolygon
has been deprecated.
Hash
The mhash,
mhash_keygen_s2k,
mhash_count,
mhash_get_block_size,
and mhash_get_hash_name have been deprecated.
Use the hash_*() functions instead.
IMAP
The NIL constant has been deprecated.
Use 0 instead.
Intl
Calling IntlCalendar::roll with a
argument is deprecated.
Use 1 and -1 instead of
and respectively.
Multibyte String
Calling mb_check_encoding without any arguments
is deprecated.
MySQLi
The mysqli_driver::$driver_version property
has been deprecated.
It was meaningless and outdated, use PHP_VERSION_ID
instead.
Calling mysqli::get_client_info or
mysqli_get_client_info with the
mysqli argument has been deprecated.
Call mysqli_get_client_info without any arguments
to obtain the version information of the client library.
The mysqli::init method has been deprecated.
Replace calls to parent::init with
parent::__construct.
OCI8
The oci8.old_oci_close_semantics
INI directive is deprecated.
ODBC
odbc_result_all has been deprecated.
PDO
The PDO::FETCH_SERIALIZE fetch mode has been deprecated.
PgSQL
Not passing the connection argument to all pgsql_*()
functions has been deprecated.
SOAP
The ssl_method option of
SoapClient::__construct has been deprecated
in favor of SSL stream context options.
Standard
Calling key, current,
next, prev,
reset, or end
on s is deprecated.
Either convert the to an using get_mangled_object_vars
first, or use the methods provided by a class that implements
Iterator, such as ArrayIterator, instead.
The auto_detect_line_endings
INI directive is deprecated.
If necessary, handle "\r" line breaks manually instead.
The FILE_BINARY and
FILE_TEXT constants have been deprecated.
They never had any effect.
New functions
PHP Core
stream_isatty
sapi_windows_vt100_support
SPL
spl_object_id
DOM
DomNodeList::count
DOMNamedNodeMap::count
FTP
ftp_append
GD
imagesetclip
imagegetclip
imageopenpolygon
imageresolution
imagecreatefrombmp
imagebmp
Hash
hash_hmac_algos
LDAP
ldap_parse_exop
ldap_exop
ldap_exop_passwd
ldap_exop_whoami
Multibyte String
mb_chr
mb_ord
mb_scrub
Oracle OCI8
oci_register_taf_callback
oci_unregister_taf_callback
Sockets
socket_addrinfo_lookup
socket_addrinfo_connect
socket_addrinfo_bind
socket_addrinfo_explain
Sodium
sodium_add
sodium_bin2hex
sodium_compare
sodium_crypto_aead_aes256gcm_decrypt
sodium_crypto_aead_aes256gcm_encrypt
sodium_crypto_aead_aes256gcm_is_available
sodium_crypto_aead_aes256gcm_keygen
sodium_crypto_aead_chacha20poly1305_decrypt
sodium_crypto_aead_chacha20poly1305_encrypt
sodium_crypto_aead_chacha20poly1305_ietf_decrypt
sodium_crypto_aead_chacha20poly1305_ietf_encrypt
sodium_crypto_aead_chacha20poly1305_ietf_keygen
sodium_crypto_aead_chacha20poly1305_keygen
sodium_crypto_auth_keygen
sodium_crypto_auth_verify
sodium_crypto_auth
sodium_crypto_box_keypair_from_secretkey_and_publickey
sodium_crypto_box_keypair
sodium_crypto_box_open
sodium_crypto_box_publickey_from_secretkey
sodium_crypto_box_publickey
sodium_crypto_box_seal_open
sodium_crypto_box_seal
sodium_crypto_box_secretkey
sodium_crypto_box_seed_keypair
sodium_crypto_box
sodium_crypto_generichash_final
sodium_crypto_generichash_init
sodium_crypto_generichash_keygen
sodium_crypto_generichash_update
sodium_crypto_generichash
sodium_crypto_kdf_derive_from_key
sodium_crypto_kdf_keygen
sodium_crypto_kx_client_session_keys
sodium_crypto_kx_keypair
sodium_crypto_kx_publickey
sodium_crypto_kx_secretkey
sodium_crypto_kx_seed_keypair
sodium_crypto_kx_server_session_keys
sodium_crypto_pwhash_scryptsalsa208sha256_str_verify
sodium_crypto_pwhash_scryptsalsa208sha256_str
sodium_crypto_pwhash_scryptsalsa208sha256
sodium_crypto_pwhash_str_verify
sodium_crypto_pwhash_str
sodium_crypto_pwhash
sodium_crypto_scalarmult_base
sodium_crypto_scalarmult
sodium_crypto_secretbox_keygen
sodium_crypto_secretbox_open
sodium_crypto_secretbox
sodium_crypto_shorthash_keygen
sodium_crypto_shorthash
sodium_crypto_sign_detached
sodium_crypto_sign_ed25519_pk_to_curve25519
sodium_crypto_sign_ed25519_sk_to_curve25519
sodium_crypto_sign_keypair_from_secretkey_and_publickey
sodium_crypto_sign_keypair
sodium_crypto_sign_open
sodium_crypto_sign_publickey_from_secretkey
sodium_crypto_sign_publickey
sodium_crypto_sign_secretkey
sodium_crypto_sign_seed_keypair
sodium_crypto_sign_verify_detached
sodium_crypto_sign
sodium_crypto_stream_keygen
sodium_crypto_stream_xor
sodium_crypto_stream
sodium_hex2bin
sodium_increment
sodium_memcmp
sodium_memzero
sodium_pad
sodium_unpad
ZIP
ZipArchive::count
ZipArchive::setEncryptionName
ZipArchive::setEncryptionIndex
New global constants
PHP Core
PHP_FLOAT_DIG
PHP_FLOAT_EPSILON
PHP_FLOAT_MIN
PHP_FLOAT_MAX
PHP_OS_FAMILY
File Information
FILEINFO_EXTENSION
JSON
JSON_INVALID_UTF8_IGNORE
JSON_INVALID_UTF8_SUBSTITUTE
GD
IMG_EFFECT_MULTIPLY
IMG_BMP
LDAP
LDAP_EXOP_START_TLS
LDAP_EXOP_MODIFY_PASSWD
LDAP_EXOP_REFRESH
LDAP_EXOP_WHO_AM_I
LDAP_EXOP_TURN
Password Hashing
PASSWORD_ARGON2I
PASSWORD_ARGON2_DEFAULT_MEMORY_COST
PASSWORD_ARGON2_DEFAULT_TIME_COST
PASSWORD_ARGON2_DEFAULT_THREADS
PCRE
PREG_UNMATCHED_AS_NULL
PDO
PDO::PARAM_STR_NATL
PDO::PARAM_STR_CHAR
PDO::ATTR_DEFAULT_STR_PARAM
Sodium
SODIUM_LIBRARY_VERSION
SODIUM_LIBRARY_MAJOR_VERSION
SODIUM_LIBRARY_MINOR_VERSION
SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES
SODIUM_CRYPTO_AEAD_AES256GCM_NSECBYTES
SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES
SODIUM_CRYPTO_AEAD_AES256GCM_ABYTES
SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES
SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES
SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES
SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_ABYTES
SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES
SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES
SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES
SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES
SODIUM_CRYPTO_AUTH_BYTES
SODIUM_CRYPTO_AUTH_KEYBYTES
SODIUM_CRYPTO_BOX_SEALBYTES
SODIUM_CRYPTO_BOX_SECRETKEYBYTES
SODIUM_CRYPTO_BOX_PUBLICKEYBYTES
SODIUM_CRYPTO_BOX_KEYPAIRBYTES
SODIUM_CRYPTO_BOX_MACBYTES
SODIUM_CRYPTO_BOX_NONCEBYTES
SODIUM_CRYPTO_BOX_SEEDBYTES
SODIUM_CRYPTO_KDF_BYTES_MIN
SODIUM_CRYPTO_KDF_BYTES_MAX
SODIUM_CRYPTO_KDF_CONTEXTBYTES
SODIUM_CRYPTO_KDF_KEYBYTES
SODIUM_CRYPTO_KX_SEEDBYTES
SODIUM_CRYPTO_KX_SESSIONKEYBYTES
SODIUM_CRYPTO_KX_PUBLICKEYBYTES
SODIUM_CRYPTO_KX_SECRETKEYBYTES
SODIUM_CRYPTO_KX_KEYPAIRBYTES
SODIUM_CRYPTO_GENERICHASH_BYTES
SODIUM_CRYPTO_GENERICHASH_BYTES_MIN
SODIUM_CRYPTO_GENERICHASH_BYTES_MAX
SODIUM_CRYPTO_GENERICHASH_KEYBYTES
SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MIN
SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MAX
SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13
SODIUM_CRYPTO_PWHASH_ALG_DEFAULT
SODIUM_CRYPTO_PWHASH_SALTBYTES
SODIUM_CRYPTO_PWHASH_STRPREFIX
SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE
SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE
SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE
SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE
SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE
SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES
SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX
SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE
SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE
SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE
SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE
SODIUM_CRYPTO_SCALARMULT_BYTES
SODIUM_CRYPTO_SCALARMULT_SCALARBYTES
SODIUM_CRYPTO_SHORTHASH_BYTES
SODIUM_CRYPTO_SHORTHASH_KEYBYTES
SODIUM_CRYPTO_SECRETBOX_KEYBYTES
SODIUM_CRYPTO_SECRETBOX_MACBYTES
SODIUM_CRYPTO_SECRETBOX_NONCEBYTES
SODIUM_CRYPTO_SIGN_BYTES
SODIUM_CRYPTO_SIGN_SEEDBYTES
SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES
SODIUM_CRYPTO_SIGN_SECRETKEYBYTES
SODIUM_CRYPTO_SIGN_KEYPAIRBYTES
SODIUM_CRYPTO_STREAM_NONCEBYTES
SODIUM_CRYPTO_STREAM_KEYBYTES
Zip
ZipArchive::EM_NONE
ZipArchive::EM_AES_128
ZipArchive::EM_AES_192
ZipArchive::EM_AES_256
Backward incompatible changes
Prevent number_format from returning negative zero
Previously, it was possible for the number_format
function to return -0. Whilst this is perfectly valid
according to the IEEE 754 floating point specification, this oddity was not
desirable for displaying formatted numbers in a human-readable form.
Convert numeric keys in object and array casts
Numeric keys are now better handled when casting arrays to objects and
objects to arrays (either from explicit casting or by
settype).
This means that integer (or stringy integer) keys from arrays being casted
to objects are now accessible:
And integer (or stringy integer) keys from objects being casted to arrays
are now accessible:
Disallow passing to get_class
Previously, passing to the get_class function
would output the name of the enclosing class. This behaviour has now been
removed, where an E_WARNING will be output instead. To
achieve the same behaviour as before, the argument should simply be omitted.
Warn when counting non-countable types
An E_WARNING will now be emitted when attempting to
count non-countable types (this includes the
sizeof alias function).
Move ext/hash from resources to objects
As part of the long-term migration away from resources, the Hash
extension has been updated to use objects instead of resources. The change should be
seamless for PHP developers, except for where
is_resource checks have been made (which will need
updating to is_object instead).
Improve SSL/TLS defaults
The following changes to the defaults have been made:
tls:// now defaults to TLSv1.0 or TLSv1.1 or TLSv1.2
ssl:// an alias of tls://
STREAM_CRYPTO_METHOD_TLS_* constants default to TLSv1.0
or TLSv1.1 + TLSv1.2, instead of TLSv1.0 only
gettype return value on closed resources
Previously, using gettype on a closed resource would
return a string of "unknown type". Now, a string of
"resource (closed)" will be returned.
is_object and __PHP_Incomplete_Class
Previously, using is_object on the
__PHP_Incomplete_Class class would return .
Now, will be returned.
Promote the error level of undefined constants
Unqualified references to undefined constants will now generate an
E_WARNING (instead of an E_NOTICE).
In the next major version of PHP, they will generate
Error exceptions.
Windows support
The officially supported, minimum Windows versions are now Windows 7/Server
2008 R2.
Checks on default property values of traits
Compatibility checks upon default trait property values will no longer
perform casting.
object for class names
The object name was previously soft-reserved in PHP 7.0.
This is now hard-reserved, prohibiting it from being used as a class, trait,
or interface name.
NetWare support
Support for NetWare has now been removed.
array_unique with SORT_STRING
While array_unique with SORT_STRING
formerly copied the array and removed non-unique elements (without packing
the array afterwards), now a new array is built by adding the
unique elements. This can result in different numeric indexes.
bcmod changes with floats
The bcmod function no longer truncates fractional
numbers to integers. As such, its behavior now follows
fmod, rather than the % operator.
For example bcmod('4', '3.5') now returns
0.5 instead of 1.
Hashing functions and non-cryptographic hashes
The hash_hmac, hash_hmac_file,
hash_pbkdf2, and hash_init (with
HASH_HMAC) functions no longer accept non-cryptographic
hashes.
json_decode function options
The json_decode function option,
JSON_OBJECT_AS_ARRAY, is now used if the second
parameter (assoc) is . Previously,
JSON_OBJECT_AS_ARRAY was always ignored.
rand and mt_rand output
Sequences generated by rand and
mt_rand for a specific seed may differ from PHP 7.1 on
64-bit machines (due to the fixing of a modulo bias bug in the
implementation).
Removal of sql.safe_mode ini setting
The sql.safe_mode ini setting has now been removed.
Changes to date_parse and date_parse_from_format
The zone element of the array returned by date_parse and
date_parse_from_format represents seconds instead of
minutes now, and its sign is inverted. For instance -120
is now 7200.
Incoming Cookies
As of PHP 7.2.34, the names of incoming cookies are no
longer url-decoded for security reasons.
Other changes
Moving of utf8_encode and utf8_decode
The utf8_encode and utf8_decode
functions have now been moved to the standard extension as string functions, whereas before
the XML extension was required for them to be available.
Changes to mail and mb_send_mail
The $additional_headers parameter of mail and
mb_send_mail now also accepts an array
instead of a string.
LMDB support
The DBA extension now has support for LMDB.
Changes to the PHP build system
Unix: Autoconf 2.64 or greater is now required to build PHP.
Unix: --with-pdo-oci configure argument no longer needs
the version number of the Oracle Instant Client.
Unix: --enable-gd-native-ttf configure argument has been
removed. This was not used since PHP 5.5.0.
Windows: --with-config-profile configure argument has been
added. This can be used to save specific configures, much like the magical
config.nice.bat file.
Changes to GD
imageantialias is now also available if compiled with
a system libgd.
imagegd stores truecolor images as real truecolor
images. Formerly, they have been converted to palette.
Moving MCrypt to PECL
The MCrypt extension has now been moved
out of the core to PECL. Given the mcrypt library has not seen any updates
since 2007, its usage is highly discouraged. Instead, either the
OpenSSL or Sodium
extension should be used.
session_module_name
Passing "user" to session_module_name
now raises an error of level E_RECOVERABLE_ERROR. Formerly,
this has been silently ignored.
New features
New object type
A new type, object, has been introduced that can be used for
(contravariant) parameter typing and (covariant) return typing of any
objects.
Extension loading by name
Shared extensions no longer require their file extension
(.so for Unix or .dll for Windows) to
be specified. This is enabled in the php.ini file, as well as in the
dl function.
Abstract method overriding
Abstract methods can now be overridden when an abstract class extends
another abstract class.
Sodium is now a core extension
The modern Sodium cryptography library has now become a core extension in PHP.
For a complete function reference, see the Sodium
chapter.
Password hashing with Argon2
Argon2 has been added to the password hashing API,
where the following constants have been exposed:
PASSWORD_ARGON2I
PASSWORD_ARGON2_DEFAULT_MEMORY_COST
PASSWORD_ARGON2_DEFAULT_TIME_COST
PASSWORD_ARGON2_DEFAULT_THREADS
Extended string types for PDO
PDO's string type has been extended to support the national character type
when emulating prepares. This has been done with the following constants:
PDO::PARAM_STR_NATL
PDO::PARAM_STR_CHAR
PDO::ATTR_DEFAULT_STR_PARAM
These constants are utilised by bitwise OR'ing them with
PDO::PARAM_STR:
Additional emulated prepares debugging information for PDO
The PDOStatement::debugDumpParams method has been
updated to include the SQL being sent to the DB, where the full, raw query
(including the replaced placeholders with their bounded values) will be
shown. This has been added to aid with debugging emulated prepares (and so
it will only be available when emulated prepares are turned on).
Support for extended operations in LDAP
Support for EXOP has been added to the LDAP extension. This has been done by
exposing the following functions and constants:
ldap_parse_exop
ldap_exop
ldap_exop_passwd
ldap_exop_whoami
LDAP_EXOP_START_TLS
LDAP_EXOP_MODIFY_PASSWD
LDAP_EXOP_REFRESH
LDAP_EXOP_WHO_AM_I
LDAP_EXOP_TURN
Address Information additions to the Sockets extension
The sockets extension now has the ability to lookup address information, as
well as connect to it, bind to it, and explain it. The following four
functions have been added for this:
socket_addrinfo_lookup
socket_addrinfo_connect
socket_addrinfo_bind
socket_addrinfo_explain
Parameter type widening
Parameter types from overridden methods and from interface implementations
may now be omitted. This is still in compliance with LSP, since parameters
types are contravariant.
Allow a trailing comma for grouped namespaces
A trailing comma can now be added to the group-use syntax introduced in
PHP 7.0.
proc_nice support on Windows
The proc_nice function is now supported on Windows.
pack and unpack endian support
The pack and unpack functions now
support float and double in both little and big endian.
Enhancements to the EXIF extension
The EXIF extension has been updated to support a much larger range of formats. This
means that their format specific tags are now properly translated when parsing images
with the exif_read_data function. The following new formats are
now supported:
Samsung
DJI
Panasonic
Sony
Pentax
Minolta
Sigma/Foveon
AGFA
Kyocera
Ricoh
Epson
The EXIF functions exif_read_data and exif_thumbnail
now support passing streams as their first argument.
New features in PCRE
The J modifier for setting PCRE_DUPNAMES has been added.
SQLite3 allows writing BLOBs
SQLite3::openBlob now allows to open BLOB fields in
write mode; formerly only read mode was supported.
Oracle OCI8 Transparent Application Failover Callbacks
Support for Oracle Database Transparent Application Failover (TAF) callbacks
has been added. TAF allows PHP OCI8 applications to
automatically reconnect to a preconfigured database when a connection
is broken. The new TAF callback support allows PHP applications to
monitor and control reconnection during failover.
Enhancements to the ZIP extension
Read and write support for encrypted archives has been added (requires libzip 1.2.0).
The ZipArchive class now implements the Countable
interface.
The zip:// stream now accepts a 'password' context option.
Deprecated features in PHP 7.2.x
Unquoted strings
Unquoted strings that are non-existent global constants are taken to be
strings of themselves. This behaviour used to emit an
E_NOTICE, but will now emit an
E_WARNING. In the next major version of PHP, an
Error exception will be thrown instead.
png2wbmp and jpeg2wbmp
The png2wbmp and jpeg2wbmp
functions from the GD extension have now been deprecated and will be removed
in the next major version of PHP.
INTL_IDNA_VARIANT_2003 variant
The Intl extension has deprecated the
INTL_IDNA_VARIANT_2003 variant, which is currently
being used as the default for idn_to_ascii and
idn_to_utf8. PHP 7.4 will see these defaults changed to
INTL_IDNA_VARIANT_UTS46, and the next major version of
PHP will remove INTL_IDNA_VARIANT_2003 altogether.
__autoload method
The __autoload method has been deprecated because it is
inferior to spl_autoload_register (due to it not being
able to chain autoloaders), and there is no interoperability between the two
autoloading styles.
track_errors ini setting and $php_errormsg variable
When the track_errors ini setting is enabled, a
$php_errormsg variable is created in the local scope when
a non-fatal error occurs. Given that the preferred way of retrieving such
error information is by using error_get_last, this
feature has been deprecated.
create_function function
Given the security issues of this function (being a thin wrapper around
eval), this dated function has now been deprecated.
The preferred alternative is to use anonymous functions.
mbstring.func_overload ini setting
Given the interoperability problems of string-based functions being used in
environments with this setting enabled, it has now been deprecated.
(unset) cast
Casting any expression to this type will always result in , and so
this superfluous casting type has now been deprecated.
parse_str without a second argument
Without the second argument to parse_str, the query
string parameters would populate the local symbol table.
Given the security implications of this, using
parse_str without a second argument has now been
deprecated. The function should always be used with two arguments, as the
second argument causes the query string to be parsed into an array.
gmp_random function
This function generates a random number based upon a range that is
calculated by an unexposed, platform-specific limb size. Because of this,
the function has now been deprecated. The preferred way of generating a
random number using the GMP extension is by
gmp_random_bits and
gmp_random_range.
each function
This function is far slower at iteration than a normal
foreach, and causes implementation issues for some
language changes. It has therefore been deprecated.
assert with a string argument
Using assert with a string argument required the string
to be eval'ed. Given the potential for remote code
execution, using assert with a string argument has now
been deprecated in favour of using boolean expressions.
$errcontext argument of error handlers
The $errcontext argument contains all local variables of
the error site. Given its rare usage, and the problems it causes with
internal optimisations, it has now been deprecated.
Instead, a debugger should be used to retrieve
information on local variables at the error site.
read_exif_data function
The read_exif_data alias has been deprecated.
The exif_read_data function should be used instead.
Windows Support
PHP Core
More POSIX Conforming File Deletion
File descriptors are opened in shared read/write/delete mode by default.
This effectively maps the POSIX semantics and allows to
delete files with handles in use. It is not 100% same, some platform
differences still persist. After the deletion, the filename entry is
blocked, until all the opened handles to it are closed.
New Functions
PHP Core
array_key_first
array_key_last
gc_status
hrtime
is_countable
net_get_interfaces
FastCGI Process Manager
fpm_get_status
Date and Time
DateTime::createFromImmutable
GNU Multiple Precision
gmp_binomial
gmp_kronecker
gmp_lcm
gmp_perfect_power
Internationalization Functions
Normalizer::getRawDecomposition
normalizer_get_raw_decomposition
Spoofchecker::setRestrictionLevel
Lightweight Directory Access Protocol
ldap_add_ext
ldap_bind_ext
ldap_delete_ext
ldap_exop_refresh
ldap_mod_add_ext
ldap_mod_replace_ext
ldap_mod_del_ext
ldap_rename_ext
OpenSSL
openssl_pkey_derive
Sockets
socket_wsaprotocol_info_export
socket_wsaprotocol_info_import
socket_wsaprotocol_info_release
New Global Constants
PHP Core
PASSWORD_ARGON2ID
Client URL Library
CURLAUTH_BEARER
CURLAUTH_GSSAPI
CURLE_WEIRD_SERVER_REPLY
CURLINFO_APPCONNECT_TIME_T
CURLINFO_CONNECT_TIME_T
CURLINFO_CONTENT_LENGTH_DOWNLOAD_T
CURLINFO_CONTENT_LENGTH_UPLOAD_T
CURLINFO_FILETIME_T
CURLINFO_HTTP_VERSION
CURLINFO_NAMELOOKUP_TIME_T
CURLINFO_PRETRANSFER_TIME_T
CURLINFO_PROTOCOL
CURLINFO_PROXY_SSL_VERIFYRESULT
CURLINFO_REDIRECT_TIME_T
CURLINFO_SCHEME
CURLINFO_SIZE_DOWNLOAD_T
CURLINFO_SIZE_UPLOAD_T
CURLINFO_SPEED_DOWNLOAD_T
CURLINFO_SPEED_UPLOAD_T
CURLINFO_STARTTRANSFER_TIME_T
CURLINFO_TOTAL_TIME_T
CURL_LOCK_DATA_CONNECT
CURL_LOCK_DATA_PSL
CURL_MAX_READ_SIZE
CURLOPT_ABSTRACT_UNIX_SOCKET
CURLOPT_DISALLOW_USERNAME_IN_URL
CURLOPT_DNS_SHUFFLE_ADDRESSES
CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS
CURLOPT_HAPROXYPROTOCOL
CURLOPT_KEEP_SENDING_ON_ERROR
CURLOPT_PRE_PROXY
CURLOPT_PROXY_CAINFO
CURLOPT_PROXY_CAPATH
CURLOPT_PROXY_CRLFILE
CURLOPT_PROXY_KEYPASSWD
CURLOPT_PROXY_PINNEDPUBLICKEY
CURLOPT_PROXY_SSLCERT
CURLOPT_PROXY_SSLCERTTYPE
CURLOPT_PROXY_SSL_CIPHER_LIST
CURLOPT_PROXY_SSLKEY
CURLOPT_PROXY_SSLKEYTYPE
CURLOPT_PROXY_SSL_OPTIONS
CURLOPT_PROXY_SSL_VERIFYHOST
CURLOPT_PROXY_SSL_VERIFYPEER
CURLOPT_PROXY_SSLVERSION
CURLOPT_PROXY_TLS13_CIPHERS
CURLOPT_PROXY_TLSAUTH_PASSWORD
CURLOPT_PROXY_TLSAUTH_TYPE
CURLOPT_PROXY_TLSAUTH_USERNAME
CURLOPT_REQUEST_TARGET
CURLOPT_SOCKS5_AUTH
CURLOPT_SSH_COMPRESSION
CURLOPT_SUPPRESS_CONNECT_HEADERS
CURLOPT_TIMEVALUE_LARGE
CURLOPT_TLS13_CIPHERS
CURLPROXY_HTTPS
CURLSSH_AUTH_GSSAPI
CURL_SSLVERSION_MAX_DEFAULT
CURL_SSLVERSION_MAX_NONE
CURL_SSLVERSION_MAX_TLSv1_0
CURL_SSLVERSION_MAX_TLSv1_1
CURL_SSLVERSION_MAX_TLSv1_2
CURL_SSLVERSION_MAX_TLSv1_3
CURL_SSLVERSION_TLSv1_3
CURL_VERSION_ALTSVC (as of PHP 7.3.6)
CURL_VERSION_ASYNCHDNS
CURL_VERSION_BROTLI
CURL_VERSION_CONV
CURL_VERSION_CURLDEBUG (as of PHP 7.3.6)
CURL_VERSION_DEBUG
CURL_VERSION_GSSAPI
CURL_VERSION_GSSNEGOTIATE
CURL_VERSION_HTTPS_PROXY
CURL_VERSION_IDN
CURL_VERSION_LARGEFILE
CURL_VERSION_MULTI_SSL
CURL_VERSION_NTLM
CURL_VERSION_NTLM_WB
CURL_VERSION_PSL (as of PHP 7.3.6)
CURL_VERSION_SPNEGO
CURL_VERSION_SSPI
CURL_VERSION_TLSAUTH_SRP
Data Filtering
FILTER_SANITIZE_ADD_SLASHES
JavaScript Object Notation
JSON_THROW_ON_ERROR
Lightweight Directory Access Protocol
LDAP_CONTROL_ASSERT
LDAP_CONTROL_MANAGEDSAIT
LDAP_CONTROL_PROXY_AUTHZ
LDAP_CONTROL_SUBENTRIES
LDAP_CONTROL_VALUESRETURNFILTER
LDAP_CONTROL_PRE_READ
LDAP_CONTROL_POST_READ
LDAP_CONTROL_SORTREQUEST
LDAP_CONTROL_SORTRESPONSE
LDAP_CONTROL_PAGEDRESULTS
LDAP_CONTROL_AUTHZID_REQUEST
LDAP_CONTROL_AUTHZID_RESPONSE
LDAP_CONTROL_SYNC
LDAP_CONTROL_SYNC_STATE
LDAP_CONTROL_SYNC_DONE
LDAP_CONTROL_DONTUSECOPY
LDAP_CONTROL_PASSWORDPOLICYREQUEST
LDAP_CONTROL_PASSWORDPOLICYRESPONSE
LDAP_CONTROL_X_INCREMENTAL_VALUES
LDAP_CONTROL_X_DOMAIN_SCOPE
LDAP_CONTROL_X_PERMISSIVE_MODIFY
LDAP_CONTROL_X_SEARCH_OPTIONS
LDAP_CONTROL_X_TREE_DELETE
LDAP_CONTROL_X_EXTENDED_DN
LDAP_CONTROL_VLVREQUEST
LDAP_CONTROL_VLVRESPONSE
Multibyte String
MB_CASE_FOLD
MB_CASE_LOWER_SIMPLE
MB_CASE_UPPER_SIMPLE
MB_CASE_TITLE_SIMPLE
MB_CASE_FOLD_SIMPLE
OpenSSL
STREAM_CRYPTO_PROTO_SSLv3
STREAM_CRYPTO_PROTO_TLSv1_0
STREAM_CRYPTO_PROTO_TLSv1_1
STREAM_CRYPTO_PROTO_TLSv1_2
PostgreSQL
PGSQL_DIAG_SCHEMA_NAME
PGSQL_DIAG_TABLE_NAME
PGSQL_DIAG_COLUMN_NAME
PGSQL_DIAG_DATATYPE_NAME
PGSQL_DIAG_CONSTRAINT_NAME
PGSQL_DIAG_SEVERITY_NONLOCALIZED
Backward Incompatible Changes
PHP Core
Heredoc/Nowdoc Ending Label Interpretation
Due to the introduction of flexible heredoc/nowdoc
syntax, doc strings that contain the ending label inside their body
may cause syntax errors or change in interpretation. For example in:
<?php
$str = <<<FOO
abcdefg
FOO
FOO;
?>
the indented occurrence of FOO did not previously have any
special meaning. Now it will be interpreted as the end of the heredoc string
and the following FOO; will cause a syntax error. This issue can
always be resolved by choosing an ending label that does not occur within the
contents of the string.
Continue Targeting Switch issues Warning
continue statements targeting switch
control flow structures will now generate a warning. In PHP such
continue statements are equivalent to
break, while they behave as continue 2
in other languages.
<?php
while ($foo) {
switch ($bar) {
case "baz":
continue;
// Warning: "continue" targeting switch is equivalent to
// "break". Did you mean to use "continue 2"?
}
}
?>
Strict Interpretation of Integer String Keys on ArrayAccess
Array accesses of type $obj["123"], where
$obj implements ArrayAccess and
"123" is an integer string literal will no
longer result in an implicit conversion to integer, i.e.,
$obj->offsetGet("123") will be called instead of
$obj->offsetGet(123). This matches existing behavior for
non-literals. The behavior of arrays is not affected in any way, they
continue to implicitly convert integral string keys to integers.
Static Properties no longer separated by Reference Assignment
In PHP, static properties are shared between inheriting classes, unless the
static property is explicitly overridden in a child class. However, due to an
implementation artifact it was possible to separate the static properties by
assigning a reference. This loophole has been fixed.
<?php
class Test {
public static $x = 0;
}
class Test2 extends Test { }
Test2::$x = &$x;
$x = 1;
var_dump(Test::$x, Test2::$x);
// Previously: int(0), int(1)
// Now: int(1), int(1)
?>
References returned by Array and Property Accesses are immediately unwrapped
References returned by array and property accesses are now unwrapped as part
of the access. This means that it is no longer possible to modify the
reference between the access and the use of the accessed value:
<?php
$arr = [1];
$ref =& $arr[0];
var_dump($arr[0] + ($arr[0] = 2));
// Previously: int(4), Now: int(3)
?>
This makes the behavior of references and non-references consistent. Please
note that reading and writing a value inside a single expression remains
undefined behavior and may change again in the future.
Argument Unpacking of Traversables with non-Integer Keys no longer supported
Argument unpacking stopped working with Traversables
with non-integer keys. The following code worked in PHP 5.6-7.2 by accident.
<?php
function foo(...$args) {
var_dump($args);
}
function gen() {
yield 1.23 => 123;
}
foo(...gen());
?>
Miscellaneous
The ext_skel utility has been completely redesigned with
new options and some old options removed. This is now written in PHP and has
no external dependencies.
Support for BeOS has been dropped.
Exceptions thrown due to automatic conversion of warnings into exceptions in
EH_THROW mode (e.g. some DateTime
exceptions) no longer populate error_get_last state. As
such, they now work the same way as manually thrown exceptions.
TypeError now reports wrong types as
int and bool instead of
integer and boolean, respectively.
Undefined variables passed to compact will now be
reported as a notice.
getimagesize and related functions now report the mime
type of BMP images as image/bmp instead of
image/x-ms-bmp, since the former has been registered with
the IANA (see RFC 7903).
stream_socket_get_name will now return IPv6 addresses
wrapped in brackets. For example "[::1]:1337" will be
returned instead of "::1:1337".
BCMath Arbitrary Precision Mathematics
All warnings thrown by BCMath functions are
now using PHP's error handling. Formerly some warnings have directly been
written to stderr.
bcmul and bcpow now return numbers
with the requested scale. Formerly, the returned numbers may have omitted
trailing decimal zeroes.
IMAP, POP3 and NNTP
rsh/ssh logins are disabled by default.
Use imap.enable_insecure_rsh if you
want to enable them. Note that the IMAP library does not filter mailbox names
before passing them to the rsh/ssh
command, thus passing untrusted data to this function with
rsh/ssh enabled is insecure.
Multibyte String
Due to added support for named captures, mb_ereg_*()
patterns using named captures will behave differently. In particular named
captures will be part of matches and mb_ereg_replace
will interpret additional syntax. See Named
Captures for more information.
MySQL Improved Extension
Prepared statements now properly report the fractional seconds for
DATETIME, TIME and
TIMESTAMP columns with decimals specifier (e.g.
TIMESTAMP(6) when using microseconds). Formerly, the
fractional seconds part was simply omitted from the returned values.
MySQL Functions (PDO_MYSQL)
Prepared statements now properly report the fractional seconds for
DATETIME, TIME and
TIMESTAMP columns with decimals specifier (e.g.
TIMESTAMP(6) when using microseconds). Formerly, the
fractional seconds part was simply omitted from the returned values. Please
note that this only affects the usage of PDO_MYSQL with emulated prepares turned off
(e.g. using the native preparation functionality). Statements using
connections having PDO::ATTR_EMULATE_PREPARES=
(which is the default) were not affected by the bug fixed and have already
been getting the proper fractional seconds values from the engine.
Reflection
Reflection export to string now uses
int and bool instead of
integer and boolean, respectively.
Standard PHP Library (SPL)
If an SPL autoloader throws an exception,
following autoloaders will not be executed. Previously all autoloaders were
executed and exceptions were chained.
SimpleXML
Mathematic operations involving SimpleXML objects will now treat the text as
an int or float, whichever is more appropriate.
Previously values were treated as ints unconditionally.
Incoming Cookies
As of PHP 7.3.23, the names of incoming cookies are no
longer url-decoded for security reasons.
Other Changes
PHP Core
Set(raw)cookie accepts $option Argument
setcookie and setrawcookie now also
support the following signature:
boolsetcookie
stringname
stringvalue""
arrayoptions[]
where $options is an associative array which may have
any of the keys "expires", "path",
"domain", "secure",
"httponly" and "samesite".
New Syslog ini Directives
The following ini Directives have been added to customize logging, if
error_log is set to
syslog:
syslog.facility
Specifies what type of program is logging the message.
syslog.filter
Specifies the filter type to filter the logged messages, with the
supported filter types - all,
no-ctrl and ascii.
Starting with PHP 7.3.8, raw is also available,
restoring the way syslog behaved in previous PHP versions.
This filter will also affect calls to syslog.
syslog.ident
Specifies the ident string which is prepended to every message.
Specifies what type of program is logging the message.
Specifies the filter type to filter the logged messages, with the
supported filter types - all,
no-ctrl and ascii.
Starting with PHP 7.3.8, raw is also available,
restoring the way syslog behaved in previous PHP versions.
This filter will also affect calls to syslog.
Specifies the ident string which is prepended to every message.
Garbage Collection
The cyclic GC has been
enhanced, which may result in considerable performance improvements.
Miscellaneous
var_export now exports stdClass
objects as an array cast to an object ((object) array( ... )), rather
than using the nonexistent method stdClass::__setState.
debug_zval_dump was changed to display recursive arrays
and objects in the same way as var_dump. Now, it doesn't
display them twice.
array_push and array_unshift can
now also be called with a single argument, which is particularly convenient
wrt. the spread operator.
Interactive PHP Debugger
The unused constants PHPDBG_FILE,
PHPDBG_METHOD, PHPDBG_LINENO and
PHPDBG_FUNC have been removed.
FastCGI Process Manager
The getallheaders function is now also available.
Client URL Library
libcurl ≥ 7.15.5 is now required.
Data Filtering
FILTER_VALIDATE_FLOAT now also supports a thousand
option, which defines the set of allowed thousand separator chars. The default
("',.") is fully backward compatible with former PHP versions.
FILTER_SANITIZE_ADD_SLASHES has been added as an alias of the
magic_quotes filter (FILTER_SANITIZE_MAGIC_QUOTES).
The magic_quotes filter is subject to removal in future versions of PHP.
FTP
The default transfer mode has been changed to binary.
Internationalization Functions
Normalizer::NONE is deprecated, when PHP is linked with
ICU ≥ 56.
Introduced Normalizer::FORM_KC_CF as
Normalizer::normalize argument for
NFKC_Casefold normalization; available when linked with
ICU ≥ 56.
JavaScript Object Notation
A new flag has been added, JSON_THROW_ON_ERROR, which
can be used with json_decode or
json_encode and causes these functions to throw the new
JsonException upon an error, instead of setting the
global error state that is retrieved with
json_last_error and json_last_error_msg.
JSON_PARTIAL_OUTPUT_ON_ERROR takes precedence over
JSON_THROW_ON_ERROR.
Multibyte String
The configuration option --with-libmbfl is
no longer available.
ODBC (Unified)
Support for ODBCRouter and Birdstep
including the birdstep.max_links ini directive has been
removed.
OPcache
The opcache.inherited_hack ini directive has been removed.
The value has already been ignored since PHP 5.3.0.
OpenSSL
The min_proto_version and max_proto_version
ssl stream options as well as related constants for possible TLS protocol values
have been added.
Regular Expressions (Perl-Compatible)
The PCRE extension has been upgraded to
PCRE2, which may cause minor behavioral changes (for instance, character
ranges in classes are now more strictly interpreted), and augments the
existing regular expression syntax.
preg_quote now also escapes the '#'
character.
Microsoft SQL Server and Sybase Functions (PDO_DBLIB)
The attribute PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS to enable automatic
skipping of empty rowsets has been added.
The PDO::DBLIB_ATTR_TDS_VERSION attribute which exposes
the TDS version has been added.
DATETIME2 columns are now treated like DATETIME columns.
SQLite Functions (PDO_SQLITE)
SQLite3 databases can now be opened in read-only mode by setting the
new PDO::SQLITE_ATTR_OPEN_FLAGS attribute to
PDO::SQLITE_OPEN_READONLY.
Session Handling
session_set_cookie_params now also supports the
following signature:
boolsession_set_cookie_params
arrayoptions
where $options is an associative array which may have
any of the keys "lifetime", "path",
"domain", "secure",
"httponly" and "samesite". Accordingly,
the return value of session_get_cookie_params now also
has an element with the key "samesite".
Furthermore, the new session.cookie_samesite ini option to
set the default of the SameSite directive for cookies has been added. It
defaults to "" (empty string), so no SameSite directive is
set. Can be set to "Lax" or "Strict",
which sets the respective SameSite directive.
Tidy
Building against tidyp is now also
supported transparently. Since tidyp offers no API to get the release date,
tidy_get_release and tidy::getRelease
return 'unknown' in this case.
XML Parser
The return value of the xml_set_external_entity_ref_handler
callback is no longer ignored if the extension has been built against libxml.
Formerly, the return value has been ignored, and parsing did never stop.
Zip
Building against the bundled libzip is discouraged, but still possible by
adding --without-libzip to the configuration.
Zlib Compression
The zlib/level context option for the compress.zlib wrapper to facilitate
setting the desired compression level has been added.
New Features
PHP Core
More Flexible Heredoc and Nowdoc Syntax
The closing marker for doc strings is no longer required to be followed by a
semicolon or newline. Additionally the closing marker may be indented, in
which case the indentation will be stripped from all lines in the doc string.
Array Destructuring supports Reference Assignments
Array destructuring now supports reference assignments using the syntax
[&$a, [$b, &$c]] = $d. The same is also supported
for list.
Instanceof Operator accepts Literals
instanceof now allows literals as the first operand, in
which case the result is always .
CompileError Exception instead of some Compilation Errors
A new CompileError exception has been added, from
which ParseError inherits. A small number of
compilation errors will now throw a CompileError
instead of generating a fatal error. Currently this only affects compilation
errors that may be thrown by token_get_all in
TOKEN_PARSE mode, but more errors may be converted in
the future.
Trailing Commas are allowed in Calls
Trailing commas in function and method calls are now allowed.
Argon2id Support
The --with-password-argon2[=dir] configure
argument now provides support for both Argon2i and Argon2id hashes in the
password_hash, password_verify,
password_get_info, and
password_needs_rehash functions. Passwords may be hashed
and verified using the PASSWORD_ARGON2ID constant.
Support for both Argon2i and Argon2id in the password_*
functions now requires PHP be linked against libargon2 reference library ≥
20161029.
FastCGI Process Manager
New options have been added to customize the FPM logging:
log_limit
This global option can be used for setting the log limit for the logged
line which allows to log messages longer than 1024 characters without
wrapping. It also fixes various wrapping issues.
log_buffering
This global option allows an experimental logging without extra buffering.
decorate_workers_output
This pool option allows to disable the output decoration for workers
output when catch_workers_output is enabled.
This global option can be used for setting the log limit for the logged
line which allows to log messages longer than 1024 characters without
wrapping. It also fixes various wrapping issues.
This global option allows an experimental logging without extra buffering.
This pool option allows to disable the output decoration for workers
output when catch_workers_output is enabled.
BC Math Functions
bcscale can now also be used as getter to retrieve the
current scale in use.
Lightweight Directory Access Protocol
Full support for LDAP Controls has been added to the LDAP querying functions and
ldap_parse_result:
A $controls parameter to send controls to the
server in ldap_add,
ldap_mod_replace, ldap_mod_add,
ldap_mod_del, ldap_rename,
ldap_compare, ldap_delete,
ldap_modify_batch,
ldap_search, ldap_list and
ldap_read has been added.
The out parameter $controls to get controls from the server in
ldap_parse_result has been added.
Support for LDAP_OPT_SERVER_CONTROLS and
LDAP_OPT_CLIENT_CONTROLS in
ldap_get_option and
ldap_set_option has been fixed.
A $controls parameter to send controls to the
server in ldap_add,
ldap_mod_replace, ldap_mod_add,
ldap_mod_del, ldap_rename,
ldap_compare, ldap_delete,
ldap_modify_batch,
ldap_search, ldap_list and
ldap_read has been added.
The out parameter $controls to get controls from the server in
ldap_parse_result has been added.
Support for LDAP_OPT_SERVER_CONTROLS and
LDAP_OPT_CLIENT_CONTROLS in
ldap_get_option and
ldap_set_option has been fixed.
Multibyte String Functions
Full Case-Mapping and Case-Folding Support
Support for full case-mapping and case-folding has been added. Unlike simple
case-mapping, full case-mapping may change the length of the string. For
example:
<?php
mb_strtoupper("Straße");
// Produces STRAßE on PHP 7.2
// Produces STRASSE on PHP 7.3
?>
The different casing mapping and folding modes are available through
mb_convert_case:
MB_CASE_LOWER (used by mb_strtolower)
MB_CASE_UPPER (used by mb_strtoupper)
MB_CASE_TITLE
MB_CASE_FOLD
MB_CASE_LOWER_SIMPLE
MB_CASE_UPPER_SIMPLE
MB_CASE_TITLE_SIMPLE
MB_CASE_FOLD_SIMPLE (used by case-insensitive operations)
Only unconditional, language agnostic full case-mapping is performed.
MB_CASE_LOWER (used by mb_strtolower)
MB_CASE_UPPER (used by mb_strtoupper)
MB_CASE_TITLE
MB_CASE_FOLD
MB_CASE_LOWER_SIMPLE
MB_CASE_UPPER_SIMPLE
MB_CASE_TITLE_SIMPLE
MB_CASE_FOLD_SIMPLE (used by case-insensitive operations)
Case-Insensitive String Operations use Case-Folding
Case-insensitive string operations now use case-folding instead of case-
mapping during comparisons. This means that more characters will be
considered (case insensitively) equal now.
MB_CASE_TITLE performs Title-Case Conversion
mb_convert_case with MB_CASE_TITLE
now performs title-case conversion based on the Cased and CaseIgnorable
derived Unicode properties. In particular this also improves handling of
quotes and apostrophes.
Unicode 11 Support
The Multibyte String data tables have
been updated for Unicode 11.
Long String Support
The Multibyte String Functions now
correctly support strings larger than 2GB.
Performance Improvements
Performance of the Multibyte String
extension has been significantly improved across the board. The largest
improvements are in case conversion functions.
Named Captures Support
The mb_ereg_* functions now support named captures.
Matching functions like mb_ereg will now return named
captures both using their group number and their name, similar to PCRE:
<?php
mb_ereg('(?<word>\w+)', '国', $matches);
// => [0 => "国", 1 => "国", "word" => "国"];
?>
Additionally, mb_ereg_replace now supports the
\k and \k'' notations to reference named
captures in the replacement string:
<?php
mb_ereg_replace('\s*(?<word>\w+)\s*', "_\k<word>_\k'word'_", ' foo ');
// => "_foo_foo_"
?>
\k and \k'' can also be used for numbered
references, which also works with group numbers greater than 9.
Readline
Support for the completion_append_character and
completion_suppress_append options has been added to
readline_info. These options are only available if PHP
is linked against libreadline (rather than libedit).
Deprecated Features
PHP Core
Case-Insensitive Constants
The declaration of case-insensitive constants has been deprecated. Passing
as the third argument to define will now generate a
deprecation warning. The use of case-insensitive constants with a case that
differs from the declaration is also deprecated.
Namespaced assert()
Declaring a function called assert() inside a namespace is
deprecated. The assert function is subject to special
handling by the engine, which may lead to inconsistent behavior when defining
a namespaced function with the same name.
Searching Strings for non-string Needle
Passing a non-string needle to string search functions is deprecated. In the
future the needle will be interpreted as a string instead of an ASCII
codepoint. Depending on the intended behavior, you should either explicitly
cast the needle to string or perform an explicit call to
chr. The following functions are affected:
strpos
strrpos
stripos
strripos
strstr
strchr
strrchr
stristr
strpos
strrpos
stripos
strripos
strstr
strchr
strrchr
stristr
Strip-Tags Streaming
The fgetss function and the string.strip_tags stream filter have been
deprecated. This also affects the
SplFileObject::fgetss
method and gzgetss function.
Data Filtering
The explicit usage of the constants
FILTER_FLAG_SCHEME_REQUIRED and
FILTER_FLAG_HOST_REQUIRED is now deprecated; both are
implied for FILTER_VALIDATE_URL anyway.
Image Processing and GD
image2wbmp has been deprecated.
Internationalization Functions
Usage of the Normalizer::NONE form throws a deprecation
warning, if PHP is linked with ICU ≥ 56.
Multibyte String
The following undocumented mbereg_*() aliases have been
deprecated. Use the corresponding mb_ereg_*() variants
instead.
mbregex_encoding
mbereg
mberegi
mbereg_replace
mberegi_replace
mbsplit
mbereg_match
mbereg_search
mbereg_search_pos
mbereg_search_regs
mbereg_search_init
mbereg_search_getregs
mbereg_search_getpos
mbereg_search_setpos
mbregex_encoding
mbereg
mberegi
mbereg_replace
mberegi_replace
mbsplit
mbereg_match
mbereg_search
mbereg_search_pos
mbereg_search_regs
mbereg_search_init
mbereg_search_getregs
mbereg_search_getpos
mbereg_search_setpos
ODBC and DB2 Functions (PDO_ODBC)
The pdo_odbc.db2_instance_name
ini setting has been formally deprecated. It is deprecated in the
documentation as of PHP 5.1.1.
Windows Support
configure flags
configure now regards additional CFLAGS and LDFLAGS set as environment
variables.
CTRL handling
CTRL
C
and
CTRL
BREAK
on console can be caught by setting a handler function
with sapi_windows_set_ctrl_handler.
proc_open on Windows can be passed a
"create_process_group" option. It is required if the child
process is supposed to handle CTRL events.
OPcache
OPcache now supports an arbitrary number of separate caches per user via the
INI directive opcache.cache_id.
All processes with the same cache ID and user share an OPcache instance.
stat
The stat implementation has been refactored.
An inode number is delivered and is based on the NTFS file index.
The device number is now based on the volume serial number.
Note that both values are derived from the system and provided as-is on 64-bit
systems. On 32-bit systems, these values might overflow the 32-bit integer in
PHP, so they're fake.
libsqlite3
libsqlite3 is no longer compiled statically into php_sqlite3.dll
and php_pdo_sqlite.dll, but rather available as libsqlite3.dll.
Refer to the installation instructions for SQLite3 and
PDO_SQLITE, respectively.
New Classes and Interfaces
Reflection
ReflectionReference
New Functions
PHP Core
get_mangled_object_vars
password_algos
sapi_windows_set_ctrl_handler
GD
imagecreatefromtga
Multibyte String
mb_str_split
OpenSSL
openssl_x509_verify
Process Control
pcntl_unshare
SQLite3
SQLite3::backup
SQLite3Stmt::getSQL
Removed Extensions
These extensions have been moved to PECL and are no longer part of the PHP
distribution. The PECL package versions of these extensions will be created
according to user demand.
Firebird/Interbase
- access to an InterBase and/or Firebird based database is still
available with the PDO Firebird driver.
Recode
WDDX
New Global Constants
PHP Core
PHP_WINDOWS_EVENT_CTRL_C
PHP_WINDOWS_EVENT_CTRL_BREAK
Multibyte String
MB_ONIGURUMA_VERSION
Sockets
Added the following FreeBSD-specific socket options:
SO_LABEL
SO_PEERLABEL
SO_LISTENQLIMIT
SO_LISTENQLEN
SO_USER_COOKIE
Tidy
TIDY_TAG_ARTICLE
TIDY_TAG_ASIDE
TIDY_TAG_AUDIO
TIDY_TAG_BDI
TIDY_TAG_CANVAS
TIDY_TAG_COMMAND
TIDY_TAG_DATALIST
TIDY_TAG_DETAILS
TIDY_TAG_DIALOG
TIDY_TAG_FIGCAPTION
TIDY_TAG_FIGURE
TIDY_TAG_FOOTER
TIDY_TAG_HEADER
TIDY_TAG_HGROUP
TIDY_TAG_MAIN
TIDY_TAG_MARK
TIDY_TAG_MENUITEM
TIDY_TAG_METER
TIDY_TAG_NAV
TIDY_TAG_OUTPUT
TIDY_TAG_PROGRESS
TIDY_TAG_SECTION
TIDY_TAG_SOURCE
TIDY_TAG_SUMMARY
TIDY_TAG_TEMPLATE
TIDY_TAG_TIME
TIDY_TAG_TRACK
TIDY_TAG_VIDEO
Backward Incompatible Changes
PHP Core
Array-style access of non-arrays
Trying to use values of type null, bool,
int, float or resource as an
array (such as $null["key"]) will now generate a notice.
get_declared_classes function
The get_declared_classes function no longer
returns anonymous classes that have not been instantiated yet.
fn keyword
fn is now a reserved keyword. In particular,
it can no longer be used as a function or class name.
It can still be used as a method or class constant name.
<?php tag at end of file
<?php at the end of the file (without trailing newline)
will now be interpreted as an opening PHP tag. Previously it was interpreted
either as a short opening tag followed by literal php and
resulted in a syntax error (with short_open_tag=1)
or was interpreted as a literal <?php string
(with short_open_tag=0).
Stream wrappers
When using include/require on a stream,
streamWrapper::stream_set_option
will be invoked with the STREAM_OPTION_READ_BUFFER option.
Custom stream wrapper implementations may need to implement the
streamWrapper::stream_set_option method to
avoid a warning (always returning is a sufficient implementation).
Serialization
The o serialization format has been removed.
As it is never produced by PHP, this may only break unserialization of
manually crafted strings.
Password algorithm constants
Password hashing algorithm identifiers are now nullable strings rather
than integers.
PASSWORD_DEFAULT was int 1; now is string '2y' (in PHP 7.4.0, 7.4.1, and 7.4.2 it was )
PASSWORD_BCRYPT was int 1; now is string '2y'
PASSWORD_ARGON2I was int 2; now is string 'argon2i'
PASSWORD_ARGON2ID was int 3; now is string 'argon2id'
Applications correctly using the constants PASSWORD_DEFAULT,
PASSWORD_BCRYPT, PASSWORD_ARGON2I, and PASSWORD_ARGON2ID will continue to
function correctly.
htmlentities function
htmlentities will now raise a notice
(instead of a strict standards warning) if it is used with
an encoding for which only basic entity substitution is supported,
in which case it is equivalent to htmlspecialchars.
fread and fwrite function
fread and fwrite will now
return if the operation failed.
Previously an empty string or 0 was returned.
EAGAIN/EWOULDBLOCK are not considered failures.
These functions now also raise a notice on failure,
such as when trying to write to a read-only file resource.
BCMath Arbitrary Precision Mathematics
BCMath functions will now warn if a non well-formed number is passed, such
as "32foo". The argument will be interpreted as zero, as before.
CURL
Attempting to serialize a CURLFile class will now
generate an exception. Previously the exception was only thrown on unserialization.
Using CURLPIPE_HTTP1 is deprecated, and is no longer
supported as of cURL 7.62.0.
The $version parameter of curl_version
is deprecated. If any value not equal to the default CURLVERSION_NOW
is passed, a warning is raised and the parameter is ignored.
Date and Time
Calling var_dump or similar on a
DateTime or DateTimeImmutable
instance will no longer leave behind accessible properties on the object.
Comparison of DateInterval objects
(using ==, , and so on) will now generate
a warning and always return . Previously all DateInterval
objects were considered equal, unless they had properties.
Intl
The default parameter value of idn_to_ascii and
idn_to_utf8 is now INTL_IDNA_VARIANT_UTS46
instead of the deprecated INTL_IDNA_VARIANT_2003.
MySQLi
The embedded server functionality has been removed. It was broken since
at least PHP 7.0.
The undocumented mysqli::$stat property has been removed
in favor of mysqli::stat.
OpenSSL
The openssl_random_pseudo_bytes function will now
throw an exception in error situations, similar to random_bytes.
In particular, an Error is thrown if the number of
requested bytes is less than or equal to zero, and an Exception
is thrown if sufficient randomness cannot be gathered.
The $crypto_strong output argument is guaranteed to always
be if the function does not throw, so explicitly checking it is not necessary.
Regular Expressions (Perl-Compatible)
When PREG_UNMATCHED_AS_NULL mode is used, trailing
unmatched capturing groups will now also be set to (or
[null, -1] if offset capture is enabled).
This means that the size of the $matches will always be the same.
PHP Data Objects
Attempting to serialize a PDO or
PDOStatement instance will now generate
an Exception rather than a PDOException,
consistent with other internal classes which do not support serialization.
Reflection
Reflection objects will now generate an exception if an attempt is made
to serialize them. Serialization for reflection objects was never
supported and resulted in corrupted reflection objects. It has been
explicitly prohibited now.
The values of the class constant of ReflectionClassConstant,
ReflectionMethod and ReflectionProperty
have changed.
Standard PHP Library (SPL)
Calling get_object_vars on an ArrayObject
instance will now always return the properties of the ArrayObject
itself (or a subclass). Previously it returned the values of the wrapped
array/object unless the ArrayObject::STD_PROP_LIST
flag was specified.
Other affected operations are:
ReflectionObject::getProperties
reset, current, etc.
Use Iterator methods instead.
Potentially others working on object properties as a list,
e.g. array_walk.
(array) casts are not affected. They will continue to
return either the wrapped array, or the ArrayObject
properties, depending on whether the ArrayObject::STD_PROP_LIST
flag is used.
SplPriorityQueue::setExtractFlags will throw
an exception if zero is passed. Previously this would generate a recoverable
fatal error on the next extraction operation.
ArrayObject, ArrayIterator,
SplDoublyLinkedList and SplObjectStorage
now support the __serialize() and __unserialize()
mechanism in addition to the Serializable interface.
This means that serialization payloads created on older PHP versions can still be
unserialized, but new payloads created by PHP 7.4 will not be understood by older versions.
Tokenizer
token_get_all will now emit a
T_BAD_CHARACTER token for unexpected
characters instead of leaving behind holes in the token stream.
Incoming Cookies
As of PHP 7.4.11, the names of incoming cookies are no
longer url-decoded for security reasons.
Other Changes
Performance Improvements
PHP Core
A specialized VM opcode for the array_key_exists
function has been added, which improves performance of this function
if it can be statically resolved. In namespaced code, this may require
writing \array_key_exists() or explicitly importing
the function.
Regular Expressions (Perl-Compatible)
When preg_match in UTF-8 mode ("u" modifier)
is repeatedly called on the same string (but possibly different offsets),
it will only be checked for UTF-8 validity once.
Changes to INI File Handling
zend.exception_ignore_args is a new INI directive
for including or excluding arguments from stack traces generated
from exceptions.
opcache.preload_user is a new INI directive
for specifying the user account under which preloading
code is execute if it would otherwise be run as root (which is not
allowed for security reasons).
Migration to pkg-config
A number of extensions have been migrated to exclusively use pkg-config for the
detection of library dependencies. Generally, this means that instead of using
--with-foo-dir=DIR or similar only
--with-foo is used. Custom library paths can be
specified either by adding additional directories to PKG_CONFIG_PATH
or by explicitly specifying compilation options through FOO_CFLAGS
and FOO_LIBS.
The following extensions and SAPIs are affected:
CURL:
--with-curl no longer accepts a directory.
Enchant:
--with-enchant no longer accepts a directory.
FPM:
--with-fpm-systemd now uses only pkg-config
for libsystem checks. The libsystemd minimum required version is 209.
GD:
--with-gd becomes
--enable-gd
(whether to enable the extension at all) and
--with-external-gd
(to opt into using an external libgd, rather than the bundled one).
--with-png-dir has been removed. libpng is required.
--with-zlib-dir has been removed. zlib is required.
--with-freetype-dir
becomes --with-freetype
--with-jpeg-dir becomes
--with-jpeg
--with-webp-dir becomes
--with-webp
--with-xpm-dir becomes
--with-xpm
IMAP:
--with-kerberos-systemd no longer accepts a directory.
Intl:
--with-icu-dir has been removed.
If --enable-intl is passed,
then libicu is always required.
LDAP:
--with-ldap-sasl no longer accepts a directory.
Libxml:
--with-libxml-dir has been removed.
--enable-libxml becomes
--with-libxml.
--with-libexpat-dir has been renamed to
--with-expat and no longer accepts a directory.
Litespeed:
--with-litespeed becomes
--enable-litespeed.
Mbstring:
--with-onig has been removed.
Unless --disable-mbregex
has been passed, libonig is required.
ODBC:
--with-iodbc no longer accepts a directory.
--with-unixODBC without a directory now uses
pkg-config (preferred). Directory is still accepted for old versions without libodbc.pc.
OpenSSL:
--with-openssl no longer accepts a directory.
PCRE:
--with-pcre-regex has been removed.
Instead --with-external-pcre
is provided to opt into using an external PCRE library, rather
than the bundled one.
PDO_SQLite:
--with-pdo-sqlite no longer accepts a directory.
Readline:
--with-libedit no longer accepts a directory.
Sodium:
--with-sodium no longer accepts a directory.
SQLite3:
--with-sqlite3 no longer accepts a directory.
XSL:
--with-xsl no longer accepts a directory.
Zip:
--with-libzip has been removed.
--enable-zip becomes
--with-zip.
CSV escaping
fputcsv,
fgetcsv,
SplFileObject::fputcsv,
SplFileObject::fgetcsv, and
SplFileObject::setCsvControl
now accept an empty string as $escape argument,
which disables the proprietary PHP escaping mechanism.
The behavior of str_getcsv has been
adjusted accordingly (formerly, an empty string was identical
to using the default).
SplFileObject::getCsvControl now may also
return an empty string for the third array element, accordingly.
Data Filtering
The filter extension no longer exposes
--with-pcre-dir for Unix builds and can now reliably
be built as shared when using ./configure
GD
The behavior of imagecropauto in the bundled
libgd has been synced with that of system libgd:
IMG_CROP_DEFAULT is no longer falling
back to IMG_CROP_SIDES
Threshold-cropping now uses the algorithm of system libgd
The default $mode parameter of
imagecropauto has been changed to
IMG_CROP_DEFAULT; passing -1
is now deprecated.
imagescale now supports aspect ratio preserving
scaling to a fixed height by passing -1
as $new_width.
HASH Message Digest Framework
The hash extension cannot be disabled
anymore and is always an integral part of any PHP build, similar to
the date extension.
Intl
The intl extension
now requires at least ICU 50.1.
ResourceBundle now implements
Countable.
Lightweight Directory Access Protocol
Support for nsldap and umich_ldap has been removed.
Libxml
All libxml-based extensions now require libxml 2.7.6 or newer.
Multibyte String
The oniguruma library is no longer bundled with PHP, instead libonig needs
to be available on the system. Alternatively
--disable-mbregex can be used to disable
the mbregex component.
OPcache
The --disable-opcache-file and
--enable-opcache-file configure options
have been removed in favor of the
opcache.file_cache INI directive.
Password Hashing
The password_hash and
password_needs_rehash functions
now accept nullable and for $algo argument.
PEAR
Installation of PEAR (including PECL) is no longer enabled by default. It
can be explicitly enabled using --with-pear.
This option is deprecated and may be removed in the future.
Reflection
The numeric values of the modifier constants
(IS_ABSTRACT,
IS_DEPRECATED,
IS_EXPLICIT_ABSTRACT,
IS_FINAL,
IS_IMPLICIT_ABSTRACT,
IS_PRIVATE,
IS_PROTECTED,
IS_PUBLIC, and
IS_STATIC) on the
ReflectionClass,
ReflectionFunction,
ReflectionMethod,
ReflectionObject, and
ReflectionProperty
classes have changed.
SimpleXML
SimpleXMLElement now implements
Countable.
SQLite3
The bundled libsqlite has been removed. To build the
SQLite3 extension a
system libsqlite3 ≥ 3.7.4 is now required. To build the
PDO_SQLite extension
a system libsqlite3 ≥ 3.5.0 is now required.
Serialization and unserialization of SQLite3,
SQLite3Stmt and SQLite3Result
is now explicitly forbidden. Formerly, serialization of instances of
these classes was possible, but unserialization yielded unusable objects.
The @param notation can now also be used to
denote SQL query parameters.
Zip
The bundled libzip library has been removed.
A system libzip >= 0.11 is now necessary to build the
zip extension.
New Features
PHP Core
Typed properties
Class properties now support type declarations.
<?php
class User {
public int $id;
public string $name;
}
?>
The above example will enforce that $user->id can only be
assigned int values and $user->name can
only be assigned string values.
Arrow functions
Arrow functions provide a
shorthand syntax for defining functions
with implicit by-value scope binding.
<?php
$factor = 10;
$nums = array_map(fn($n) => $n * $factor, [1, 2, 3, 4]);
// $nums = array(10, 20, 30, 40);
?>
Limited return type covariance and argument type contravariance
The following code will now work:
<?php
class A {}
class B extends A {}
class Producer {
public function method(): A {}
}
class ChildProducer extends Producer {
public function method(): B {}
}
?>
Full variance support is only available if autoloading is used. Inside a
single file only non-cyclic type references are possible, because all
classes need to be available before they are referenced.
<?php
/**
* These classes satisfy the LSP requirements, because C is a subtype of A.
* However, at the time class B is declared, class C is not yet available
*/
class A
{
public function method(): A {}
}
class B extends A
{
// Fatal error: Could not check compatibility between B::method():C and
// A::method(): A, because class С is not available
public function method(): С {}
}
class C extends B {}
?>
Null coalescing assignment operator
<?php
$array['key'] ??= computeDefault();
// is roughly equivalent to
if (!isset($array['key'])) {
$array['key'] = computeDefault();
}
?>
Unpacking inside arrays
<?php
$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];
?>
Numeric literal separator
Numeric literals can contain underscores between digits.
<?php
6.674_083e-11; // float
299_792_458; // decimal
0xCAFE_F00D; // hexadecimal
0b0101_1111; // binary
?>
Weak references
Weak references allow the programmer to retain a reference to an object
that does not prevent the object from being destroyed.
Allow exceptions from __toString()
Throwing exceptions from __toString()
is now permitted. Previously this resulted in a fatal error. Existing
recoverable fatal errors in string conversions have been converted to
Error exceptions.
CURL
CURLFile now supports stream wrappers in addition
to plain file names, if the extension has been built against libcurl >= 7.56.0.
Filter
The FILTER_VALIDATE_FLOAT filter now supports the
min_range and max_range
options, with the same semantics as FILTER_VALIDATE_INT.
FFI
FFI is a new extension, which provides a simple way to call
native functions, access native variables, and create/access
data structures defined in C libraries.
GD
Added the IMG_FILTER_SCATTER image filter
to apply a scatter filter to images.
Hash
Added crc32c hash using Castagnoli's polynomial.
This CRC32 variant is used by storage systems, such as
iSCSI, SCTP, Btrfs and ext4.
Multibyte String
Added the mb_str_split function, which provides
the same functionality as str_split, but operating
on code points rather than bytes.
OPcache
Support for preloading code has been added.
Regular Expressions (Perl-Compatible)
The preg_replace_callback and preg_replace_callback_array
functions now accept an additional flags argument, with support for the
PREG_OFFSET_CAPTURE and PREG_UNMATCHED_AS_NULL flags.
This influences the format of the matches array passed to the callback function.
PDO
The username and password can now be specified as part of the PDO DSN for
the mysql, mssql, sybase, dblib, firebird and oci drivers. Previously this
was only supported by the pgsql driver. If a username/password is specified
both in the constructor and the DSN, the constructor takes precedence.
It is now possible to escape question marks in SQL queries to avoid them
being interpreted as parameter placeholders. Writing ??
allows sending a single question mark to the database and e.g. use the
PostgreSQL JSON key exists (?) operator.
PDO_OCI
PDOStatement::getColumnMeta is now available.
PDO_SQLite
PDOStatement::getAttribute(PDO::SQLITE_ATTR_READONLY_STATEMENT)
allows checking whether the statement is read-only, i.e. if it doesn't modify
the database.
PDO::setAttribute(PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES, true)
enables the use of SQLite3 extended result codes in PDO::errorInfo
and PDOStatement::errorInfo.
SQLite3
Added SQLite3::lastExtendedErrorCode
to fetch the last extended result code.
Added SQLite3::enableExtendedResultCodes($enable = true),
which will make SQLite3::lastErrorCode
return extended result codes.
Standard
strip_tags() with array of tag names
strip_tags now also accepts an array of allowed tags:
instead of strip_tags($str, '<a><p>')
you can now write strip_tags($str, ['a', 'p']).
Custom object serialization
A new mechanism for custom object serialization has been added, which
uses two new magic methods: __serialize
and __unserialize.
<?php
// Returns array containing all the necessary state of the object.
public function __serialize(): array
{
}
// Restores the object state from the given data array.
public function __unserialize(array $data): void
{
}
?>
The new serialization mechanism supersedes the
Serializable interface,
which will be deprecated in the future.
Array merge functions without arguments
array_merge and array_merge_recursive
may now be called without any arguments, in which case they will return an empty array.
This is useful in conjunction with the spread operator, e.g. array_merge(...$arrays).
proc_open function
proc_open now accepts an array instead of a
string for the command. In this case the process will be opened
directly (without going through a shell) and PHP will take care of
any necessary argument escaping.
<?php
proc_open(['php', '-r', 'echo "Hello World\n";'], $descriptors, $pipes);
?>
proc_open now supports
redirect and null descriptors.
<?php
// Like 2>&1 on the shell
proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['redirect', 1]], $pipes);
// Like 2>/dev/null or 2>nul on the shell
proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['null']], $pipes);
?>
argon2i(d) without libargon
password_hash now has the argon2i and argon2id implementations
from the sodium extension when PHP is built without libargon.
Deprecated Features
PHP Core
Nested ternary operators without explicit parentheses
Nested ternary operations must explicitly use parentheses
to dictate the order of the operations. Previously, when used
without parentheses, the left-associativity would not result
in the expected behaviour in most cases.
<?php
1 ? 2 : 3 ? 4 : 5; // deprecated
(1 ? 2 : 3) ? 4 : 5; // ok
1 ? 2 : (3 ? 4 : 5); // ok
?>
Parentheses are not required when nesting into the middle operand,
as this is always unambiguous and not affected by associativity:
1 ? 2 ? 3 : 4 : 5 // ok
Array and string offset access using curly braces
The array and string offset access syntax using curly braces is
deprecated. Use $var[$idx] instead of
$var{$idx}.
(real) cast and is_real function
The (real) cast is deprecated,
use (float) instead.
The is_real function is also deprecated,
use is_float instead.
Unbinding $this when $this is used
Unbinding $this of a non-static closure
that uses $this is deprecated.
parent keyword without parent class
Using parent inside a class without a parent
is deprecated, and will throw a compile-time error in the future.
Currently an error will only be generated if/when the parent is
accessed at run-time.
allow_url_include INI option
The allow_url_include
ini directive is deprecated. Enabling it will generate
a deprecation notice at startup.
Invalid characters in base conversion functions
Passing invalid characters to base_convert,
bindec, octdec and
hexdec will now generate a deprecation notice.
The result will still be computed as if the invalid characters did not exist.
Leading and trailing whitespace, as well as prefixes of type 0x (depending on base)
continue to be allowed.
Using array_key_exists on objects
Using array_key_exists on objects is deprecated.
Instead either isset or property_exists
should be used.
Magic quotes functions
The get_magic_quotes_gpc and get_magic_quotes_runtime
functions are deprecated. They always return .
hebrevc function
The hebrevc function is deprecated.
It can be replaced with nl2br(hebrev($str)) or,
preferably, the use of Unicode RTL support.
convert_cyr_string function
The convert_cyr_string function is deprecated.
It can be replaced by one of mb_convert_string,
iconv or UConverter.
money_format function
The money_format function is deprecated.
It can be replaced by the intl NumberFormatter functionality.
ezmlm_hash function
The ezmlm_hash function is deprecated.
restore_include_path function
The restore_include_path function is deprecated.
It can be replaced by ini_restore('include_path').
Implode with historical parameter order
Passing parameters to implode in reverse order
is deprecated, use implode($glue, $parts)
instead of implode($parts, $glue).
COM
Importing type libraries with case-insensitive constant
registering has been deprecated.
Filter
FILTER_SANITIZE_MAGIC_QUOTES is deprecated,
use FILTER_SANITIZE_ADD_SLASHES instead.
Multibyte String
Passing a non-string pattern to mb_ereg_replace
is deprecated. Currently, non-string patterns are interpreted as
ASCII codepoints. In PHP 8, the pattern will be interpreted as a
string instead.
Passing the encoding as 3rd parameter to mb_strrpos
is deprecated. Instead pass a 0 offset, and encoding as 4th parameter.
Lightweight Directory Access Protocol
ldap_control_paged_result_response and
ldap_control_paged_result are deprecated.
Pagination controls can be sent along with
ldap_search instead.
Reflection
Calls to ReflectionType::__toString now generate
a deprecation notice. This method has been deprecated in favor of
ReflectionNamedType::getName in the documentation
since PHP 7.1, but did not throw a deprecation notice for technical reasons.
The export() methods on all Reflection
classes are deprecated. Construct a Reflection object and
convert it to string instead:
<?php
// ReflectionClass::export(Foo::class, false) is:
echo new ReflectionClass(Foo::class), "\n";
// $str = ReflectionClass::export(Foo::class, true) is:
$str = (string) new ReflectionClass(Foo::class);
?>
Socket
The AI_IDN_ALLOW_UNASSIGNED and
AI_IDN_USE_STD3_ASCII_RULES flags for
socket_addrinfo_lookup are deprecated,
due to an upstream deprecation in glibc.
New Classes and Interfaces
cURL
CurlHandle
CurlMultiHandle
CurlShareHandle
Enchant
EnchantBroker
EnchantDictionary
GD
GdImage
OpenSSL
OpenSSLAsymmetricKey
OpenSSLCertificate
OpenSSLCertificateSigningRequest
Shmop
Shmop
Sockets
AddressInfo
Socket
Systen V
SysvMessageQueue
SysvSemaphore
SysvSharedMemory
XML Parser
XMLParser
XMLWriter
XMLWriter
Zlib
DeflateContext
InflateContext
Backward Incompatible Changes
PHP Core
String to Number Comparison
Non-strict comparisons between numbers and non-numeric strings now work by casting the number to
string and comparing the strings. Comparisons between numbers and numeric strings continue to
work as before. Notably, this means that 0 == "not-a-number" is considered false
now.
Comparison
Before
After
0 == "0"
0 == "0.0"
0 == "foo"
0 == ""
42 == " 42"
42 == "42foo"
Other incompatible Changes
match is now a reserved keyword.
mixed is now a reserved word, so it cannot be used to name a class, interface or trait, and is also prohibited from being used in namespaces.
Assertion failures now throw by default. If the old behavior is desired,
assert.exception=0 can be set in the INI settings.
Methods with the same name as the class are no longer interpreted as constructors. The
__construct() method should be used instead.
The ability to call non-static methods statically has been removed. Thus
is_callable will fail when checking for a non-static method with a classname
(must check with an object instance).
The (real) and (unset) casts have been removed.
The track_errors ini directive has been removed. This
means that php_errormsg is no longer available. The
error_get_last function may be used instead.
The ability to define case-insensitive constants has been removed. The third argument to
define may no longer be .
The ability to specify an autoloader using an __autoload function has been
removed. spl_autoload_register should be used instead.
The errcontext argument will no longer be passed to custom error handlers
set with set_error_handler.
create_function has been removed. Anonymous functions may be used instead.
each has been removed. or ArrayIterator
should be used instead.
The ability to unbind this from closures that were created from a method,
using Closure::fromCallable or
ReflectionMethod::getClosure, has been removed.
The ability to unbind this from proper closures that contain uses of
this has also been removed.
The ability to use array_key_exists with objects has been removed.
isset or property_exists may be used instead.
The behavior of array_key_exists regarding the type of the
key parameter has been made consistent with isset and
normal array access. All key types now use the usual coercions and array/object keys throw a
TypeError.
Any array that has a number n as its first numeric key will use
n+1 for its next implicit key, even if n is
negative.
The default error_reporting level is now E_ALL. Previously it excluded
E_NOTICE and E_DEPRECATED.
display_startup_errors is now enabled by
default.
Using parent inside a class that has no parent will now result in a fatal
compile-time error.
The @ operator will no longer silence fatal errors
(E_ERROR, E_CORE_ERROR,
E_COMPILE_ERROR, E_USER_ERROR,
E_RECOVERABLE_ERROR, E_PARSE). Error handlers that
expect error_reporting to be 0 when @ is used, should be
adjusted to use a mask check instead:
<?php
// Replace
function my_error_handler($err_no, $err_msg, $filename, $linenum) {
if (error_reporting() == 0) {
return false;
}
// ...
}
// With
function my_error_handler($err_no, $err_msg, $filename, $linenum) {
if (!(error_reporting() & $err_no)) {
return false;
}
// ...
}
?>
Additionally, care should be taken that error messages are not displayed in production
environments, which can result in information leaks. Please ensure that
display_errors=Off is used in conjunction with error logging.
#[ is no longer interpreted as the start of a comment,
as this syntax is now used for attributes.
Inheritance errors due to incompatible method signatures (LSP violations) will now always
generate a fatal error. Previously a warning was generated in some cases.
The precedence of the concatenation operator has changed relative to bitshifts and addition as
well as subtraction.
<?php
echo "Sum: " . $a + $b;
// was previously interpreted as:
echo ("Sum: " . $a) + $b;
// is now interpreted as:
echo "Sum:" . ($a + $b);
?>
Arguments with a default value that resolves to at runtime will no longer implicitly mark
the argument type as nullable. Either an explicit nullable type, or an explicit default
value has to be used instead.
<?php
// Replace
function test(int $arg = CONST_RESOLVING_TO_NULL) {}
// With
function test(?int $arg = CONST_RESOLVING_TO_NULL) {}
// Or
function test(int $arg = null) {}
?>
A number of warnings have been converted into Error exceptions:
Attempting to write to a property of a non-object. Previously this
implicitly created an stdClass object for null, false and empty strings.
Attempting to append an element to an array for which the PHP_INT_MAX key
is already used.
Attempting to use an invalid type (array or object) as an array key or
string offset.
Attempting to write to an array index of a scalar value.
Attempting to unpack a non-array/Traversable.
Attempting to access unqualified constants which are undefined.
Previously, unqualified constant accesses resulted in a warning and were interpreted as strings.
Passing the wrong number of arguments to a non-variadic built-in
function will throw an ArgumentCountError.
Passing invalid countable types to count will throw
a TypeError.
A number of notices have been converted into warnings:
Attempting to read an undefined variable.
Attempting to read an undefined property.
Attempting to read an undefined array key.
Attempting to read a property of a non-object.
Attempting to access an array index of a non-array.
Attempting to convert an array to string.
Attempting to use a resource as an array key.
Attempting to use null, a boolean, or a float as a string offset.
Attempting to read an out-of-bounds string offset.
Attempting to assign an empty string to a string offset.
Attempting to assign multiple bytes to a string offset will now emit a warning.
Unexpected characters in source files (such as NUL bytes outside of strings) will now result in a
ParseError exception instead of a compile warning.
Uncaught exceptions now go through "clean shutdown", which means that destructors will be called
after an uncaught exception.
The compile time fatal error "Only variables can be passed by reference" has been delayed until
runtime, and converted into an "Argument cannot be passed by reference"
Error exception.
Some "Only variables should be passed by reference" notices have been converted to "Argument
cannot be passed by reference" exception.
The generated name for anonymous classes has changed. It will now include the name of the first
parent or interface:
<?php
new class extends ParentClass {};
// -> ParentClass@anonymous
new class implements FirstInterface, SecondInterface {};
// -> FirstInterface@anonymous
new class {};
// -> class@anonymous
?>
The name shown above is still followed by a NUL byte and a unique suffix.
Non-absolute trait method references in trait alias adaptations are now required to be
unambiguous:
<?php
class X {
use T1, T2 {
func as otherFunc;
}
function func() {}
}
?>
If both T1::func() and T2::func() exist, this code was previously
silently accepted, and func was assumed to refer to T1::func. Now it will generate a
fatal error instead, and either T1::func or T2::func needs to be
written explicitly.
The signature of abstract methods defined in traits is now checked against the implementing class
method:
<?php
trait MyTrait {
abstract private function neededByTrait(): string;
}
class MyClass {
use MyTrait;
// Error, because of return type mismatch.
private function neededByTrait(): int { return 42; }
}
?>
Disabled functions are now treated exactly like non-existent functions. Calling a disabled
function will report it as unknown, and redefining a disabled function is now possible.
data:// stream wrappers are no longer writable, which matches the documented
behavior.
The arithmetic and bitwise operators +, -,
*, /, **, %,
, , ,
|, ^, ~, ++,
-- will now consistently throw a TypeError when one of
the operands is an , or non-overloaded . The only exception to this is
the array + array merge operation, which remains supported.
Float to string casting will now always behave locale-independently.
<?php
setlocale(LC_ALL, "de_DE");
$f = 3.14;
echo $f, "\n";
// Previously: 3,14
// Now: 3.14
?>
See printf, number_format and
NumberFormatter for ways to customize number formatting.
Support for deprecated curly braces for offset access has been removed.
<?php
// Instead of:
$array{0};
$array{"key"};
// Write:
$array[0];
$array["key"];
?>
Applying the final modifier on a private method will now produce a warning unless that method is
the constructor.
If an object constructor exits, the object destructor will no longer be
called. This matches the behavior when the constructor throws.
Namespaced names can no longer contain whitespace: While Foo\Bar will be recognized
as a namespaced name, Foo \ Bar will not. Conversely, reserved keywords are now
permitted as namespace segments, which may also change the interpretation of code:
new\x is now the same as constant('new\x'), not
new \x().
Nested ternaries now require explicit parentheses.
debug_backtrace and Exception::getTrace will no
longer provide references to arguments. It will not be possible to change function arguments
through the backtrace.
Numeric string handling has been altered to be more intuitive and less error-prone. Trailing
whitespace is now allowed in numeric strings for consistency with how leading whitespace is
treated. This mostly affects:
The is_numeric function
String-to-string comparisons
Type declarations
Increment and decrement operations
The concept of a "leading-numeric string" has been mostly dropped; the cases where this remains
exist in order to ease migration. Strings which emitted an E_NOTICE "A non
well-formed numeric value encountered" will now emit an E_WARNING "A
non-numeric value encountered" and all strings which emitted an E_WARNING "A
non-numeric value encountered" will now throw a
TypeError. This mostly affects:
Arithmetic operations
Bitwise operations
This E_WARNING to TypeError change also affects the
E_WARNING "Illegal string offset 'string'" for illegal string offsets. The
behavior of explicit casts to int/float from strings has not been changed.
Magic Methods will now have their arguments and return types checked if they have them declared.
The signatures should match the following list:
__call(string $name, array $arguments): mixed
__callStatic(string $name, array $arguments): mixed
__clone(): void
__debugInfo(): ?array
__get(string $name): mixed
__invoke(mixed $arguments): mixed
__isset(string $name): bool
__serialize(): array
__set(string $name, mixed $value): void
__set_state(array $properties): object
__sleep(): array
__unserialize(array $data): void
__unset(string $name): void
__wakeup(): void
call_user_func_array array keys will now be interpreted as parameter names,
instead of being silently ignored.
Declaring a function called assert() inside a namespace is
no longer allowed, and issues E_COMPILE_ERROR.
The assert function is subject to special handling by the engine,
which may lead to inconsistent behavior when defining a namespaced function with the same name.
Resource to Object Migration
Several s have been migrated to s.
Return value checks using is_resource should be replaced with checks for .
curl_init will now return a CurlHandle object rather
than a . The curl_close function no longer has an effect,
instead the CurlHandle instance is automatically destroyed if it is no
longer referenced.
curl_multi_init will now return a CurlMultiHandle
object rather than a . The curl_multi_close function no
longer has an effect, instead the CurlMultiHandle instance is
automatically destroyed if it is no longer referenced.
curl_share_init will now return a CurlShareHandle
object rather than a . The curl_share_close function no
longer has an effect, instead the CurlShareHandle instance is
automatically destroyed if it is no longer referenced.
enchant_broker_init will now return an EnchantBroker
object rather than a .
enchant_broker_request_dict and
enchant_broker_request_pwl_dict will now return an
EnchantDictionary object rather than a .
The GD extension now uses GdImage objects as the underlying data structure
for images, rather than s.
The imagedestroy function no longer has an effect; instead the
GdImage instance is automatically destroyed if it is no longer referenced.
openssl_x509_read and openssl_csr_sign will now return
an OpenSSLCertificate object rather than a .
The openssl_x509_free function is deprecated and no longer has an effect,
instead the OpenSSLCertificate instance is automatically destroyed if it
is no longer referenced.
openssl_csr_new will now return an
OpenSSLCertificateSigningRequest object rather than a .
openssl_pkey_new will now return an
OpenSSLAsymmetricKey object rather than a .
The openssl_pkey_free function is deprecated and no longer has an effect,
instead the OpenSSLAsymmetricKey instance is automatically destroyed if it
is no longer referenced.
shmop_open will now return a Shmop object rather than
a . The shmop_close function no longer has an effect, and is
deprecated; instead the Shmop instance is automatically destroyed if it is
no longer referenced.
socket_create, socket_create_listen,
socket_accept, socket_import_stream,
socket_addrinfo_connect, socket_addrinfo_bind, and
socket_wsaprotocol_info_import will now return a
Socket object rather than a .
socket_addrinfo_lookup will now return an array of
AddressInfo objects rather than s.
msg_get_queue will now return an SysvMessageQueue
object rather than a .
sem_get will now return an SysvSemaphore object
rather than a .
shm_attach will now return an SysvSharedMemory object
rather than a .
xml_parser_create and xml_parser_create_ns will now
return an XMLParser object rather than a . The
xml_parser_free function no longer has an effect, instead the XMLParser
instance is automatically destroyed if it is no longer referenced.
The XMLWriter functions now accept and return, respectively,
XMLWriter objects instead of s.
inflate_init will now return an InflateContext object
rather than a .
deflate_init will now return a DeflateContext object
rather than a .
COM and .Net (Windows)
The ability to import case-insensitive constants from type libraries has been removed.
The second argument to com_load_typelib may no longer be false;
com.autoregister_casesensitive
may no longer be disabled; case-insensitive markers in
com.typelib_file are ignored.
CURL
CURLOPT_POSTFIELDS no longer accepts objects as arrays. To
interpret an object as an array, perform an explicit (array) cast. The
same applies to other options accepting arrays as well.
Date and Time
mktime and gmmktime now require at least one
argument. time can be used to get the current timestamp.
DOM
Unimplemented classes from the DOM extension that had no behavior and contained test
data have been removed. These classes have also been removed in the latest version of
the DOM standard:
DOMNameList
DomImplementationList
DOMConfiguration
DomError
DomErrorHandler
DOMImplementationSource
DOMLocator
DOMUserDataHandler
DOMTypeInfo
DOMStringExtend
Unimplemented methods from the DOM extension that had no behavior have been removed:
DOMNamedNodeMap::setNamedItem
DOMNamedNodeMap::removeNamedItem
DOMNamedNodeMap::setNamedItemNS
DOMNamedNodeMap::removeNamedItemNS
DOMText::replaceWholeText
DOMNode::compareDocumentPosition
DOMNode::isEqualNode
DOMNode::getFeature
DOMNode::setUserData
DOMNode::getUserData
DOMDocument::renameNode
Enchant
enchant_broker_list_dicts, enchant_broker_describe and
enchant_dict_suggest will now return an empty array instead of .
Exif
read_exif_data has been removed; exif_read_data
should be used instead.
Filter
The FILTER_FLAG_SCHEME_REQUIRED and
FILTER_FLAG_HOST_REQUIRED flags for the
FILTER_VALIDATE_URL filter have been removed. The scheme
and host are (and have been) always required.
The INPUT_REQUEST and INPUT_SESSION source for
filter_input etc. have been removed. These were never implemented and their
use always generated a warning.
GD
The deprecated function image2wbmp has been removed.
The deprecated functions png2wbmp and jpeg2wbmp have
been removed.
The default mode parameter of imagecropauto no longer
accepts -1. IMG_CROP_DEFAULT should be used instead.
On Windows, php_gd2.dll has been renamed to php_gd.dll.
GMP
gmp_random has been removed. One of gmp_random_range or
gmp_random_bits should be used instead.
Iconv
iconv implementations which do not properly set errno in case of errors are no
longer supported.
IMAP
The unused default_host argument of imap_headerinfo
has been removed.
The imap_header function which is an alias of
imap_headerinfo has been removed.
Internationalization Functions
The deprecated constant INTL_IDNA_VARIANT_2003 has been removed.
The deprecated Normalizer::NONE constant has been removed.
LDAP
The deprecated functions ldap_sort,
ldap_control_paged_result and
ldap_control_paged_result_response have been removed.
The interface of ldap_set_rebind_proc has changed; the
callback parameter does not accept empty strings anymore; should be
used instead.
MBString
The mbstring.func_overload directive has been
removed. The related MB_OVERLOAD_MAIL,
MB_OVERLOAD_STRING, and MB_OVERLOAD_REGEX constants
have also been removed. Finally, the "func_overload" and
"func_overload_list" entries in mb_get_info have been
removed.
mb_parse_str can no longer be used without specifying a result array.
A number of deprecated mbregex aliases have been removed. See the following
list for which functions should be used instead:
mbregex_encoding → mb_regex_encoding
mbereg → mb_ereg
mberegi → mb_eregi
mbereg_replace → mb_ereg_replace
mberegi_replace → mb_eregi_replace
mbsplit → mb_split
mbereg_match → mb_ereg_match
mbereg_search → mb_ereg_search
mbereg_search_pos → mb_ereg_search_pos
mbereg_search_regs → mb_ereg_search_regs
mbereg_search_init → mb_ereg_search_init
mbereg_search_getregs → mb_ereg_search_getregs
mbereg_search_getpos → mb_ereg_search_getpos
mbereg_search_setpos → mb_ereg_search_setpos
The e modifier for mb_ereg_replace has been removed.
mb_ereg_replace_callback should be used instead.
A non-string pattern argument to mb_ereg_replace will now be interpreted as
a string instead of an ASCII codepoint. The previous behavior may be restored with an explicit
call to chr.
The needle argument for mb_strpos,
mb_strrpos, mb_stripos,
mb_strripos, mb_strstr,
mb_stristr, mb_strrchr and
mb_strrichr can now be empty.
The is_hex parameter, which was not used internally, has been removed from
mb_decode_numericentity.
The legacy behavior of passing the encoding as the third argument instead of an offset for the
mb_strrpos function has been removed; an explicit 0
offset with the encoding should be provided as the fourth argument instead.
The ISO_8859-* character encoding aliases have been replaced by
ISO8859-* aliases for better interoperability with the iconv extension. The
mbregex ISO 8859 aliases with underscores (ISO_8859_* and
ISO8859_*) have also been removed.
mb_ereg and mb_eregi will now return boolean on
a successful match. Previously they returned integer 1 if
matches was not passed, or max(1, strlen($matches[0])) if
matches was passed.
OCI8
The OCI-Lob class is now called OCILob, and the
OCI-Collection class is now called OCICollection
for name compliance enforced by PHP 8 arginfo type annotation tooling.
Several alias functions have been marked as deprecated.
oci_internal_debug and its alias ociinternaldebug have
been removed.
ODBC
odbc_connect no longer reuses connections.
The unused flags parameter of odbc_exec has been
removed.
OpenSSL
openssl_seal and openssl_open now require
method to be passed, as the previous default of "RC4"
is considered insecure.
Regular Expressions (Perl-Compatible)
When passing invalid escape sequences they are no longer interpreted as literals. This behavior
previously required the X modifier which is now ignored.
PHP Data Objects
The default error handling mode has been changed from "silent" to "exceptions". See
Errors and error handling for details.
The signatures of some PDO methods have changed:
PDO::query(string $query, ?int $fetchMode = null, mixed ...$fetchModeArgs)
PDOStatement::setFetchMode(int $mode, mixed ...$args)
PDO ODBC
The directive
pdo_odbc.db2_instance_name has been
removed.
PDO MySQL
PDO::inTransaction now reports the actual transaction state of
the connection, rather than an approximation maintained by PDO. If a query that is
subject to "implicit commit" is executed, PDO::inTransaction
will subsequently return , as a transaction is no longer active.
PostgreSQL
The deprecated pg_connect syntax using multiple parameters instead of a
connection string is no longer supported.
The deprecated pg_lo_import and pg_lo_export signature
that passes the connection as the last argument is no longer supported. The connection should be
passed as first argument instead.
pg_fetch_all will now return an empty array instead of for result
sets with zero rows.
Phar
Metadata associated with a phar will no longer be automatically unserialized, to fix potential
security vulnerabilities due to object instantiation, autoloading, etc.
Reflection
The method signatures
ReflectionClass::newInstance($args)
ReflectionFunction::invoke($args)
ReflectionMethod::invoke($object, $args)
have been changed to:
ReflectionClass::newInstance(...$args)
ReflectionFunction::invoke(...$args)
ReflectionMethod::invoke($object, ...$args)
Code that must be compatible with both PHP 7 and PHP 8 can use the following
signatures to be compatible with both versions:
ReflectionClass::newInstance($arg = null, ...$args)
ReflectionFunction::invoke($arg = null, ...$args)
ReflectionMethod::invoke($object, $arg = null, ...$args)
The ReflectionType::__toString method will now return a complete debug
representation of the type, and is no longer deprecated. In particular the result will include a
nullability indicator for nullable types. The format of the return value is not stable and may
change between PHP versions.
Reflection export() methods have been removed.
Instead reflection objects can be cast to string.
ReflectionMethod::isConstructor and
ReflectionMethod::isDestructor now also return for
__construct() and
__destruct() methods of interfaces.
Previously, this would only be true for methods of classes and traits.
ReflectionType::isBuiltin method has been moved to
ReflectionNamedType. ReflectionUnionType does not
have it.
Sockets
The deprecated AI_IDN_ALLOW_UNASSIGNED and
AI_IDN_USE_STD3_ASCII_RULES flags for
socket_addrinfo_lookup have been removed.
Standard PHP Library (SPL)
SplFileObject::fgetss has been removed.
SplFileObject::seek now always seeks to the beginning of the line.
Previously, positions =1 sought to the beginning of the next line.
SplHeap::compare now specifies a method signature. Inheriting classes
implementing this method will now have to use a compatible method signature.
SplDoublyLinkedList::push,
SplDoublyLinkedList::unshift and
SplQueue::enqueue now return void instead of .
spl_autoload_register will now always throw a
TypeError on invalid arguments, therefore the second argument
do_throw is ignored and a notice will be emitted if it is set to .
SplFixedArray is now an IteratorAggregate
and not an Iterator.
SplFixedArray::rewind, SplFixedArray::current,
SplFixedArray::key, SplFixedArray::next, and
SplFixedArray::valid have been removed. In their place,
SplFixedArray::getIterator has been added. Any code which uses explicit
iteration over SplFixedArray must now obtain an
Iterator through
SplFixedArray::getIterator. This means that
SplFixedArray is now safe to use in nested loops.
Standard Library
assert will no longer evaluate string arguments, instead they will be
treated like any other argument. assert($a == $b) should be used instead of
assert('$a == $b'). The assert.quiet_eval ini directive and the
ASSERT_QUIET_EVAL constant have also been removed, as they would no longer
have any effect.
parse_str can no longer be used without specifying a result array.
The string.strip_tags filter has been removed.
The needle argument of strpos,
strrpos, stripos, strripos,
strstr, strchr, strrchr, and
stristr will now always be interpreted as a string. Previously non-string
needles were interpreted as an ASCII code point. An explicit call to chr can
be used to restore the previous behavior.
The needle argument for strpos,
strrpos, stripos, strripos,
strstr, stristr and strrchr can
now be empty.
The length argument for substr,
substr_count, substr_compare, and
iconv_substr can now be . values will behave as if no length
argument was provided and will therefore return the remainder of the string instead of an empty
string.
The length argument for array_splice can now be
. values will behave identically to omitting the argument, thus removing everything
from the offset to the end of the array.
The args argument of vsprintf,
vfprintf, and vprintf must now be an array. Previously
any type was accepted.
The 'salt' option of password_hash is no longer
supported. If the 'salt' option is used a warning is generated, the provided
salt is ignored, and a generated salt is used instead.
The quotemeta function will now return an empty string if an empty string
was passed. Previously was returned.
The following functions have been removed:
hebrevc
convert_cyr_string
money_format
ezmlm_hash
restore_include_path
get_magic_quotes_gpc
get_magic_quotes_runtime
fgetss
FILTER_SANITIZE_MAGIC_QUOTES has been removed.
Calling implode with parameters in a reverse order ($pieces,
$glue) is no longer supported.
parse_url will now distinguish absent and empty queries and fragments:
http://example.com/foo → query = null, fragment = null
http://example.com/foo? → query = "", fragment = null
http://example.com/foo# → query = null, fragment = ""
http://example.com/foo?# → query = "", fragment = ""
Previously all cases resulted in query and fragment being .
var_dump and debug_zval_dump will now print
floating-point numbers using serialize_precision
rather than precision. In a default configuration, this
means that floating-point numbers are now printed with full accuracy by these debugging
functions.
If the array returned by __sleep() contains non-existing
properties, these are now silently ignored. Previously, such properties would have been
serialized as if they had the value .
The default locale on startup is now always "C". No locales are inherited from
the environment by default. Previously, LC_ALL was set to
"C", while LC_CTYPE was inherited from the environment.
However, some functions did not respect the inherited locale without an explicit
setlocale call. An explicit setlocale call is now
always required if a locale component should be changed from the default.
The deprecated DES fallback in crypt has been removed. If an unknown salt
format is passed to crypt, the function will fail with *0
instead of falling back to a weak DES hash now.
Specifying out of range rounds for SHA256/SHA512 crypt will now fail with
*0 instead of clamping to the closest limit. This matches glibc behavior.
The result of sorting functions may have changed, if the array contains elements that compare as
equal.
Any functions accepting callbacks that are not explicitly specified to accept parameters by
reference will now warn if a callback with reference parameters is used. Examples include
array_filter and array_reduce. This was already the
case for most, but not all, functions previously.
The HTTP stream wrapper as used by functions like file_get_contents
now advertises HTTP/1.1 rather than HTTP/1.0 by default. This does not change the behavior of the
client, but may cause servers to respond differently. To retain the old behavior, set the
'protocol_version' stream context option, e.g.
<?php
$ctx = stream_context_create(['http' => ['protocol_version' => '1.0']]);
echo file_get_contents('http://example.org', false, $ctx);
?>
Calling crypt without an explicit salt is no longer supported. If you would
like to produce a strong hash with an auto-generated salt, use
password_hash instead.
substr, mb_substr, iconv_substr and
grapheme_substr now consistently clamp out-of-bounds offsets to the string
boundary. Previously, was returned instead of the empty string in some cases.
On Windows, the program execution functions (proc_open, exec,
popen etc.) using the shell, now consistently execute %comspec% /s
/c "$commandline", which has the same effect as executing
$commandline (without additional quotes).
Sysvsem
The auto_release parameter of sem_get was changed to
accept bool values rather than int.
Tidy
The use_include_path parameter, which was not used internally, has been
removed from tidy_repair_string.
tidy::repairString and tidy::repairFile became
static methods.
Tokenizer
T_COMMENT tokens will no longer include a trailing newline. The newline will
instead be part of a following T_WHITESPACE token. It should be noted that
T_COMMENT is not always followed by whitespace, it may also be followed by
T_CLOSE_TAG or end-of-file.
Namespaced names are now represented using the T_NAME_QUALIFIED
(Foo\Bar), T_NAME_FULLY_QUALIFIED (\Foo\Bar) and
T_NAME_RELATIVE (namespace\Foo\Bar) tokens.
T_NS_SEPARATOR is only used for standalone namespace separators, and only
syntactially valid in conjunction with group use declarations.
XMLReader
XMLReader::open and XMLReader::XML are now
static methods. They can still be called as instance methods, but inheriting classes need to declare them
as static if they override these methods.
XML-RPC
The XML-RPC extension has been moved to PECL and is no longer part of the PHP
distribution.
Zip
ZipArchive::OPSYS_Z_CPM has been removed (this name was a typo). Use
ZipArchive::OPSYS_CPM instead.
Zlib
gzgetss has been removed.
zlib.output_compression is no longer
automatically disabled for Content-Type: image/*.
Windows PHP Test Packs
The test runner has been renamed from run-test.php to
run-tests.php, to match its name in php-src.
Other Changes
Changes in SAPI Modules
Apache2Handler
The PHP module has been renamed from php7_module to
php_module.
Changed Functions
Reflection
ReflectionClass::getConstants and
ReflectionClass::getReflectionConstants results can be now filtered via
a new parameter filter. Three new constants were added to be used with it:
ReflectionClassConstant::IS_PUBLIC
ReflectionClassConstant::IS_PROTECTED
ReflectionClassConstant::IS_PRIVATE
Standard
The math functions abs, ceil,
floor and round now properly heed
the strict_types directive.
Previously, they coerced the first argument even in strict type mode.
Zip
The ZipArchive::addGlob and
ZipArchive::addPattern methods accept more values in the
options array argument:
flags
comp_method
comp_flags
env_method
enc_password
ZipArchive::addEmptyDir, ZipArchive::addFile
and ZipArchive::addFromString
methods have a new flags argument. This allows managing name encoding
(ZipArchive::FL_ENC_*) and entry replacement
(ZipArchive::FL_OVERWRITE).
ZipArchive::extractTo now restores the file modification time.
Other Changes to Extensions
CURL
The CURL extension now requires at least libcurl 7.29.0.
The deprecated parameter version of curl_version has
been removed.
Date and Time
DatePeriod now implements IteratorAggregate
(instead of Traversable).
DOM
DOMNamedNodeMap and DOMNodeList now implement
IteratorAggregate (instead of
Traversable).
Intl
IntlBreakIterator and ResourceBundle now implement
IteratorAggregate (instead of Traversable).
Enchant
The enchant extension now uses libenchant-2 by default when available. libenchant version 1 is
still supported but is deprecated and could be removed in the future.
GD
The num_points parameter of imagepolygon,
imageopenpolygon and imagefilledpolygon is now
optional, i.e. these functions may be called with either 3 or 4 arguments. If the argument is
omitted, it is calculated as count($points)/2.
The function imagegetinterpolation to get the current interpolation method
has been added.
JSON
The JSON extension cannot be disabled anymore and is always an integral part of any PHP build,
similar to the date extension.
MBString
The Unicode data tables have been updated to version 13.0.0.
PDO
PDOStatement now implements
IteratorAggregate (instead of
Traversable).
LibXML
The minimum required libxml version is now 2.9.0. This means that external entity loading is now
guaranteed to be disabled by default, and no extra steps need to be taken to protect against XXE
attacks.
MySQLi / PDO MySQL
When mysqlnd is not used (which is the default and recommended option), the minimum supported
libmysqlclient version is now 5.5.
mysqli_result now implements
IteratorAggregate (instead of
Traversable).
PGSQL / PDO PGSQL
The PGSQL and PDO PGSQL extensions now require at least libpq 9.1.
Readline
Calling readline_completion_function before the interactive prompt starts
(e.g. in auto_prepend_file) will now override the
default interactive prompt completion function. Previously,
readline_completion_function only worked when called after starting the
interactive prompt.
SimpleXML
SimpleXMLElement now implements
RecursiveIterator and absorbed the functionality of
SimpleXMLIterator. SimpleXMLIterator is an empty
extension of SimpleXMLElement.
Changes to INI File Handling
com.dotnet_version
is a new INI directive to choose the version of the .NET framework to use for
dotnet objects.
zend.exception_string_param_max_len
is a new INI directive to set the maximum string length in an argument of a stringified
stack strace.
EBCDIC
EBCDIC targets are no longer supported, though it's unlikely that they were still working in the
first place.
Performance
A Just-In-Time (JIT) compiler has been added to the opcache extension.
array_slice on an array without gaps will no longer scan the whole array
to find the start offset. This may significantly reduce the runtime of the function with large
offsets and small lengths.
strtolower now uses a SIMD implementation when using the
"C" LC_CTYPE locale (which is the default).
New Features
PHP Core
Named Arguments
Support for Named Arguments has been added.
Attributes
Support for Attributes has been added.
Constructor Property Promotion
Support for constructor property promotion (declaring properties in the constructor signature)
has been added.
Union Types
Support for union types has been added.
Match Expression
Support for match expressions has been added.
Nullsafe Operator
Support for the nullsafe operator (?->) has been added.
Other new Features
The WeakMap class has been added.
The ValueError class has been added.
Any number of function parameters may now be replaced by a variadic argument, as long as the
types are compatible. For example, the following code is now allowed:
<?php
class A {
public function method(int $many, string $parameters, $here) {}
}
class B extends A {
public function method(...$everything) {}
}
?>
static (as in "late static binding") can now be used as a return type:
<?php
class Test {
public function create(): static {
return new static();
}
}
?>
It is now possible to fetch the class name of an object using
$object::class. The result is the same as get_class($object).
and can now be used with arbitrary expressions,
using new (expression)(...$args) and $obj instanceof (expression).
Some consistency fixes to variable syntax have been applied, for example writing
Foo::BAR::$baz is now allowed.
Added Stringable interface, which is automatically implemented if
a class defines a __toString() method.
Traits can now define abstract private methods.
Such methods must be implemented by the class using the trait.
throw can now be used as an expression.
That allows usages like:
<?php
$fn = fn() => throw new Exception('Exception in arrow function');
$user = $session->user ?? throw new Exception('Must have user');
An optional trailing comma is now allowed in parameter lists.
<?php
function functionWithLongSignature(
Type1 $parameter1,
Type2 $parameter2, // <-- This comma is now allowed.
) {
}
It is now possible to write catch (Exception) to catch an exception without storing
it in a variable.
Support for mixed type has been added.
Private methods declared on a parent class no longer enforce any inheritance rules on the methods
of a child class (with the exception of final private constructors).
The following example illustrates which restrictions have been removed:
<?php
class ParentClass {
private function method1() {}
private function method2() {}
private static function method3() {}
// Throws a warning, as "final" no longer has an effect:
private final function method4() {}
}
class ChildClass extends ParentClass {
// All of the following are now allowed, even though the modifiers aren't
// the same as for the private methods in the parent class.
public abstract function method1() {}
public static function method2() {}
public function method3() {}
public function method4() {}
}
?>
get_resource_id has been added, which returns the same value as
(int) $resource. It provides the same functionality under a clearer API.
The InternalIterator has been added.
Date and Time
DateTime::createFromInterface and
DateTimeImmutable::createFromInterface have been added.
The DateTime format specifier p has been added, which is the same as
P but returns Z rather than +00:00
for UTC.
DOM
DOMParentNode and DOMChildNode with
new traversal and manipulation APIs have been added.
Filter
FILTER_VALIDATE_BOOL has been added as an alias for
FILTER_VALIDATE_BOOLEAN. The new name is preferred, as it uses the canonical
type name.
Enchant
enchant_dict_add, enchant_dict_is_added, and
LIBENCHANT_VERSION have been added.
FPM
Added a new option pm.status_listen that allows getting the status from
different endpoint (e.g. port or UDS file) which is useful for getting the status when all
children are busy with serving long running requests.
Hash
HashContext objects can now be serialized.
Internationalization Functions
The IntlDateFormatter::RELATIVE_FULL,
IntlDateFormatter::RELATIVE_LONG,
IntlDateFormatter::RELATIVE_MEDIUM, and
IntlDateFormatter::RELATIVE_SHORT
constants have been added.
LDAP
ldap_count_references has been added, which returns the number
of reference messages in a search result.
OPcache
If the opcache.record_warnings ini setting is
enabled, OPcache will record compile-time warnings and replay them on the next include, even if
it is served from cache.
OpenSSL
Added Cryptographic Message Syntax (CMS) (RFC 5652)
support composed of functions for encryption, decryption, signing, verifying and reading. The API
is similar to the API for PKCS #7 functions with an addition of new encoding constants:
OPENSSL_ENCODING_DER, OPENSSL_ENCODING_SMIME
and OPENSSL_ENCODING_PEM:
openssl_cms_encrypt encrypts the message in the file with the certificates
and outputs the result to the supplied file.
openssl_cms_decrypt that decrypts the S/MIME message in the file and outputs
the results to the supplied file.
openssl_cms_read that exports the CMS file to an array
of PEM certificates.
openssl_cms_sign that signs the MIME message in the file with a cert and key
and output the result to the supplied file.
openssl_cms_verify that verifies that the data block is intact, the signer
is who they say they are, and returns the certs of the signers.
Regular Expressions (Perl-Compatible)
preg_last_error_msg has been added, which returns a human-readable message for the last
PCRE error. It complements preg_last_error, which returns an integer enum value
instead.
Reflection
The following methods can now return information about default values of
parameters of internal functions:
ReflectionParameter::isDefaultValueAvailable
ReflectionParameter::getDefaultValue
ReflectionParameter::isDefaultValueConstant
ReflectionParameter::getDefaultValueConstantName
SQLite3
SQLite3::setAuthorizer and respective class constants have been added
to set a userland callback that will be used to authorize or not an action on the database.
Standard Library
str_contains, str_starts_with and
str_ends_with have been added, which check whether haystack contains,
starts with or ends with needle, respectively.
fdiv has been added, which performs a floating-point division under IEEE 754 semantics.
Division by zero is considered well-defined and will return one of Inf,
-Inf or NaN.
get_debug_type has been added, which returns a type useful for error messages. Unlike
gettype, it uses canonical type names, returns class names for objects, and
indicates the resource type for resources.
printf and friends now support the %h and
%H format specifiers. These are the same as %g and
%G, but always use "." as the decimal separator, rather
than determining it through the LC_NUMERIC locale.
printf and friends now support using "*" as width or
precision, in which case the width/precision is passed as an argument to printf. This also allows
using precision -1 with %g, %G,
%h and %H. For example, the following code can be used to
reproduce PHP's default floating point formatting:
<?php
printf("%.*H", (int) ini_get("precision"), $float);
printf("%.*H", (int) ini_get("serialize_precision"), $float);
?>
proc_open now supports pseudo-terminal (PTY) descriptors. The following
attaches stdin, stdout and stderr to the
same PTY:
<?php
$proc = proc_open($command, [['pty'], ['pty'], ['pty']], $pipes);
?>
proc_open now supports socket pair descriptors. The following attaches a
distinct socket pair to stdin, stdout and
stderr:
<?php
$proc = proc_open($command, [['socket'], ['socket'], ['socket']], $pipes);
?>
Unlike pipes, sockets do not suffer from blocking I/O issues on Windows. However, not all
programs may work correctly with stdio sockets.
Sorting functions are now stable, which means that equal-comparing elements will retain their
original order.
array_diff, array_intersect and their variations can
now be used with a single array as argument. This means that usages like the following are now
possible:
<?php
// OK even if $excludes is empty:
array_diff($array, ...$excludes);
// OK even if $arrays only contains a single array:
array_intersect(...$arrays);
?>
The flag parameter of ob_implicit_flush was changed
to accept a bool rather than an int.
Tokenizer
PhpToken adds an object-based interface to the tokenizer. It provides a
more uniform and ergonomic representation, while being more memory efficient and faster.
Zip
The Zip extension has been updated to version 1.19.1.
New ZipArchive::setMtimeName and
ZipArchive::setMtimeIndex to set the modification time of an entry.
New ZipArchive::registerProgressCallback to provide updates during archive close.
New ZipArchive::registerCancelCallback to allow cancellation during archive
close.
New ZipArchive::replaceFile to replace an entry content.
New ZipArchive::isCompressionMethodSupported to check optional compression
features.
New ZipArchive::isEncryptionMethodSupported to check optional encryption
features.
The ZipArchive::lastId property to get the index value of
the last added entry has been added.
Errors can now be checked after an archive has been closed using the
ZipArchive::status and
ZipArchive::statusSys properties, or the
ZipArchive::getStatusString method.
The 'remove_path' option of ZipArchive::addGlob and
ZipArchive::addPattern is now treated as an arbitrary string prefix (for
consistency with the 'add_path' option), whereas formerly it was treated as a
directory name.
Optional compression / encryption features are now listed in phpinfo.
Deprecated Features
PHP Core
If a parameter with a default value is followed by a required parameter, the default value has
no effect. This is deprecated as of PHP 8.0.0 and can generally be resolved by dropping the
default value, without a change in functionality:
<?php
function test($a = [], $b) {} // Before
function test($a, $b) {} // After
?>
One exception to this rule are parameters of the form Type $param = null, where
the null default makes the type implicitly nullable. This usage remains allowed, but it is
recommended to use an explicit nullable type instead:
<?php
function test(A $a = null, $b) {} // Still allowed
function test(?A $a, $b) {} // Recommended
?>
Calling get_defined_functions with exclude_disabled
explicitly set to is deprecated and no longer has an effect.
get_defined_functions will never include disabled functions.
Enchant
enchant_broker_set_dict_path and
enchant_broker_get_dict_path
are deprecated, because that functionality is neither available in libenchant 1.5 nor in
libenchant-2.
enchant_dict_add_to_personal is deprecated; use
enchant_dict_add instead.
enchant_dict_is_in_session is deprecated; use
enchant_dict_is_added instead.
enchant_broker_free and enchant_broker_free_dict are
deprecated; unset the object instead.
The ENCHANT_MYSPELL and ENCHANT_ISPELL constants are
deprecated.
LibXML
libxml_disable_entity_loader has been deprecated. As libxml 2.9.0 is now
required, external entity loading is guaranteed to be disabled by default, and this function is
no longer needed to protect against XXE attacks, unless the (still vulnerable)
LIBXML_NOENT is used.
In that case, it is recommended to refactor the code using
libxml_set_external_entity_loader to suppress loading of external entities.
PGSQL / PDO PGSQL
The constant PGSQL_LIBPQ_VERSION_STR now has the same value as
PGSQL_LIBPQ_VERSION, and thus is deprecated.
Function aliases in the pgsql extension have been deprecated.
See the following list for which functions should be used instead:
pg_errormessage → pg_last_error
pg_numrows → pg_num_rows
pg_numfields → pg_num_fields
pg_cmdtuples → pg_affected_rows
pg_fieldname → pg_field_name
pg_fieldsize → pg_field_size
pg_fieldtype → pg_field_type
pg_fieldnum → pg_field_num
pg_result → pg_fetch_result
pg_fieldprtlen → pg_field_prtlen
pg_fieldisnull → pg_field_is_null
pg_freeresult → pg_free_result
pg_getlastoid → pg_last_oid
pg_locreate → pg_lo_create
pg_lounlink → pg_lo_unlink
pg_loopen → pg_lo_open
pg_loclose → pg_lo_close
pg_loread → pg_lo_read
pg_lowrite → pg_lo_write
pg_loreadall → pg_lo_read_all
pg_loimport → pg_lo_import
pg_loexport → pg_lo_export
pg_setclientencoding → pg_set_client_encoding
pg_clientencoding -> pg_client_encoding
Standard Library
Sort comparison functions that return or will now throw a deprecation warning, and
should be replaced with an implementation that returns an integer less than, equal to, or greater
than zero.
<?php
// Replace
usort($array, fn($a, $b) => $a > $b);
// With
usort($array, fn($a, $b) => $a <=> $b);
?>
Zip
Using an empty file as ZipArchive is deprecated. Libzip 1.6.0 does not accept empty files as
valid zip archives any longer. The existing workaround will be removed in the next version.
The procedural API of Zip is deprecated. Use ZipArchive instead.
Iteration over all entries can be accomplished using ZipArchive::statIndex
and a for loop:
<?php
// iterate using the procedural API
assert(is_resource($zip));
while ($entry = zip_read($zip)) {
echo zip_entry_name($entry);
}
// iterate using the object-oriented API
assert($zip instanceof ZipArchive);
for ($i = 0; $entry = $zip->statIndex($i); $i++) {
echo $entry['name'];
}
?>
Reflection
ReflectionFunction::isDisabled is deprecated, as it is no longer
possible to create a ReflectionFunction for a disabled function. This
method now always returns .
ReflectionParameter::getClass,
ReflectionParameter::isArray, and
ReflectionParameter::isCallable are deprecated.
ReflectionParameter::getType and the
ReflectionType APIs should be used instead.
New functions
Date and Time
DateTimeImmutable::createFromMutable
GMP
gmp_root
gmp_rootrem
Hash
hash_equals
LDAP
ldap_escape
ldap_modify_batch
MySQLi
mysqli_get_links_stats
OCI8
oci_get_implicit_resultset
OpenSSL
openssl_get_cert_locations
openssl_x509_fingerprint
openssl_spki_new
openssl_spki_verify
openssl_spki_export_challenge
openssl_spki_export
PostgreSQL
pg_connect_poll
pg_consume_input
pg_flush
pg_socket
PDO_PGSQL
PDO::pgsqlGetNotify
PDO::pgsqlGetPid
Session
session_abort
session_reset
Zip
ZipArchive::setPassword
New global constants
GD
IMG_WEBP (as of PHP 5.6.25)
LDAP
LDAP_ESCAPE_DN
LDAP_ESCAPE_FILTER
OpenSSL
OPENSSL_DEFAULT_STREAM_CIPHERS
STREAM_CRYPTO_METHOD_ANY_CLIENT
STREAM_CRYPTO_METHOD_ANY_SERVER
STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT
STREAM_CRYPTO_METHOD_TLSv1_0_SERVER
STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
STREAM_CRYPTO_METHOD_TLSv1_1_SERVER
STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
PostgreSQL
PGSQL_CONNECT_ASYNC
PGSQL_CONNECTION_AUTH_OK
PGSQL_CONNECTION_AWAITING_RESPONSE
PGSQL_CONNECTION_MADE
PGSQL_CONNECTION_SETENV
PGSQL_CONNECTION_SSL_STARTUP
PGSQL_CONNECTION_STARTED
PGSQL_DML_ESCAPE
PGSQL_POLLING_ACTIVE
PGSQL_POLLING_FAILED
PGSQL_POLLING_OK
PGSQL_POLLING_READING
PGSQL_POLLING_WRITING
OpenSSL changes in PHP 5.6.x
Stream wrappers now verify peer certificates and host names by default when using SSL/TLS
Certificate fingerprints
Support has been added for extracting and verifying certificate
fingerprints. openssl_x509_fingerprint has been added
to extract a fingerprint from an X.509 certificate, and two
SSL stream context options have been
added: capture_peer_cert to capture the peer's X.509
certificate, and peer_fingerprint to assert that the
peer's certificate should match the given fingerprint.
Default ciphers updated
The default ciphers used by PHP have been updated to a more secure list
based on the
Mozilla cipher recommendations,
with two additional exclusions: anonymous Diffie-Hellman ciphers, and RC4.
This list can be accessed via the new
OPENSSL_DEFAULT_STREAM_CIPHERS constant, and can be
overridden (as in previous PHP versions) by setting the
ciphers
context option.
Compression disabled by default
SSL/TLS compression has been disabled by default to mitigate the CRIME
attack. PHP 5.4.13 added a
disable_compression
context option to allow compression to be disabled: this is now set to
(that is, compression is disabled) by default.
Allow servers to prefer their cipher order
The honor_cipher_order SSL context option has been
added to allow encrypted stream servers to mitigate BEAST vulnerabilities
by preferring the server's ciphers to the client's.
Access the negotiated protocol and cipher
The protocol and cipher that were negotiated for an encrypted stream can
now be accessed via stream_get_meta_data or
stream_context_get_options when the
capture_session_meta SSL context option is set to
.
New options for perfect forward secrecy in encrypted stream servers
Encrypted client streams already support perfect forward secrecy, as it is
generally controlled by the server. PHP encrypted server streams using
certificates capable of perfect forward secrecy do not need to take any
additional action to enable PFS; however a number of new SSL context options
have been added to allow more control over PFS and deal with any
compatibility issues that may arise.
This option allows the selection of a specific curve for use with ECDH
ciphers. If not specified, prime256v1 will be used.
A path to a file containing parametrs for Diffie-Hellman key exchange,
such as that created by the following command:
If set to , a new key pair will be created when using
Diffie-Hellman parameters, thereby improving forward secrecy.
If set to , a new key pair will always be generated when ECDH
cipher suites are negotiated. This improves forward secrecy.
SSL/TLS version selection
It is now possible to select specific versions of SSL and TLS via the
crypto_method SSL context option or by specifying a
specific transport when creating a stream wrapper (for example, by calling
stream_socket_client or
stream_socket_server).
The crypto_method SSL context option accepts a
bitmask enumerating the protocols that are permitted, as does the
crypto_type of
stream_socket_enable_crypto.
Selected protocol versions and corresponding options
openssl_get_cert_locations added
The openssl_get_cert_locations function has been
added: it returns the default locations PHP will search when looking for
CA bundles.
SPKI support
Support has been added for generating, extracting and verifying signed
public key and challenges (SPKAC). openssl_spki_new,
openssl_spki_verify,
openssl_spki_export_challenge, and
openssl_spki_export have been added to create, verify
export PEM public key and associated challenge from
SPKAC's generated from a KeyGen HTML5 element.
Generates a new SPKAC using private key, challenge string and hashing
algorithm.
Verifies provided SPKAC.
Exports associated challenge from provided SPKAC.
Exports the PEM formatted RSA public key from SPKAC.
Backward incompatible changes
Although most existing PHP 5 code should work without changes, please take
note of some backward incompatible changes:
Array keys won't be overwritten when defining an array as a property of a class via an array literal
Previously, arrays declared as class properties which mixed explicit and
implicit keys could have array elements silently overwritten if an explicit
key was the same as a sequential implicit key. For example:
json_decode strictness
json_decode now rejects non-lowercase variants of the
JSON literals true, false and
null at all times, as per the JSON specification, and
sets json_last_error accordingly. Previously, inputs
to json_decode that consisted solely of one of these
values in upper or mixed case were accepted.
This change will only affect cases where invalid JSON was being passed to
json_decode: valid JSON input is unaffected and will
continue to be parsed normally.
Stream wrappers now verify peer certificates and host names by default when using SSL/TLS
GMP resources are now objects
GMP resources are now objects. The
functional API implemented in the GMP extension has not changed, and code
should run unmodified unless it checks explicitly for a resource using
is_resource or similar.
Mcrypt functions now require valid keys and IVs
mcrypt_encrypt, mcrypt_decrypt,
mcrypt_cbc, mcrypt_cfb,
mcrypt_ecb, mcrypt_generic and
mcrypt_ofb will no longer accept keys or IVs with
incorrect sizes, and block cipher modes that require IVs will now fail if
an IV isn't provided.
cURL file uploads
Uploads using the @file syntax now require CURLOPT_SAFE_UPLOAD to be set to
. CURLFile should be used instead.
New features
Constant expressions
It is now possible to provide a scalar expression involving numeric and
string literals and/or constants in contexts where PHP previously expected
a static value, such as constant and property declarations and default
function arguments.
It is also now possible to define a constant array using the
const keyword:
Variadic functions via ...
Variadic functions can
now be implemented using the ... operator, instead of
relying on func_get_args.
Argument unpacking via ...
Arrays and
Traversable objects can be unpacked into
argument lists when calling functions by using the ...
operator. This is also known as the splat operator in other languages,
including Ruby.
Exponentiation via **
A right associative ** operator has been added to
support exponentiation, along with a **= shorthand
assignment operator.
use function and use const
The
use
operator has been extended to support importing functions and constants in
addition to classes. This is achieved via the
use function and use const
constructs, respectively.
phpdbg
PHP now includes an interactive debugger called phpdbg implemented as a
SAPI module. For more information, please visit the
phpdbg documentation.
Default character encoding
default_charset is now used as
the default character set for the htmlentities,
html_entity_decode and
htmlspecialchars functions. Note that if the (now
deprecated) iconv and mbstring encoding settings are set, they will take
precedence over default_charset for iconv and mbstring functions,
respectively.
The default value for this setting is UTF-8.
php://input is reusable
php://input
may now be reopened and read as many times as required. This work has also
resulted in a major reduction in the amount of memory required to deal
with POST data.
Large file uploads
Files larger than 2 gigabytes in size are now accepted.
GMP supports operator overloading
GMP objects now support operator
overloading and casting to scalar types. This allows for more expressive
code using GMP:
hash_equals for timing attack safe string comparison
The hash_equals function has been added to compare
two strings in constant time. This should be used to mitigate timing
attacks; for instance, when testing crypt password
hashes (assuming that you are unable to use
password_hash and
password_verify, which aren't susceptible to timing
attacks).
__debugInfo()
The __debugInfo()
magic method has been added to allow objects to change the properties and
values that are shown when the object is output using
var_dump.
gost-crypto hash algorithm
The gost-crypto hash algorithm has been added. This
implements the GOST hash function using the CryptoPro S-box tables as
specified by
RFC 4357, section 11.2.
SSL/TLS improvements
A wide range of improvements have been made to the SSL/TLS support in PHP
5.6. These include
enabling peer verification by default,
supporting certificate fingerprint matching, mitigating against TLS
renegotiation attacks, and many new
SSL context options to allow more fine
grained control over protocol and verification settings when using
encrypted streams.
These changes are described in more detail in the
OpenSSL changes in PHP 5.6.x
section of this migration guide.
pgsql async support
The pgsql extension now supports
asynchronous connections and queries, thereby enabling non-blocking
behaviour when interacting with PostgreSQL databases. Asynchronous
connections may be established via the
PGSQL_CONNECT_ASYNC constant, and the new
pg_connect_poll, pg_socket,
pg_consume_input and pg_flush
functions may be used to handle asynchronous connections and queries.
Other changes to extensions
cURL
A number of constants marked obsolete in the cURL library have now been
removed:
CURLOPT_CLOSEPOLICY
CURLCLOSEPOLICY_CALLBACK
CURLCLOSEPOLICY_LEAST_RECENTLY_USED
CURLCLOSEPOLICY_LEAST_TRAFFIC
CURLCLOSEPOLICY_OLDEST
CURLCLOSEPOLICY_SLOWEST
OCI8
Support for implicit result sets for Oracle Database 12c has been added
via the new oci_get_implicit_resultset function.
Using oci_execute($s, OCI_NO_AUTO_COMMIT) for a
SELECT no longer unnecessarily initiates an internal ROLLBACK during
connection close.
Added DTrace probes controlled by the --enable-dtrace
configure option.
oci_internal_debug is now a no-op.
The phpinfo output format for OCI8 has changed.
Zip
A --with-libzip configure option has been added to use
a system libzip installation. libzip version 0.11 is required, with 0.11.2
or later recommended.
MySQLi
A new mysqli.rollback_on_cached_plink
option was added, which controls the rollback behavior of persistent connections.
Changed functions
PHP Core
crypt will now raise an
E_NOTICE error if the salt
parameter is omitted.
substr_compare will now accept 0
for its length parameter.
unserialize will now fail if passed serialised data
that has been manipulated to attempt to instantiate an object without
calling its constructor.
cURL
Uploads using the @file syntax are now only supported
if the CURLOPT_SAFE_UPLOAD option is set to
. CURLFile should be used instead.
Mcrypt
The source parameter of
mcrypt_create_iv now defaults to
MCRYPT_DEV_URANDOM instead of
MCRYPT_DEV_RANDOM.
OpenSSL
stream_socket_enable_crypto now allows the
crypto_type parameter to be optional if the
stream's SSL context includes the new crypto_type
option.
PostgreSQL
pg_insert, pg_select,
pg_update and pg_delete are no
longer experimental.
pg_send_execute,
pg_send_prepare, pg_send_query
and pg_send_query_params will no longer block until
query write completion if the underlying socket stream for the database
connection is set to non-blocking mode.
Reflection
ReflectionClass::newInstanceWithoutConstructor
now allows non-final internal classes to be
instantiated.
XMLReader
XMLReader::getAttributeNs and
XMLReader::getAttributeNo now return if
the attribute could not be found, like
XMLReader::getAttribute.
Deprecated features in PHP 5.6.x
Calls from incompatible context
Methods called from an incompatible context are now deprecated, and will
generate E_DEPRECATED errors when invoked instead of
E_STRICT. Support for these calls will be removed in
a future version of PHP.
An example of such a call is:
$HTTP_RAW_POST_DATA and always_populate_raw_post_data
always_populate_raw_post_data
will now generate an E_DEPRECATED error when
$HTTP_RAW_POST_DATA is populated.
New code should use
php://input
instead of $HTTP_RAW_POST_DATA, which will be removed
in a future release. You can opt in for the new behaviour (in which
$HTTP_RAW_POST_DATA is never defined hence no
E_DEPRECATED error will be generated) by setting
always_populate_raw_post_data
to -1.
iconv and mbstring encoding settings
The iconv and
mbstring configuration options related
to encoding have been deprecated in favour of
default_charset.
The deprecated options are:
iconv.input_encoding
iconv.output_encoding
iconv.internal_encoding
mbstring.http_input
mbstring.http_output
mbstring.internal_encoding
Windows Support
Support for long and UTF-8 path
If a web application is UTF-8 conform, no further action is required. For
applications depending on paths in non UTF-8 encodings for I/O, an explicit
INI directive has to be set. The encoding INI settings check relies on the
order in the core:
internal_encoding
default_charset
zend.multibyte
Several functions for codepage handling were introduced:
sapi_windows_cp_set() to set the default codepage
sapi_windows_cp_get() to retrieve the current codepage
sapi_windows_cp_is_utf8()
sapi_windows_cp_conv() to convert between codepages, using iconv() compatible signature
These functions are thread safe.
The console output codepage is adjusted depending on the encoding used in
PHP. Depending on the concrete system OEM codepage, the visible output
might or might be not correct. For example, in the default cmd.exe and on
a system with the OEM codepage 437, outputs in codepages 1251, 1252, 1253
and some others can be shown correctly when using UTF-8. On the same system,
chars in codepage like 20932 probably won't be shown correctly. This refers
to the particular system rules for codepage, font compatibility and the
particular console program used. PHP automatically sets the console codepage
according to the encoding rules from php.ini. Using alternative consoles
instead of cmd.exe directly might bring better experience in some cases.
Nevertheless be aware, runtime codepage switch after the request start
might bring unexpected side effects on CLI. The preferable way is php.ini,
When PHP CLI is used in a console emulator, that doesn't support Unicode,
it might possibly be required, to avoid changing the console codepage. The
best way to achieve it is by setting the default or internal encoding to
correspond the ANSI codepage. Another method is to set the INI directives
output_encoding and input_encoding to the required codepage, in which case
however the difference between internal and I/O codepage is likely to cause
mojibake. In rare cases, if PHP happens to crash gracefully, the original
console codepage might be not restored. In this case, the chcp command
can be used, to restore it manually.
Special awareness for the DBCS systems - the codepage switch on runtime
using ini_set is likely to cause display issues. The difference to the
non DBCS systems is, that the extended characters require two console cells
to be displayed. In certain case, only the mapping of the characters into
the glyph set of the font could happen, no actual font change. This is the
nature of DBCS systems, the most simple way to prevent display issues is
to avoid usage of ini_set for the codepage change.
As a result of UTF-8 support in the streams, PHP scripts are not limited
to ASCII or ANSI filenames anymore. This is supported out of the box on
CLI. For other SAPI, the documentation for the corresponding server
is useful.
Long paths support is transparent. Paths longer than 260 bytes get
automatically prefixed with \\?\. The max path length is limited to
2048 bytes. Be aware, that the path segment limit (basename length) still
persists.
For the best portability, it is strongely recommended to handle filenames,
I/O and other related topics UTF-8. Additionally, for the console applications,
the usage of a TrueType font is preferable and the usage of ini_set() for
the codepage change is discouraged.
readline
The readline extension is supported
through the WinEditLine
library. Thereby, the interactive CLI shell is
supported as well (php.exe -a).
PHP_FCGI_CHILDREN
PHP_FCGI_CHILDREN is now respected. If this environment variable is
defined, the first php-cgi.exe process will exec the specified number
of children. These will share the same TCP socket.
ftok()
Added support for ftok
New functions
PHP Core
sapi_windows_cp_get
sapi_windows_cp_set
sapi_windows_cp_conv
sapi_windows_cp_is_utf8
Closure
Closure::fromCallable
CURL
curl_multi_errno
curl_share_errno
curl_share_strerror
OpenSSL
openssl_get_curve_names
Session
session_create_id
session_gc
SPL
is_iterable
PCNTL
pcntl_async_signals
pcntl_signal_get_handler
New global constants
Core Predefined Constants
PHP_FD_SETSIZE
CURL
CURLMOPT_PUSHFUNCTION
CURL_PUSH_OK
CURL_PUSH_DENY
Data Filtering
FILTER_FLAG_EMAIL_UNICODE
Image Processing and GD
IMAGETYPE_WEBP
JSON
JSON_UNESCAPED_LINE_TERMINATORS
LDAP
LDAP_OPT_X_SASL_NOCANON
LDAP_OPT_X_SASL_USERNAME
LDAP_OPT_X_TLS_CACERTDIR
LDAP_OPT_X_TLS_CACERTFILE
LDAP_OPT_X_TLS_CERTFILE
LDAP_OPT_X_TLS_CIPHER_SUITE
LDAP_OPT_X_TLS_KEYFILE
LDAP_OPT_X_TLS_RANDOM_FILE
LDAP_OPT_X_TLS_CRLCHECK
LDAP_OPT_X_TLS_CRL_NONE
LDAP_OPT_X_TLS_CRL_PEER
LDAP_OPT_X_TLS_CRL_ALL
LDAP_OPT_X_TLS_DHFILE
LDAP_OPT_X_TLS_CRLFILE
LDAP_OPT_X_TLS_PROTOCOL_MIN
LDAP_OPT_X_TLS_PROTOCOL_SSL2
LDAP_OPT_X_TLS_PROTOCOL_SSL3
LDAP_OPT_X_TLS_PROTOCOL_TLS1_0
LDAP_OPT_X_TLS_PROTOCOL_TLS1_1
LDAP_OPT_X_TLS_PROTOCOL_TLS1_2
LDAP_OPT_X_TLS_PACKAGE
LDAP_OPT_X_KEEPALIVE_IDLE
LDAP_OPT_X_KEEPALIVE_PROBES
LDAP_OPT_X_KEEPALIVE_INTERVAL
PostgreSQL
PGSQL_NOTICE_LAST
PGSQL_NOTICE_ALL
PGSQL_NOTICE_CLEAR
SPL
MT_RAND_PHP
Backward incompatible changes
Throw on passing too few function arguments
Previously, a warning would be emitted for invoking user-defined functions
with too few arguments. Now, this warning has been promoted to an Error
exception. This change only applies to user-defined functions, not internal
functions. For example:
Forbid dynamic calls to scope introspection functions
Dynamic calls for certain functions have been forbidden (in the form of
$func() or array_map('extract', ...),
etc). These functions either inspect or modify another scope, and present
with them ambiguous and unreliable behavior. The functions are as follows:
assert - with a string as the first argument
compact
extract
func_get_args
func_get_arg
func_num_args
get_defined_vars
mb_parse_str - with one arg
parse_str - with one arg
Invalid class, interface, and trait names
The following names cannot be used to name classes, interfaces, or traits:
void
iterable
Numerical string conversions now respect scientific notation
Integer operations and conversions on numerical strings now respect
scientific notation. This also includes the (int) cast
operation, and the following functions: intval (where
the base is 10), settype, decbin,
decoct, and dechex.
Fixes to mt_rand algorithm
mt_rand will now default to using the fixed version of
the Mersenne Twister algorithm. If deterministic output from
mt_rand was relied upon, then
MT_RAND_PHP can be used as optional second parameter
to mt_srand to preserve the old (incorrect)
implementation.
rand aliased to mt_rand and
srand aliased to mt_srand
rand and srand have now been made
aliases to mt_rand and mt_srand,
respectively. This means that the output for the following functions have
changed: rand, shuffle,
str_shuffle, and array_rand.
Disallow the ASCII delete control character in identifiers
The ASCII delete control character (0x7F) can no longer
be used in identifiers that are not quoted.
error_log changes with syslog
value
If the error_log ini setting is set to
syslog, the PHP error levels are mapped to the syslog
error levels. This brings finer differentiation in the error logs in
contrary to the previous approach where all the errors are logged with the
notice level only.
Do not call destructors on incomplete objects
Destructors are now never called for objects that throw an exception during
the execution of their constructor. In previous versions this behavior
depended on whether the object was referenced outside the constructor (e.g.
by an exception backtrace).
call_user_func handling of reference arguments
call_user_func will now always generate a warning
upon calls to functions that expect references as arguments. Previously
this depended on whether the call was fully qualified.
Additionally, call_user_func and
call_user_func_array will no longer abort the function
call in this case. The "expected reference" warning will be emitted, but the
call will proceed as usual.
The empty index operator is not supported for strings anymore
Applying the empty index operator to a string (e.g. $str[] = $x)
throws a fatal error instead of converting silently to array.
Assignment via string index access on an empty string
String modification by character on an empty string now works like for non-empty
strings, i.e. writing to an out of range offset pads the string with spaces,
where non-integer types are converted to integer, and only the first character of
the assigned string is used. Formerly, empty strings where silently treated like
an empty array.
<?php
$a = '';
$a[10] = 'foo';
var_dump($a);
?>
array(1) {
[10]=>
string(3) "foo"
}
string(11) " f"
Removed ini directives
The following ini directives have been removed:
session.entropy_file
session.entropy_length
session.hash_function
session.hash_bits_per_character
Array ordering when elements are automatically created during by reference
assignments has changed
The order of the elements in an array has changed when those elements have
been automatically created by referencing them in a by reference
assignment. For example:
Sort order of equal elements
The internal sorting algorithm has been improved, what may result in
different sort order of elements, which compare as equal, than before.
Don't rely on the order of elements which compare as equal; it might change
anytime.
Error message for E_RECOVERABLE errors
The error message for E_RECOVERABLE errors has been changed from "Catchable
fatal error" to "Recoverable fatal error".
$options parameter of unserialize()
The allowed_classes element of the $options parameter of
unserialize is now strictly typed, i.e. if anything
other than an array or a bool is given,
unserialize() returns and issues an E_WARNING.
DateTime constructor incorporates microseconds
DateTime and DateTimeImmutable
now properly incorporate microseconds when constructed from the current time,
either explicitly or with a relative string (e.g. "first day of next
month"). This means that naive comparisons of two newly created
instances will now more likely return instead of :
<?php
new DateTime() == new DateTime();
?>
Fatal errors to Error exceptions conversions
In the Date extension, invalid serialization data for
DateTime or DatePeriod classes,
or timezone initialization failure from serialized data, will now throw an
Error exception from the
__wakeup or __set_state
methods, instead of resulting in a fatal error.
In the DBA extension, data modification functions (such as
dba_insert) will now throw an
Error exception instead of triggering a catchable
fatal error if the key does not contain exactly two elements.
In the DOM extension, invalid schema or RelaxNG validation contexts will now
throw an Error exception instead of resulting in a
fatal error. Similarly, attempting to register a node class that does not
extend the appropriate base class, or attempting to read an invalid property
or write to a readonly property, will also now throw an
Error exception.
In the IMAP extension, email addresses longer than 16385 bytes will throw an
Error exception instead of resulting in a fatal error.
In the Intl extension, failing to call the parent constructor in a class
extending Collator before invoking the parent methods
will now throw an Error instead of resulting in a
recoverable fatal error. Also, cloning a
Transliterator object will now throw an
Error exception on failure to clone the internal
transliterator instead of resulting in a fatal error.
In the LDAP extension, providing an unknown modification type to
ldap_batch_modify will now throw an
Error exception instead of resulting in a fatal error.
In the mbstring extension, the mb_ereg and
mb_eregi functions will now throw a
ParseError exception if an invalid PHP expression is
provided and the 'e' option is used.
In the Mcrypt extension, the mcrypt_encrypt and
mcrypt_decrypt will now throw an
Error exception instead of resulting in a fatal error
if mcrypt cannot be initialized.
In the mysqli extension, attempting to read an invalid property or write to
a readonly property will now throw an Error exception
instead of resulting in a fatal error.
In the Reflection extension, failing to retrieve a reflection object or
retrieve an object property will now throw an Error
exception instead of resulting in a fatal error.
In the Session extension, custom session handlers that do not return strings
for session IDs will now throw an Error exception
instead of resulting in a fatal error when a function is called that must
generate a session ID.
In the SimpleXML extension, creating an unnamed or duplicate attribute will
now throw an Error exception instead of resulting in
a fatal error.
In the SPL extension, attempting to clone an
SplDirectory object will now throw an
Error exception instead of resulting in a fatal
error. Similarly, calling ArrayIterator::append when
iterating over an object will also now throw an Error
exception.
In the standard extension, the assert function, when
provided with a string argument as its first parameter, will now throw a
ParseError exception instead of resulting in a
catchable fatal error if the PHP code is invalid. Similarly, calling
forward_static_call outside of a class scope will now
throw an Error exception.
In the Tidy extension, creating a tidyNode manually
will now throw an Error exception instead of
resulting in a fatal error.
In the WDDX extension, a circular reference when serializing will now throw
an Error exception instead of resulting in a fatal
error.
In the XML-RPC extension, a circular reference when serializing will now
throw an instance of Error exception instead of
resulting in a fatal error.
In the Zip extension, the ZipArchive::addGlob
method will now throw an Error exception instead of
resulting in a fatal error if glob support is not available.
Lexically bound variables cannot reuse names
Variables bound to a closure via
the use construct cannot use the same name as any
, $this, or any parameter. For
example, all of these function definition will result in a fatal error:
<?php
$f = function () use ($_SERVER) {};
$f = function () use ($this) {};
$f = function ($param) use ($param) {};
long2ip() parameter type change
long2ip now expects an int instead of a
string.
JSON encoding and decoding
The serialize_precision ini setting now controls the
serialization precision when encoding floats.
Decoding an empty key now results in an empty property name, rather than
_empty_ as a property name.
<?php
var_dump(json_decode(json_encode(['' => 1])));
object(stdClass)#1 (1) {
[""]=>
int(1)
}
When supplying the JSON_UNESCAPED_UNICODE flag to
json_encode, the sequences U+2028 and U+2029 are now
escaped.
Changes to mb_ereg and mb_eregi
parameter semantics
The third parameter to the mb_ereg and
mb_eregi functions (regs) will now be
set to an empty array if nothing was matched. Formerly, the parameter would
not have been modified.
Drop support for the sslv2 stream
The sslv2 stream has now been dropped in OpenSSL.
Forbid "return;" for typed returns already at compile-time
Return statements without argument in functions which declare a return type
now trigger E_COMPILE_ERROR (unless the return type is
declared as void), even if the return statement would never be
reached.
Other changes
Notices and warnings on arithmetic with invalid strings
New E_WARNING and E_NOTICE errors
have been introduced when invalid strings are coerced using operators
expecting numbers (+ -
* / **
% << >>
| & ^) or their
assignment equivalents. An E_NOTICE is emitted when the
string begins with a numeric value but contains trailing non-numeric
characters, and an E_WARNING is emitted when the string
does not contain a numeric value.
Warn on octal escape sequence overflow
Previously, 3-octet octal string escape sequences would overflow silently.
Now, they will still overflow, but E_WARNING will be
emitted.
Inconsistency fixes to $this
Whilst $this is considered a special variable in PHP, it
lacked proper checks to ensure it wasn't used as a variable name or
reassigned. This has now been rectified to ensure that
$this cannot be a user-defined variable, reassigned to a
different value, or be globalised.
Session ID generation without hashing
Session IDs will no longer be hashed upon generation. With this change
brings about the removal of the following four ini settings:
session.entropy_file
session.entropy_length
session.hash_function
session.hash_bits_per_character
And the addition of the following two ini settings:
session.sid_length - defines the length of the
session ID, defaulting to 32 characters for backwards compatibility)
session.sid_bits_per_character - defines the number
of bits to be stored per character (i.e. increases the range of characters
that can be used in the session ID), defaulting to 4 for backwards
compatibility
Changes to INI file handling
If the value is set to -1, then the dtoa mode 0 is used. The default
value is still 14.
If the value is set to -1, then the dtoa mode 0 is used. The value -1 is
now used by default.
The default of this setting has been changed to 1, so by
default libjpeg warnings are ignored.
The default of this setting has been changed to 1
(enabled) in PHP 7.1.2, and back to 0 (disabled) in PHP 7.1.7.
Session ID generation with a CSPRNG only
Session IDs will now only be generated with a CSPRNG.
More informative TypeError messages when is allowed
TypeError exceptions for arg_info type checks will
now provide more informative error messages. If the parameter type or return
type accepts (by either having a default value of or being a
nullable type), then the error message will now mention this with a message
of "must be ... or null" or "must ... or be null."
New features
Nullable types
Type declarations for parameters and return values can now be marked as
nullable by prefixing the type name with a question mark. This signifies
that as well as the specified type, can be passed as an argument, or
returned as a value, respectively.
Void functions
A void return type has been introduced. Functions declared with
void as their return type must either omit their return statement altogether,
or use an empty return statement. is not a valid return value for a
void function.
Attempting to use a void function's return value simply evaluates to
, with no warnings emitted. The reason for this is because warnings
would implicate the use of generic higher order functions.
Symmetric array destructuring
The shorthand array syntax ([]) may now be used to
destructure arrays for assignments (including within
foreach), as an alternative to the existing
list syntax, which is still supported.
Class constant visibility
Support for specifying the visibility of class constants has been added.
iterable pseudo-type
A new pseudo-type (similar to callable) called
iterable has been introduced. It may be used in parameter
and return types, where it accepts either arrays or objects that implement
the Traversable interface. With respect to subtyping,
parameter types of child classes may broaden a parent's declaration of array
or Traversable to iterable. With return types,
child classes may narrow a parent's return type of iterable to
array or an object that implements Traversable.
Multi catch exception handling
Multiple exceptions per catch block may now be specified using the pipe
character (|). This is useful for when different
exceptions from different class hierarchies are handled the same.
Support for keys in list
You can now specify keys in list, or its new shorthand
[] syntax. This enables destructuring of arrays with
non-integer or non-sequential keys.
Support for negative string offsets
Support for negative string offsets has been added to the
string manipulation functions
accepting offsets, as well as to
string indexing with
[] or {}. In such cases, a negative
offset is interpreted as being an offset from the end of the string.
Negative string and array offsets are now also supported in the simple
variable parsing syntax inside of strings.
Support for AEAD in ext/openssl
Support for AEAD (modes GCM and CCM) have been added by extending the
openssl_encrypt and
openssl_decrypt functions with additional parameters.
Convert callables to Closures with Closure::fromCallable
A new static method has been introduced to the Closure
class to allow for callables to be easily converted into
Closure objects.
Asynchronous signal handling
A new function called pcntl_async_signals has been
introduced to enable asynchronous signal handling without using ticks (which
introduce a lot of overhead).
HTTP/2 server push support in ext/curl
Support for server push has been added to the CURL extension (requires
version 7.46 and above). This can be leveraged through the
curl_multi_setopt function with the new
CURLMOPT_PUSHFUNCTION constant. The constants
CURL_PUSH_OK and CURL_PUSH_DENY have also been
added so that the execution of the server push callback can either be
approved or denied.
Stream Context Options
The tcp_nodelay stream
context option has been added.
Changed functions
PHP Core
getopt has an optional third parameter that exposes
the index of the next element in the argument vector list to be processed.
This is done via a by-ref parameter.
getenv no longer requires its parameter. If the
parameter is omitted, then the current environment variables will be
returned as an associative array.
get_headers now has an additional parameter to enable
for the passing of custom stream contexts.
output_reset_rewrite_vars no longer resets session
URL rewrite variables.
parse_url is now more restrictive and supports
RFC3986.
unpack now accepts an optional third parameter to
specify the offset to begin unpacking from.
File System
file_get_contents now accepts a negative seek offset
if the stream is seekable.
tempnam now emits a notice when falling back to the
system's temp directory.
JSON
json_encode now accepts a new option,
JSON_UNESCAPED_LINE_TERMINATORS, to disable the
escaping of U+2028 and U+2029 characters when
JSON_UNESCAPED_UNICODE is supplied.
Multibyte String
mb_ereg now rejects illegal byte sequences.
mb_ereg_replace now rejects illegal byte sequences.
PDO
PDO::lastInsertId for PostgreSQL will now trigger an error
when nextval has not been called for the current
session (the postgres connection).
PostgreSQL
pg_last_notice now accepts an optional parameter to
specify an operation. This can be done with one of the following new
constants: PGSQL_NOTICE_LAST,
PGSQL_NOTICE_ALL, or
PGSQL_NOTICE_CLEAR.
pg_fetch_all now accepts an optional second parameter
to specify the result type (similar to the third parameter of
pg_fetch_array).
pg_select now accepts an optional fourth parameter to
specify the result type (similar to the third parameter of
pg_fetch_array).
Session
session_start now returns and no longer
initializes $_SESSION when it failed to start the
session.
Deprecated features in PHP 7.1.x
ext/mcrypt
The mcrypt extension has been abandonware for nearly a decade now, and was
also fairly complex to use. It has therefore been deprecated in favour of
OpenSSL, where it will be removed from the core and into PECL in PHP 7.2.
Eval option for mb_ereg_replace and mb_eregi_replace
The e pattern modifier has been deprecated for the
mb_ereg_replace and
mb_eregi_replace functions.
Windows Support
Core
The configuration variables PHP_VERSION,
PHP_MINOR_VERSION, and
PHP_RELEASE_VERSION are now always numbers.
Previously, they have been strings for buildconf builds.
phpize builds now reflect the source tree in the
build dir (as it already worked for in-tree builds); some extension
builds (especially when using Makefile.frag.w32) may need adjustments.
--enable-sanitizer is now supported
for MSVC builds. This enables ASan and debug assertions, and is supported
as of MSVC 16.10 and Windows 10.
The --with-uncritical-warn-choke
configuration option for clang builds is no longer supported.
Select warnings to suppress via CFLAGS instead.
COM
The extension is now build shared by default; previously it defaulted to a
static extension, although the official Windows binaries built a shared
extension.
FFI
It is no longer necessary to specify the library when using
FFI::cdef and FFI::load.
However, this convenience feature should not be used in production.
Streams
If only pipe streams are contained in the $read
array, and the $write and
$except arrays are empty,
stream_select now behaves similar to POSIX systems,
i.e. the function only returns if at least one pipe is ready to be read,
or after the timeout expires.
Previously, stream_select returned immediately,
reporting all streams as ready to read.
New Classes and Interfaces
Core
Curl
Filter
URI
New Functions
Core
Curl
DOM
Enchant
Intl
Opcache
PDO_SQLITE
PGSQL
Reflection
Sqlite
Standard
New Global Constants
Core
cURL
Filter
Intl
OpenSSL
POSIX
Sockets
Tokenizer
Standard
Backward Incompatible Changes
PHP Core
"array" and "callable" alias name
It is no longer possible to use "array"
and "callable" as class alias names
in class_alias
Loosely comparing uncomparable objects
Loosely comparing uncomparable objects (e.g. enums,
CurlHandle and other internal classes) to booleans
was previously inconsistent. If compared to a boolean literal
$object == true, it would behave the same way as
(bool)$object. If compared to a statically unknown value
$object == $true, it would always return .
This behavior was consolidated to always follow the behavior of
(bool)$object.
Return value of gc_collect_cycles
The return value of gc_collect_cycles no longer includes
strings and resources that were indirectly collected through cycles.
Substitute static keyword in final subclass
It is now allowed to substitute static with self or the concrete class name
in final subclasses.
Tick handlers
The tick handlers are now deactivated after all shutdown functions,
destructors have run and the output handlers have been cleaned up.
Traits binding
Traits are now bound before the parent class. This is a subtle behavioral
change, but should more closely match user expectations.
Errors during compilation and class linking
Errors emitted during compilation and class linking are now always delayed
and handled after compilation or class linking. Fatal errors emitted during
compilation or class linking cause any delayed errors to be handled
immediately, without calling user-defined error handlers.
Exceptions thrown by user-defined error handler
Exceptions thrown by user-defined error handlers when handling class linking
errors are not promoted to fatal errors anymore and do not prevent linking.
Attribute apply error during compilation
Applying #[\Attribute] to an abstract class, enum, interface, or trait
triggers an error during compilation. Previously, the attribute could be
added, but when ReflectionAttribute::newInstance
was called an error would be thrown.
The error can be delayed from compilation to runtime using the new
#[\DelayedTargetValidation] attribute.
disable_classes INI setting
The disable_classes INI setting
has been removed as it causes various engine assumptions to be broken.
Destructuring non-array values
Destructuring non-array values (other than ) using [] or list now
emits a warning.
Warnings related to cast
A warning is now emitted when casting floats (or strings that look like
floats) to int if they cannot be represented as one. This affects explicit
int casts and implicit int casts.
A warning is now emitted when casting NAN to other types.
Bzip2
bzcompress now throws a ValueError
when $block_size is not between 1 and 9.
bzcompress now throws a ValueError
when $work_factor is not between 0 and 250.
DOM
Cloning a DOMNamedNodeMap,
DOMNodeList, Dom\NamedNodeMap,
Dom\NodeList, Dom\HTMLCollection,
and Dom\DtdNamedNodeMap now fails.
This never actually resulted in a working object, therefore no impact is expected.
FileInfo
finfo_file and finfo::file
now throws a ValueError instead of a
TypeError when $filename
contains nul bytes.
This aligns the type of Error thrown to be consistent with the rest of
the language.
Intl
The extension now requires at least ICU 57.1.
IntlDateFormatter::setTimeZone/datefmt_set_timezone
now throws an IntlException on uninitialised
classes/clone failures.
All Locale methods now throw a
ValueError when the locale argument contain null bytes.
The behaviour of Collator::SORT_REGULAR with respect to
handling numeric strings is now aligned with the behaviour of
SORT_REGULAR in ext/standard.
LDAP
ldap_get_option and ldap_set_option
now throw a ValueError when passing an invalid option.
MBString
Unicode data tables have been updated to Unicode 17.0
MySQLi
Calling the mysqli constructor on an already-constructed object
is now no longer possible and throws an Error.
ODBC
ODBC now assumes that at least ODBC 3.5 functionality is available.
The ODBCVER definition and build system flags to control it have been removed.
ODBC no longer has build flags to build against specific drivers (except
for DB2) and removes special cases for those drivers. It is strongly
recommended to use a driver manager like iODBC or unixODBC on non-Windows.
Opcache
The Opcache extension is now always built into the PHP binary and is always
loaded.
The INI directives opcache.enable
and opcache.enable_cli are still
honored.
The --enable-opcache/--disable-opcache
configure flags have been removed, and the build does not produce opcache.so
or php_opcache.dll objects anymore.
Using zend_extension=opcache.so or
zend_extension=php_opcache.dll INI directives
will emit a warning.
PCNTL
pcntl_exec now throws ValueError
when entries of the $args parameter contain null bytes.
pcntl_exec now throws ValueError
when entries or keys of the $env_vars parameter
contain null bytes.
PCRE
The extension is compiled without semi-deprecated
PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK compile option.
PDO
The constructor arguments set in conjunction with
PDO::FETCH_CLASS now follow the usual CUFA
(call_user_func_array) semantics.
This means string keys will act like a named argument.
Moreover, automatic wrapping for by-value arguments passed to a by-ref
parameter has been removed, and the usual E_WARNING
about this is now emitted.
To pass a variable by-ref to a constructor argument use the general
array value reference assignment: $ctor_args = [$valByRef]
Attempting to call PDOStatement::setFetchMode during
a call to PDO::fetch,
PDO::fetchObject,
PDO::fetchAll, for example using tricks such as
passing the statement object as a constructor argument when fetching into an
object, will now throw an Error.
The value of the constants PDO::FETCH_GROUP,
PDO::FETCH_UNIQUE,
PDO::FETCH_CLASSTYPE,
PDO::FETCH_PROPS_LATE, and
PDO::FETCH_SERIALIZE have changed.
A ValueError is now thrown if
PDO::FETCH_PROPS_LATE is used with a fetch mode
different than PDO::FETCH_CLASS, consistent with
other fetch flags.
A ValueError is now thrown if
PDO::FETCH_INTO is used as a fetch mode in
PDO::fetchAll,
similar to PDO::FETCH_LAZY.
PDO_FIREBIRD
A ValueError is now thrown when trying to set a cursor
name that is too long on a PDOStatement resulting from
the Firebird driver.
PDO_SQLITE
SQLite PDO::quote will now throw an exception
or emit a warning, depending on the error mode, if the string contains
a null byte.
PDO::sqliteCreateCollation will now throw an
exception if the callback has the wrong return type, making it more
in line with Pdo\Sqlite::createCollation behavior.
POSIX
posix_kill now throws a
ValueError when the process_id argument is
lower or greater than what the platform supports (signed integer or
long range), posix_setpgid now throws a
ValueError when the process_id or
the process_group_id is lower than zero or greater than what the platform
supports.
posix_setrlimit now throws a
ValueError when the hard_limit or
soft_limit arguments are lower than -1 or if soft_limit is greater than
hard_limit.
Reflection
ReflectionAttribute::newInstance can now throw
errors for internal attributes if the attribute was applied on an invalid
target and the error was delayed from compile time to runtime via the
#[\DelayedTargetValidation] attribute.
Session
Attempting to write session data where $_SESSION has a key
containing the pipe character (|) will now emit a warning
instead of silently failing.
session_start is stricter in regard to the options
argument. It now throws a ValueError if
the array is not a hashmap, or a TypeError
if the read_and_close value is not a valid type compatible with int.
Passing an integer 0 as the locales
argument to setlocale is no longer supported and now throws
a TypeError.
SimpleXML
Passing an XPath expression that returns something other than a node set
to SimpleXMLElement::xpath will now emit a warning
and return , instead of silently failing and returning an empty array.
SNMP
snmpget,
snmpset,
snmp2_get,
snmp2_set,
snmp3_get,
snmp3_set
and SNMP::__construct now throw a
ValueError when the hostname
is too large, contains any null byte or if the port is given
when negative or greater than 65535, timeout and retries values
are lower than -1 or too large.
SOAP
SoapClient::__doRequest now accepts a new,
optional $uriParserClass parameter accepting
string or arguments.
represents the original (parse_url) based
method, while the new backends will be used when passing either
Uri\Rfc3986\Uri or Uri\WhatWg\Url.
Sockets
socket_create_listen,
socket_bind and socket_sendto
now throw a ValueError if the port is lower
than 0 or greater than 65535, and also if any of the hints array entries are
indexed numerically.
socket_addrinfo_lookup now throws a
TypeError if any of the hints values cannot
be cast to int and can throw a ValueError if
any of these values overflow.
socket_set_option with
MCAST_LEAVE_GROUP/MCAST_LEAVE_SOURCE_GROUP
options now throw an exception if the value isn't a valid object or array.
socket_set_option with multicast context now throws a
ValueError when the created socket is not of
AF_INET/AF_INET6 family.
SPL
ArrayObject no longer accepts enums, as modifying the
$name or $value properties can break
engine assumptions.
SplFileObject::fwrite's parameter
$length is now nullable.
The default value changed from 0 to .
Standard
Using a printf-family function with a formatter that did not specify the
precision previously incorrectly reset the precision instead of treating
it as a precision of 0.
Tidy
tidy::__construct,
tidy::parseFile,
tidy::parseString now throws a
ValueError if the configuration contains an
invalid value or attempts to set a read-only internal entry,
and a TypeError if a configuration key is not a
string.
Other Changes
Core changes
Core
The high resolution timer (hrtime) on macOS now
uses the recommended
clock_gettime_nsec_np(CLOCK_UPTIME_RAW) API instead of
mach_absolute_time().
CGI/CLI
The -z or --zend-extension option
has been removed as it was non-functional.
Use -d zend_extension=[path] instead.
PDO_ODBC
The fetch behaviour for larger columns has been changed. Rather than
fetching 256 byte blocks, PDO_ODBC will try to fetch a larger block size;
currently, this is the page size minus string overhead. Drivers that
return SQL_NO_TOTAL in SQLGetData are also better handled as well.
This should improve compatibility and performance.
Changes in SAPI Modules
CLI
Trying to set a process title that is too long with
cli_set_process_title will now fail instead of
silently truncating the given title.
Added a new --ini=diff option to print INI settings
changed from the builtin default.
FPM
FPM with httpd ProxyPass optionally decodes the full script path. Added
fastcgi.script_path_encoded
INI setting to prevent this new behavior.
FPM access log limit now respects log_limit value.
Changed Functions
Intl
grapheme_extract properly assigns
$next value when skipping over invalid starting bytes.
Previously there were cases where it would point to the start of the
grapheme boundary instead of the end.
transliterator_get_error_code,
transliterator_get_error_message,
TransLiterator::getErrorCode,
and TransLiterator::getErrorMessage
have dropped from the return type union. Returning
was actually never possible.
The following functions now support a $locale argument:
grapheme_strpos,
grapheme_stripos,
grapheme_strrpos,
grapheme_strripos,
grapheme_substr,
grapheme_strstr and
grapheme_stristr
LDAP
ldap_get_option now accepts a connection,
like ldap_set_option, to allow retrieval of global
options.
libxml
libxml_set_external_entity_loader now has a formal
return type of true.
OpenSSL
openssl_public_encrypt and
openssl_private_decrypt have a new parameter
$digest_algo that allows specifying the hash
digest algorithm for OAEP padding.
openssl_sign and openssl_verify
have a new parameter $padding to allow using more
secure RSA PSS padding.
openssl_cms_encrypt $cipher_algo
parameter can be a string with the cipher name.
That allows to use more algorithms including AES GCM cipher algorithms for
auth enveloped data.
PCNTL
pcntl_exec now has a formal return type of
false.
pcntl_waitid takes an additional resource_usage
argument to gather various platform specific metrics about the child process.
PDO_PGSQL
Pdo\Pgsql::copyFromArray now supports iterable inputs.
Pdo\Pgsql::setAttribute and
Pdo\Pgsql::prepare support setting
PDO::ATTR_PREFETCH to 0 which enters lazy fetch mode.
In this mode, statements cannot be run in parallel.
PostgreSQL
pg_copy_from now supports iterable inputs.
pg_connect checks if the connection_string argument
contains any null byte.
pg_close_stmt checks if the statement_name argument
contains any null byte.
POSIX
posix_ttyname sets last_error to EBADF when encountering
an invalid file descriptor.
posix_isatty raises an E_WARNING
message when encountering an invalid file descriptor.
posix_fpathconf checks invalid file descriptors and
sets last_error to EBADF and raises an E_WARNING message.
Reflection
The output of ReflectionClass::__toString for
enums has changed to better indicate that the class is an enum, and that
the enum cases are enum cases rather than normal class constants.
The output of ReflectionProperty::__toString for
properties with hooks has changed to indicate what hooks the property has,
whether those hooks are final, and whether the property is virtual.
This also affects the output of ReflectionClass::__toString
when a class contains hooked properties.
Sockets
socket_create/socket_bind can
create AF_PACKET family sockets.
socket_getsockname gets the interface index and its
string representation with AF_PACKET socket.
Zlib
The $use_include_path argument for the
gzfile, gzopen and
readgzfile functions has been changed
from int to bool.
gzfile,
gzopen and readgzfile functions
now respect the default stream context.
Other Changes to Extensions
cURL
curl_setopt with
CURLOPT_FOLLOWLOCATION option's value
no longer is treated as boolean but integer to handle
CURLFOLLOW_OBEYCODE and
CURLFOLLOW_FIRSTONLY.
Fileinfo
Upgraded file from 5.45 to 5.46.
The return type of finfo_close has been changed to
true, rather than bool.
Intl
Intl's internal error mechanism has been modernized so that it
indicates more accurately which call site caused what error.
Moreover, some ext/date exceptions have been wrapped inside a
IntlException now.
Lexbor
An always enabled lexbor extension is added. It contains the lexbor
library that was separated from ext/dom
for being reused among other extensions.
The new extension is not directly exposed to userland.
Opcache
The Opcache extension is now always
built into the PHP binary and is always loaded.
The INI directives opcache.enable
and opcache.enable_cli are
still honored.
PCRE
Upgraded pcre2lib from 10.44 to 10.46.
PDO_Sqlite
Increased minimum release version support from 3.7.7 to 3.7.17.
Readline
The return types of readline_add_history,
readline_clear_history,
and readline_callback_handler_install have been
changed to true, rather than bool.
Reflection
ReflectionConstant is no longer final.
Changes to INI File Handling
Core
Added fatal_error_backtraces to control whether fatal errors should include
a backtrace.
Added startup-only max_memory_limit INI setting to control the maximum
memory_limit that may be configured at startup or runtime. Exceeding this
value emits a warning, unless set to -1, and sets memory_limit to the
current max_memory_limit instead.
Opcache
Added opcache.file_cache_read_only to support a read-only
opcache.file_cache directory,
for use with read-only file systems (e.g. read-only Docker containers).
Best used with opcache.validate_timestamps=0,
opcache.enable_file_override=1,
and opcache.file_cache_consistency_checks=0.
A cache generated with a different build of PHP, a different file
path, or different settings (including which extensions are loaded), may be
ignored.
The default value of
opcache.jit_hot_loop is
now 61 (a prime) to prevent it from being a multiple of loop iteration
counts.
It is recommended that this parameter is set to a prime number.
Changing opcache.memory_consumption
when OPcache SHM is already set up will now correctly report a failure
instead of silently doing nothing and showing misleading values in PHPInfo.
OpenSSL
Added openssl.libctx
to select the OpenSSL library context type.
Either custom libctx for each thread can be used or a single global (default)
libctx is used.
Performance
Core
Remove OPcodes for identity comparisons against booleans, particularly
for the match(true) pattern.
Add OPcode specialization for === [] and
!== [] comparisons.
Creating exception objects is now much faster.
The parts of the code that used SSE2 have been adapted to use SIMD
with ARM NEON as well.
Introduced the TAILCALL VM, enabled by default when compiling with Clang>=19
on x86_64 or aarch64. The TAILCALL VM is as fast as the HYBRID VM used when
compiling with GCC. This makes PHP binaries built with Clang>=19 as fast as
binaries built with GCC. The performance of the CALL VM, used with other
compilers, has also improved considerably.
Intl
Now avoids creating extra string copies when converting strings
for use in the collator.
MBString
The parts of the code that used SSE2 have been adapted to use SIMD
with ARM NEON as well.
Opcache
Improved performance of fetching TLS variables in JIT'ed code in non-Glibc
builds.
Reflection
Improved performance of the following methods:
ReflectionProperty::getValue
ReflectionProperty::getRawValue
ReflectionProperty::isInitialized
ReflectionProperty::isInitialized
ReflectionProperty::setValue
ReflectionProperty::setRawValue
SPL
Improved performance of dimension accessors and methods of
SplFixedArray.
Standard
Improved performance of array functions with callbacks
(array_find, array_filter,
array_map, usort, ...).
Improved performance of urlencode and
rawurlencode.
Improved unpack performance with nameless
repetitions by avoiding creating temporary strings and reparsing them.
Improved pack performance.
Minor improvements in array_chunk performance.
XML
Improved XMLReader property access performance.
Improved XMLWriter performance and reduced memory
consumption.
New Features
PHP Core
Pipe Operator
Added the pipe
(|>) operator.
Closure in constant expressions
Added support for Closures and
first class callables
in constant expressions. This includes:
Attribute parameters.
Default values of properties and parameters.
Constants and Class Constants.
#[\NoDiscard] attribute
Added the NoDiscard attribute to indicate that a
function's return value is important and should be consumed.
Also, added the (void) cast to indicate that not using a value is intentional.
The (void) cast has no effect on the program's execution by itself, but
it can be used to suppress warnings emitted by #[\NoDiscard] and possibly
also diagnostics emitted by external IDEs or static analysis tools.
Attributes on Constants
Added support for attributes on compile-time non-class constants
(e.g. const MY_CONST = 1; rather than
define('MY_CONST', 1);).
The Deprecated attribute can now be used on constants.
#[\DelayedTargetValidation] attribute
The new DelayedTargetValidation attribute can be used
to suppress compile-time errors from core (or extension) attributes that are
used on invalid targets. These errors are instead reported at runtime if and
when ReflectionAttribute::newInstance is called.
#[\Override] for properties
Override attribute can now be applied to properties.
Static Asymmetric Visibility
Added asymmetric
visibility support for static properties.
Backtraces for Fatal Errors
Fatal Errors (such as an exceeded maximum execution time) now include a
backtrace.
Constructor promotion for final property
Constructor
property promotion can now be used for final properties.
Casts in constant expressions
Added support for casts in constant expressions.
Clone function
The clone language construct
is now a function and supports reassigning (readonly) properties during
cloning via the new $withProperties parameter.
cURL
Added support for
share handles
that are persisted across multiple PHP requests, safely allowing for
more effective connection reuse.
Added support for CURLINFO_USED_PROXY (libcurl >= 8.7.0),
CURLINFO_HTTPAUTH_USED,
and CURLINFO_PROXYAUTH_USED (libcurl >= 8.12.0)
to the curl_getinfo function.
When curl_getinfo returns an array, the same information
is available as "used_proxy",
"httpauth_used", and "proxyauth_used"
keys.
CURLINFO_USED_PROXY gets zero set if no proxy was used in the
previous transfer or a non-zero value if a proxy was used.
CURLINFO_HTTPAUTH_USED and
CURLINFO_PROXYAUTH_USED get bitmasks
indicating the HTTP and proxy authentication methods that were
used in the previous request.
See CURLAUTH_* constants for
possible values.
Added CURLOPT_INFILESIZE_LARGE Curl option, which is a safe
replacement for CURLOPT_INFILESIZE. On certain systems,
CURLOPT_INFILESIZE only accepts a 32-bit signed integer as
the file size (2.0 GiB) even on 64-bit systems.
CURLOPT_INFILESIZE_LARGE accepts the largest integer value
the system can handle.
Added CURLFOLLOW_OBEYCODE,
CURLFOLLOW_FIRSTONLY and CURLFOLLOW_ALL
values for CURLOPT_FOLLOWLOCATION
curl_setopt option.
CURLFOLLOW_OBEYCODE to follow more strictly in regard to
redirect if they are allowed.
CURLFOLLOW_FIRSTONLY to follow only the first redirect thus
if there is any follow up redirect, it won't go any further.
CURLFOLLOW_ALL is equivalent to setting
CURLOPT_FOLLOWLOCATION to true.
Added support for CURLINFO_CONN_ID (libcurl >= 8.2.0)
to the curl_getinfo function. This constant allows retrieving
the unique ID of the connection used by a cURL transfer. It is primarily
useful when connection reuse or connection pooling logic is needed in
PHP-level applications. When curl_getinfo returns an array,
this value is available as the "conn_id" key.
Added support for CURLINFO_QUEUE_TIME_T (libcurl >= 8.6.0)
to the curl_getinfo function. This constant allows
retrieving the time (in microseconds) that the request spent in libcurls
connection queue before it was sent.
This value can also be retrieved by passing
CURLINFO_QUEUE_TIME_T to the curl_getinfo
option parameter.
Added support for CURLOPT_SSL_SIGNATURE_ALGORITHMS to
specify the signature algorithms to use for TLS.
DOM
Added Dom\Element::$outerHTML.
Added $children property to
Dom\ParentNode implementations.
EXIF
Added support for OffsetTime* Exif tags.
Added support for HEIF/HEIC.
Filter
Added new FILTER_THROW_ON_FAILURE flag which can be
passed to the filter functions and will force an exception to be triggered
when validation fails.
The new flag cannot be combined with
FILTER_NULL_ON_FAILURE; trying to do so will result
in a ValueError being thrown.
Intl
Added class constants NumberFormatter::CURRENCY_ISO,
NumberFormatter::CURRENCY_PLURAL,
NumberFormatter::CASH_CURRENCY,
and NumberFormatter::CURRENCY_STANDARD
for various currency-related number formats.
Added Locale::addLikelySubtags and
Locale::minimizeSubtags to handle likely tags
on a given locale.
Added IntlListFormatter class to format, order,
and punctuate a list of items with a given locale,
IntlListFormatter::TYPE_AND,
IntlListFormatter::TYPE_OR,
IntlListFormatter::TYPE_UNITS operands and
IntlListFormatter::WIDTH_WIDE,
IntlListFormatter::WIDTH_SHORT and
IntlListFormatter::WIDTH_NARROW widths.
It is supported from icu 67.
PDO_Sqlite
Added class constant Pdo\Sqlite::ATTR_BUSY_STATEMENT.
Added class constants Pdo\Sqlite::ATTR_EXPLAIN_STATEMENT,
Pdo\Sqlite::EXPLAIN_MODE_PREPARED,
Pdo\Sqlite::EXPLAIN_MODE_EXPLAIN,
Pdo\Sqlite::EXPLAIN_MODE_EXPLAIN_QUERY_PLAN.
Added Pdo\Sqlite::ATTR_TRANSACTION_MODE connection attribute
with possible values Pdo\Sqlite::TRANSACTION_MODE_DEFERRED,
Pdo\Sqlite::TRANSACTION_MODE_IMMEDIATE,
and Pdo\Sqlite::TRANSACTION_MODE_EXCLUSIVE,
allowing to configure the transaction mode to use when calling beginTransaction().
Session
session_set_cookie_params,
session_get_cookie_params,
and session_start now support partitioned cookies via the
"partitioned" key.
SOAP
Enumeration cases are now dumped in SoapClient::__getTypes.
Added support for Soap 1.2 Reason Text xml:lang attribute.
The signature of SoapFault::__construct and
SoapServer::fault therefore
now have an optional $lang parameter.
This support solves compatibility with .NET SOAP clients.
Standard
mail now returns the actual sendmail error and detects
if the sendmail process was terminated unexpectedly.
In such cases, a warning is emitted and the function returns false.
Previously, these errors were silently ignored.
This change affects only the sendmail transport.
getimagesize now supports HEIF/HEIC images.
getimagesize now supports SVG images when ext-libxml
is also loaded.
Similarly, image_type_to_extension and
image_type_to_mime_type
now also handle IMAGETYPE_SVG.
The array returned by getimagesize now has two additional entries:
"width_unit" and "height_unit" to indicate in
which units the dimensions are expressed. These units are px by default. They are not
necessarily the same (just to give one example: one may be cm and the other may be px).
setcookie and setrawcookie now support the
"partitioned" key.
URI
An always enabled uri extension is added that can be used for handling
URIs and URLs according to RFC 3986 and WHATWG URL.
XSL
The $namespace argument of XSLTProcessor::getParameter,
XSLTProcessor::setParameter and
XSLTProcessor::removeParameter now actually works
instead of being treated as empty.
This only works if the $name argument does not use Clark notation and is not a
QName because in those cases the namespace is taken from the namespace href or
prefix respectively.
Zlib
flock is now supported on zlib streams. Previously,
this always failed to perform any locking action.
Deprecated Features
PHP Core
Changes to user output handler
Trying to produce output (e.g. with echo) within
a user output handler is deprecated.
The deprecation warning will bypass the handler producing the output to
ensure it is visible; if there are nested output handlers the next
one will still be used.
Non-canonical cast names
Non-canonical cast names (boolean),
(integer), (double),
and (binary) have been deprecated,
use (bool), (int),
(float), and (string) respectively.
Terminating case statements with a semicolon
Terminating case statements with a semicolon instead of a colon has
been deprecated.
The backtick operator
The backtick operator
as an alias for shell_exec has been deprecated.
Returning null from __debugInfo()
Returning from
__debugInfo()
has been deprecated. Return an empty array instead.
report_memleaks INI directive
The report_memleaks INI directive
has been deprecated.
Constant redeclaration
Constant redeclaration has been deprecated.
Note that this already generated a warning and will continue to do so.
Closure binding issues
The following closure binding issues, which already emit an
E_WARNING, are now deprecated:
Binding an instance to a static closure.
Binding methods to objects that are not instances of the class
(or subclass) that the method is defined.
Unbinding $this from a method.
Unbinding $this from a closure that uses `$this`.
Binding a closure to the scope of an internal class.
Rebinding the scope of a closure created from a function or method.
__sleep() and __wakeup() magic methods
The __sleep() and
__wakeup() magic methods
have been soft-deprecated.
The __serialize() and
__unserialize() magic
methods should be used instead, or at the same time if compatibility
with PHP 7 is required.
Using null as an array offset
Using as an array offset or when calling array_key_exists
is now deprecated. Instead an empty string should be used.
Incrementing non-numeric strings
Incrementing non-numeric strings is now deprecated.
Instead the str_increment function should be used.
register_argc_argv INI directive
Deriving $_SERVER['argc'] and $_SERVER['argv']
from the query string for non-CLI SAPIs has been deprecated.
Configure register_argc_argv=0 and switch to either
$_GET or $_SERVER['QUERY_STRING']
to access the information, after verifying that the usage is safe.
cURL
The curl_close function has been deprecated,
as CurlHandle objects are freed automatically.
The curl_share_close function has been deprecated,
as CurlShareHandle objects are freed automatically.
Date
The DATE_RFC7231 and
DateTimeInterface::RFC7231 constants have been deprecated.
This is because the associated timezone is ignored and always uses GMT.
FileInfo
The finfo_close function has been deprecated.
As finfo objects are freed automatically.
The $context parameter of the
finfo_buffer function has been deprecated
as it is ignored.
GD
The imagedestroy function has been deprecated,
as GdImage objects are freed automatically.
Hash
The MHASH_* constants have
been deprecated.
Intl
The intl.error_level INI setting
has been deprecated.
Errors should either be checked manually or exceptions should be enabled by
using the intl.use_exceptions
INI setting.
LDAP
Specific Oracle Instant Client calls and constants have been deprecated.
List of affected calls:
ldap_connect with wallet support
ldap_connect_wallet
List of affected constants:
GSLC_SSL_NO_UATH
GSLC_SSL_ONEWAY_UATH
GSLC_SSL_TWOWAY_UATH
MySQLi
The mysqli_execute alias function has been deprecated.
Use mysqli_stmt_execute instead.
OpenSSL
The $key_length parameter for
openssl_pkey_derive has been deprecated.
This is because it is either ignored, or truncates the key, which can be
a security vulnerability.
PDO
The "uri:" DSN scheme has been deprecated due to security concerns with
DSNs coming from remote URIs.
Driver specific constants in the PDO class have been deprecated.
List of affected constants and their replacement:
PDO::DBLIB_ATTR_CONNECTION_TIMEOUT => Pdo\Dblib::ATTR_CONNECTION_TIMEOUT
PDO::DBLIB_ATTR_QUERY_TIMEOUT => Pdo\Dblib::ATTR_QUERY_TIMEOUT
PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER => Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER
PDO::DBLIB_ATTR_VERSION => Pdo\Dblib::ATTR_VERSION
PDO::DBLIB_ATTR_TDS_VERSION => Pdo\Dblib::ATTR_TDS_VERSION
PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS => Pdo\Dblib::ATTR_SKIP_EMPTY_ROWSETS
PDO::DBLIB_ATTR_DATETIME_CONVERT => Pdo\Dblib::ATTR_DATETIME_CONVERT
PDO::FB_ATTR_DATE_FORMAT => Pdo\Firebird::ATTR_DATE_FORMAT
PDO::FB_ATTR_TIME_FORMAT => Pdo\Firebird::ATTR_TIME_FORMAT
PDO::FB_ATTR_TIMESTAMP_FORMAT => Pdo\Firebird::ATTR_TIMESTAMP_FORMAT
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => Pdo\Mysql::ATTR_USE_BUFFERED_QUERY
PDO::MYSQL_ATTR_LOCAL_INFILE => Pdo\Mysql::ATTR_LOCAL_INFILE
PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY => Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY
PDO::MYSQL_ATTR_INIT_COMMAND => Pdo\Mysql::ATTR_INIT_COMMAND
PDO::MYSQL_ATTR_MAX_BUFFER_SIZE => Pdo\Mysql::ATTR_MAX_BUFFER_SIZE
PDO::MYSQL_ATTR_READ_DEFAULT_FILE => Pdo\Mysql::ATTR_READ_DEFAULT_FILE
PDO::MYSQL_ATTR_READ_DEFAULT_GROUP => Pdo\Mysql::ATTR_READ_DEFAULT_GROUP
PDO::MYSQL_ATTR_COMPRESS => Pdo\Mysql::ATTR_COMPRESS
PDO::MYSQL_ATTR_DIRECT_QUERY => Pdo\Mysql::ATTR_DIRECT_QUERY
PDO::MYSQL_ATTR_FOUND_ROWS => Pdo\Mysql::ATTR_FOUND_ROWS
PDO::MYSQL_ATTR_IGNORE_SPACE => Pdo\Mysql::ATTR_IGNORE_SPACE
PDO::MYSQL_ATTR_SSL_KEY => Pdo\Mysql::ATTR_SSL_KEY
PDO::MYSQL_ATTR_SSL_CERT => Pdo\Mysql::ATTR_SSL_CERT
PDO::MYSQL_ATTR_SSL_CA => Pdo\Mysql::ATTR_SSL_CA
PDO::MYSQL_ATTR_SSL_CAPATH => Pdo\Mysql::ATTR_SSL_CAPATH
PDO::MYSQL_ATTR_SSL_CIPHER => Pdo\Mysql::ATTR_SSL_CIPHER
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => Pdo\Mysql::ATTR_SSL_VERIFY_SERVER_CERT
PDO::MYSQL_ATTR_SERVER_PUBLIC_KEY => Pdo\Mysql::ATTR_SERVER_PUBLIC_KEY
PDO::MYSQL_ATTR_MULTI_STATEMENTS => Pdo\Mysql::ATTR_MULTI_STATEMENTS
PDO::ODBC_ATTR_USE_CURSOR_LIBRARY => Pdo\Odbc::ATTR_USE_CURSOR_LIBRARY
PDO::ODBC_ATTR_ASSUME_UTF8 => Pdo\Odbc::ATTR_ASSUME_UTF8
PDO::ODBC_SQL_USE_IF_NEEDED => Pdo\Odbc::SQL_USE_IF_NEEDED
PDO::ODBC_SQL_USE_DRIVER => Pdo\Odbc::SQL_USE_DRIVER
PDO::ODBC_SQL_USE_ODBC => Pdo\Odbc::SQL_USE_ODBC
PDO::PGSQL_ATTR_DISABLE_PREPARES => Pdo\Pgsql::ATTR_DISABLE_PREPARES
PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES => Pdo\Sqlite::ATTR_EXTENDED_RESULT_CODES
PDO::SQLITE_ATTR_OPEN_FLAGS => Pdo\Sqlite::OPEN_FLAGS
PDO::SQLITE_ATTR_READONLY_STATEMENT => Pdo\Sqlite::ATTR_READONLY_STATEMENT
PDO::SQLITE_DETERMINISTIC => Pdo\Sqlite::DETERMINISTIC
PDO::SQLITE_OPEN_READONLY => Pdo\Sqlite::OPEN_READONLY
PDO::SQLITE_OPEN_READWRITE => Pdo\Sqlite::OPEN_READWRITE
PDO::SQLITE_OPEN_CREATE => Pdo\Sqlite::OPEN_CREATE
Driver specific methods in the PDO class have been deprecated.
List of affected methods and their replacement:
PDO::pgsqlCopyFromArray => Pdo\Pgsql::copyFromArray
PDO::pgsqlCopyFromFile => Pdo\Pgsql::copyFromFile
PDO::pgsqlCopyToArray => Pdo\Pgsql::copyToArray
PDO::pgsqlCopyToFile => Pdo\Pgsql::copyToFile
PDO::pgsqlGetNotify => Pdo\Pgsql::getNotify
PDO::pgsqlGetPid => Pdo\Pgsql::getPid
PDO::pgsqlLOBCreate => Pdo\Pgsql::lobCreate
PDO::pgsqlLOBOpen => Pdo\Pgsql::lobOpen
PDO::pgsqlLOBUnlink => Pdo\Pgsql::lobUnlink
PDO::sqliteCreateAggregate => Pdo\Sqlite::createAggregate
PDO::sqliteCreateCollation => Pdo\Sqlite::createCollation
PDO::sqliteCreateFunction => Pdo\Sqlite::createFunction
PDO_PGSQL
Constants related to transaction states have been deprecated as this feature is unavailable with PDO:
PDO::PGSQL_TRANSACTION_IDLE
PDO::PGSQL_TRANSACTION_ACTIVE
PDO::PGSQL_TRANSACTION_INTRANS
PDO::PGSQL_TRANSACTION_INERROR
PDO::PGSQL_TRANSACTION_UNKNOWN
Reflection
The setAccessible() methods of various Reflection objects have been
deprecated, as those no longer have an effect.
Calling ReflectionClass::getConstant for constants
that do not exist has been deprecated.
Calling ReflectionProperty::getDefaultValue for
properties without default values has been deprecated.
SPL
Unregistering all autoloaders by passing the
spl_autoload_call function as a callback argument to
spl_autoload_unregister has been deprecated.
Instead if this is needed, one should iterate over the return value of
spl_autoload_functions and call
spl_autoload_unregister on each value.
The SplObjectStorage::contains,
SplObjectStorage::attach, and
SplObjectStorage::detach methods have been deprecated
in favour of SplObjectStorage::offsetExists,
SplObjectStorage::offsetSet, and
SplObjectStorage::offsetUnset respectively.
Using ArrayObject and
ArrayIterator with objects has been deprecated.
Standard
The socket_set_timeout alias function has been deprecated.
Use stream_set_timeout instead.
Passing to readdir,
rewinddir, and closedir
to use the last opened directory has been deprecated.
Provide the last opened directory explicitly instead.
Passing integers outside the interval [0, 255] to chr
is now deprecated.
This is because a byte can only hold a value within this interval.
Passing a string which is not a single byte to ord
is now deprecated, this is indicative of a bug.
The locally predefined variable
$http_response_header
is deprecated. Instead one should call the
http_get_last_response_headers function.
XML
The xml_parser_free function has been deprecated,
as XMLParser objects are freed automatically.
Windows Support
Core
Windows specific error messages are no longer localized, but instead
always displayed in English to better match PHP error messages.
Preliminary and highly experimental support for building on ARM64 has been added.
OCI8
Because building against Oracle Client 10g is no longer supported anyway,
the configuration option --with-oci8 has been dropped.
The --with-oci8-11g, --with-oci8-12c and
--with-oci8-19 configuration options are still supported.
Zip
The Zip extension is upgraded to version 1.21.0,
and is now built as shared library (DLL) by default.
New Functions
cURL
IMAP
MySQLi
ODBC
OpenSSL
Reflection
Sodium
XChaCha20
Standard
XML
New Global Constants
COM
DISP_E_PARAMNOTFOUND
LOCALE_NEUTRAL
cURL
CURLALTSVC_H1 (libcurl >= 7.64.1)
CURLALTSVC_H2 (libcurl >= 7.64.1)
CURLALTSVC_H3 (libcurl >= 7.64.1)
CURLALTSVC_READONLYFILE (libcurl >= 7.64.1)
CURLAUTH_AWS_SIGV4 (libcurl >= 7.75.0)
CURLE_PROXY (libcurl >= 7.73.0)
CURLFTPMETHOD_DEFAULT
CURLHSTS_ENABLE (libcurl >= 7.74.0)
CURLHSTS_READONLYFILE (libcurl >= 7.74.0)
CURLINFO_PROXY_ERROR (libcurl >= 7.73.0)
CURLINFO_REFERER (libcurl >= 7.76.0)
CURLINFO_RETRY_AFTER (libcurl >= 7.66.0)
CURLMOPT_MAX_CONCURRENT_STREAMS (libcurl >= 7.67.0)
CURLOPT_ALTSVC_CTRL (libcurl >= 7.64.1)
CURLOPT_ALTSVC (libcurl >= 7.64.1)
CURLOPT_AWS_SIGV4 (libcurl >= 7.75.0)
CURLOPT_CAINFO_BLOB (libcurl >= 7.77.0)
CURLOPT_DOH_SSL_VERIFYHOST (libcurl >= 7.76.0)
CURLOPT_DOH_SSL_VERIFYPEER (libcurl >= 7.76.0)
CURLOPT_DOH_SSL_VERIFYSTATUS (libcurl >= 7.76.0)
CURLOPT_HSTS_CTRL (libcurl >= 7.74.0)
CURLOPT_HSTS (libcurl >= 7.74.0)
CURLOPT_MAIL_RCPT_ALLLOWFAILS (libcurl >= 7.69.0)
CURLOPT_MAXAGE_CONN (libcurl >= 7.65.0)
CURLOPT_MAXFILESIZE_LARGE
CURLOPT_MAXLIFETIME_CONN (libcurl >= 7.80.0)
CURLOPT_PROXY_CAINFO_BLOB (libcurl >= 7.77.0)
CURLOPT_SASL_AUTHZID (libcurl >= 7.66.0)
CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 (libcurl >= 7.80.0)
CURLOPT_SSL_EC_CURVES (libcurl >= 7.73.0)
CURLOPT_UPKEEP_INTERVAL_MS (libcurl >= 7.62.0)
CURLOPT_UPLOAD_BUFFERSIZE (libcurl >= 7.62.0)
CURLOPT_XFERINFOFUNCTION (libcurl >= 7.32.0)
CURLPROTO_MQTT (libcurl >= 7.71.0)
CURLPX_BAD_ADDRESS_TYPE (libcurl >= 7.73.0)
CURLPX_BAD_VERSION (libcurl >= 7.73.0)
CURLPX_CLOSED (libcurl >= 7.73.0)
CURLPX_GSSAPI (libcurl >= 7.73.0)
CURLPX_GSSAPI_PERMSG (libcurl >= 7.73.0)
CURLPX_GSSAPI_PROTECTION (libcurl >= 7.73.0)
CURLPX_IDENTD_DIFFER (libcurl >= 7.73.0)
CURLPX_IDENTD (libcurl >= 7.73.0)
CURLPX_LONG_HOSTNAME (libcurl >= 7.73.0)
CURLPX_LONG_PASSWD (libcurl >= 7.73.0)
CURLPX_LONG_USER (libcurl >= 7.73.0)
CURLPX_NO_AUTH (libcurl >= 7.73.0)
CURLPX_OK (libcurl >= 7.73.0)
CURLPX_RECV_ADDRESS (libcurl >= 7.73.0)
CURLPX_RECV_AUTH (libcurl >= 7.73.0)
CURLPX_RECV_CONNECT (libcurl >= 7.73.0)
CURLPX_RECV_REQACK (libcurl >= 7.73.0)
CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED (libcurl >= 7.73.0)
CURLPX_REPLY_COMMAND_NOT_SUPPORTED (libcurl >= 7.73.0)
CURLPX_REPLY_CONNECTION_REFUSED (libcurl >= 7.73.0)
CURLPX_REPLY_GENERAL_SERVER_FAILURE (libcurl >= 7.73.0)
CURLPX_REPLY_HOST_UNREACHABLE (libcurl >= 7.73.0)
CURLPX_REPLY_NETWORK_UNREACHABLE (libcurl >= 7.73.0)
CURLPX_REPLY_NOT_ALLOWED (libcurl >= 7.73.0)
CURLPX_REPLY_TTL_EXPIRED (libcurl >= 7.73.0)
CURLPX_REPLY_UNASSIGNED (libcurl >= 7.73.0)
CURLPX_REQUEST_FAILED (libcurl >= 7.73.0)
CURLPX_RESOLVE_HOST (libcurl >= 7.73.0)
CURLPX_SEND_AUTH (libcurl >= 7.73.0)
CURLPX_SEND_CONNECT (libcurl >= 7.73.0)
CURLPX_SEND_REQUEST (libcurl >= 7.73.0)
CURLPX_UNKNOWN_FAIL (libcurl >= 7.73.0)
CURLPX_UNKNOWN_MODE (libcurl >= 7.73.0)
CURLPX_USER_REJECTED (libcurl >= 7.73.0)
CURLSSLOPT_AUTO_CLIENT_CERT (libcurl >= 7.77.0)
CURLSSLOPT_NATIVE_CA (libcurl >= 7.71.0)
CURLSSLOPT_NO_PARTIALCHAIN (libcurl >= 7.68.0)
CURLSSLOPT_REVOKE_BEST_EFFORT (libcurl >= 7.70.0)
CURL_VERSION_GSASL (libcurl >= 7.76.0)
CURL_VERSION_HSTS (libcurl >= 7.74.0)
CURL_VERSION_HTTP3 (libcurl >= 7.66.0)
CURL_VERSION_UNICODE (libcurl >= 7.72.0)
CURL_VERSION_ZSTD (libcurl >= 7.72.0)
DBA
DBA_LMDB_USE_SUB_DIR
DBA_LMDB_NO_SUB_DIR
Filter
FILTER_FLAG_GLOBAL_RANGE
Sockets
The following socket options are now defined if they are supported:
SO_INCOMING_CPU
SO_MEMINFO
SO_RTABLE (OpenBSD)
TCP_KEEPALIVE (MacOS)
TCP_KEEPCNT (Linux, others)
TCP_KEEPIDLE (Linux, others)
TCP_KEEPINTVL (Linux, others)
TCP_NOTSENT_LOWAT
LOCAL_CREDS_PERSISTENT (FreeBSD)
SCM_CREDS2 (FreeBSD)
LOCAL_CREDS (NetBSD)
SO_BPF_EXTENSIONS
SO_SETFIB
TCP_CONGESTION (Linux, FreeBSD)
SO_ZEROCOPY (Linux)
MSG_ZEROCOPY (Linux)
Backward Incompatible Changes
Date
DateTime::createFromImmutable now has a tentative
return type of static, previously it was DateTime.
DateTimeImmutable::createFromMutable now has a tentative
return type of static, previously it was DateTimeImmutable.
number symbols in relative formats
no longer accept multiple signs, e.g. +-2.
ODBC
The ODBC extension now escapes the username and password for the case when
both a connection string and username/password are passed, and the string
must be appended to. Before, user values containing values needing escaping
could have created a malformed connection string, or injected values from
user-provided data. The escaping rules should be identical to the .NET BCL
DbConnectionOptions behaviour.
PDO_ODBC
The PDO_ODBC extension also escapes the username and password when a
connection string is passed. See the change to the ODBC extension for
further details.
Standard
glob now returns an empty if all paths are
restricted by open_basedir.
Previously it returned .
Moreover, a warning is now emitted even if only some paths are restricted by
open_basedir.
FilesystemIterator::__construct: prior to PHP 8.2.0,
FilesystemIterator::SKIP_DOTS constant was always set
and couldn't be disabled. In order to maintain the previous behaviour the constant
must be explicitly set when using the flags parameter.
The default value from flags parameter has
not been modified.
strtolower,
strtoupper,
stristr,
stripos,
strripos,
lcfirst,
ucfirst,
ucwords,
and str_ireplace are no longer locale-sensitive.
They now perform ASCII case conversion, as if the locale were "C".
Localized versions of these functions are available in the MBString extension.
Moreover, array_change_key_case, and sorting with
SORT_FLAG_CASE now also use ASCII case conversion.
str_split returns an empty for an empty now.
Previously it returned an array with a single empty string entry.
mb_str_split is not affected by this change as it was
already behaving like that.
ksort and krsort now do numeric string
comparison under SORT_REGULAR using the standard PHP 8 rules now.
var_export no longer omits the leading backslash for exported classes,
i.e. these are now fully qualified.
Standard PHP Library (SPL)
The following methods now enforce their signature:
SplFileInfo::_bad_state_ex
SplFileObject::getCsvControl
SplFileObject::fflush
SplFileObject::ftell
SplFileObject::fgetc
SplFileObject::fpassthru
SplFileObject::hasChildren now has a tentative
return type of false, previously it was bool.
SplFileObject::getChildren now has a tentative
return type of null, previously it was
RecursiveIteratornull.
GlobIterator now returns an empty if all
paths are restricted by open_basedir.
Previously it returned .
Moreover, a warning is now emitted even if only some paths are restricted by
open_basedir.
Other Changes
Core changes
The iterable type is now a built-in compile time alias for
arrayTraversable.
Error messages relating to iterable will therefore
now use array|Traversable.
Type Reflection is preserved for single iterable
(and ?iterable) to produce a
ReflectionNamedType with name iterable,
however usage of iterable in union types will be
converted to array|Traversable.
The date format of sent cookies is now 'D, d M Y H:i:s \G\M\T';
previously it was 'D, d-M-Y H:i:s T'.
Changes in SAPI Modules
CLI
The STDOUT, STDERR and STDIN streams are no longer closed on resource destruction
which is mostly when the CLI finishes. It is however still possible to
explicitly close those streams using fclose and similar.
Changed Functions
Core
The strcmp, strcasecmp,
strncmp, strncasecmp, and
substr_compare functions, using binary safe string
comparison is no longer guaranteed to return
strlen($string1) - strlen($string2) when string lengths are not
equal, but may now return -1 or 1
instead. Instead of depending on any concrete value, the return value should
be compared to 0.
DBA
dba_open and dba_popen
now have the following enforced signature:
resourcefalsedba_open
stringpath
stringmode
stringnullhandler
intpermission0644
intmap_size0
intnullflags
dba_fetch's optional skip argument is now at the end
in line with PHP userland semantics. Its signature is now:
stringfalsedba_fetch
stringarraykey
resourcehandle
intskip
The overloaded signature:
stringfalsedba_fetch
stringarraykey
intskip
resourcehandle
is still accepted, but it is recommended to use the new standard variant.
Random
random_bytes and random_int
now throw a \Random\RandomException on CSPRNG failures.
Previously a plain \Exception was thrown instead.
SPL
The iterator parameter of
iterator_to_array and iterator_count
is widened to iterable from Iterator,
allowing arrays to be passed.
Other Changes to Extensions
Date
The properties of DatePeriod are now properly declared.
Intl
Instances of
IntlBreakIterator,
IntlRuleBasedBreakIterator,
IntlCodePointBreakIterator,
IntlPartsIterator,
IntlCalendar,
Collator,
IntlIterator,
UConverter,
IntlDateFormatter,
IntlDatePatternGenerator,
MessageFormatter,
ResourceBundle,
Spoofchecker,
IntlTimeZone,
and Transliterator
are no longer serializable. Previously, they could be serialized, but
unserialization yielded unusable objects or failed.
MySQLi
The support for libmysql has been removed and it is no longer
possible to compile mysqli with libmysql.
From now on, the mysqli extension can be compiled only with mysqlnd.
All libmysql features unavailable in mysqlnd have been removed:
The reconnect property of mysqli_driver
The mysqli.reconnect INI directive
The MYSQLI_IS_MARIADB constant has been deprecated
OCI8
The minimum Oracle Client library version required is now 11.2.
PCRE
NUL characters (\0) in pattern strings are now supported.
Session
Trying to change the
session.cookie_samesite
INI directive while the session is active or output has already been sent
will now fail and emit a warning.
This aligns the behaviour with all other session INI settings.
SQLite3
sqlite3.defensive
is now INI_USER.
Standard
getimagesize now reports the actual image dimensions,
bits and channels of AVIF images. Previously, the dimensions have been reported as 0x0,
and bits and channels have not been reported at all.
Tidy
The properties of the tidy class are now properly declared.
And those of the tidyNode class are now properly declared as readonly.
Zip
The Zip extension has been updated to version 1.20.0,
which adds the following methods:
ZipArchive::clearError
ZipArchive::getStreamName
ZipArchive::getStreamIndex
Changes to INI File Handling
Support for binary (0b/0B) and octal
(0o/0O) prefixes has been added to integer INI settings.
Integer INI settings that start with a zero (0)
continue to be interpreted as an octal integer.
Parsing of some ill-formatted values will now trigger a warning when this
was silently ignored before.
For backwards compatibility, interpretation of these values has not changed.
This affects the following settings:
bcmath.scale
com.code_page
default_socket_timeout
fiber.stack_size
hard_timeout
intl.error_level
ldap.max_links
max_input_nesting_level
max_input_vars
mbstring.regex_retry_limit
mbstring.regex_stack_limit
mysqli.allow_local_infile
mysqli.allow_persistent
mysqli.default_port
mysqli.max_links
mysqli.max_persistent
mysqli.rollback_on_cached_plink
mysqlnd.log_mask
mysqlnd.mempool_default_size
mysqlnd.net_read_buffer_size
mysqlnd.net_read_timeout
oci8.default_prefetch
oci8.max_persistent
oci8.persistent_timeout
oci8.ping_interval
oci8.prefetch_lob_size
oci8.privileged_connect
oci8.statement_cache_size
odbc.allow_persistent
odbc.check_persistent
odbc.max_persistent
odbc.max_links
odbc.defaultbinmode
odbc.default_cursortype
odbc.defaultlrl
opcache.consistency_checks
opcache.file_update_protection
opcache.force_restart_timeout
opcache.interned_strings_buffer
opcache.jit_bisect_limit
opcache.jit_blacklist_root_trace
opcache.jit_blacklist_side_trace
opcache.jit_debug
opcache.jit_hot_func
opcache.jit_hot_loop
opcache.jit_hot_return
opcache.jit_hot_side_exit
opcache.jit_max_exit_counters
opcache.jit_max_loop_unrolls
opcache.jit_max_polymorphic_calls
opcache.jit_max_recursive_calls
opcache.jit_max_recursive_returns
opcache.jit_max_root_traces
opcache.jit_max_side_traces
opcache.log_verbosity_level
opcache.max_file_size
opcache.opt_debug_level
opcache.optimization_level
opcache.revalidate_freq
output_buffering
pcre.backtrack_limit
pcre.recursion_limit
pgsql.max_links
pgsql.max_persistent
post_max_size
realpath_cache_size
realpath_cache_ttl
session.cache_expire
session.cookie_lifetime
session.gc_divisor
session.gc_maxlifetime
session.gc_probability
soap.wsdl_cache_limit
soap.wsdl_cache_ttl
unserialize_max_depth
upload_max_filesize
user_ini.cache_ttl
xmlrpc_error_number
zend.assertions
zlib.output_compression_level
New Features
PHP Core
SensitiveParameter Attribute
Added the #[\SensitiveParameter] attribute to redact
sensitive data in backtraces.
error_log_mode INI directive
The error_log_mode INI directive has been added which allows setting
the permissions for the error log file.
Enumerations properties in constant expressions
It is now possible to fetch properties of
Enumerations
in constant expressions.
Type System Improvements
It is now possible to use null and false
as stand-alone types.
The true type has been added.
It is now possible to combine intersection and union types.
The type needs to be written in DNF.
Constants in Traits
It is now possible to define constants in traits.
Readonly Classes
Support for readonly
on classes has been added.
cURL
Added the CURLINFO_EFFECTIVE_METHOD option,
which returns the effective HTTP method in the return value of
curl_getinfo.
Exposed multiple new constants from libcurl 7.62 to 7.80.
Added the curl_upkeep function to perform any connection upkeep checks.
DBA
The LMDB Driver now accepts the DBA_LMDB_USE_SUB_DIR or
DBA_LMDB_NO_SUB_DIR flags to determine if it should
create a subdirectory or not when creating a database file.
OCI8
Added the oci8.prefetch_lob_size INI directive and
oci_set_prefetch_lob function to tune LOB query
performance by reducing the number of round-trips between PHP and
Oracle Databases when fetching LOBS.
This is usable with Oracle Database 12.2 or later.
OpenSSL
Added AEAD support for the chacha20-poly1305 algorithm.
ODBC
Added the odbc_connection_string_is_quoted,
odbc_connection_string_should_quote, and
odbc_connection_string_quote functions.
These are primarily used behind the scenes in the ODBC and PDO_ODBC extensions,
but are exposed to userland for easier unit testing, and for user
applications and libraries to perform quoting themselves.
PCRE
Added support for the n (NO_AUTO_CAPTURE) modifier,
which makes simple (xyz) groups non-capturing.
Only named groups like (?<name>xyz) are capturing.
This only affects which groups are capturing, it is still possible to use
numbered subpattern references, and the matches array will still contain
numbered results.
Random
This is a new extension which organises and consolidates existing
implementations related to random number generators.
New and better RNGs are available with scope issues eliminated.
Deprecated Features
PHP Core
Usage of dynamic properties
The creation of dynamic properties is deprecated, unless the class opts in by
using the #[\AllowDynamicProperties] attribute.
stdClass allows dynamic properties.
Usage of the __get()/__set() magic methods is not affected by this change.
A dynamic properties deprecation warning can be addressed by:
Declaring the property (preferred).
Adding the #[\AllowDynamicProperties] attribute to the class
(which also applies to all child classes).
Using a WeakMap if additional data needs to be
associated with an object which one does not own.
Relative callables
Callables that are not accepted by the $callable() syntax
(but are accepted by call_user_func) are deprecated.
In particular:
"self::method"
"parent::method"
"static::method"
["self", "method"]
["parent", "method"]
["static", "method"]
["Foo", "Bar::method"]
[new Foo, "Bar::method"]
This does not affect normal method callables such as
"A::method" or ["A", "method"].
"${var}" and "${expr}" style interpolation
The "${var}" and "${expr}" style of string
interpolation is deprecated.
Use "$var"/"{$var}" and "{${expr}}", respectively.
MBString
Usage of the QPrint, Base64,
Uuencode, and HTML-ENTITIES
'text encodings' is deprecated for all MBString functions.
Unlike all the other text encodings supported by MBString,
these do not encode a sequence of Unicode codepoints, but rather a sequence of raw bytes.
It is not clear what the correct return values for most MBString functions
should be when one of these non-encodings is specified.
Moreover, PHP has separate, built-in implementations of all of them;
for example, UUencoded data can be handled using
convert_uuencode/convert_uudecode.
SPL
The internal SplFileInfo::_bad_state_ex method
has been deprecated.
Standard
utf8_encode and utf8_decode
have been deprecated.
Windows Support
Core
Minimum supported Windows version has been bumped to Windows 8 or
Windows Server 2012.
New Classes and Interfaces
Date
DateError
DateObjectError
DateRangeError
DateException
DateInvalidOperationException
DateInvalidTimeZoneException
DateMalformedIntervalStringException
DateMalformedPeriodStringException
DateMalformedStringException
Random
Random\IntervalBoundary
New Functions
Date
DOM
Intl
JSON
LDAP
MBString
Posix
PostgreSQL
Random
Reflection
Sockets
Standard
Zip
New Global Constants
cURL
CURLINFO_CAPATH (libcurl >= 7.84.0)
CURLINFO_CAINFO (libcurl >= 7.84.0)
CURLOPT_MIME_OPTIONS (libcurl >= 7.81.0)
CURLMIMEOPT_FORMESCAPE (libcurl >= 7.81.0)
CURLOPT_WS_OPTIONS (libcurl >= 7.86.0)
CURLWS_RAW_MODE (libcurl >= 7.86.0)
CURLOPT_SSH_HOSTKEYFUNCTION (libcurl >= 7.84.0)
CURLOPT_PROTOCOLS_STR (libcurl >= 7.85.0)
CURLOPT_REDIR_PROTOCOLS_STR (libcurl >= 7.85.0)
CURLOPT_CA_CACHE_TIMEOUT (libcurl >= 7.87.0)
CURLOPT_QUICK_EXIT (libcurl >= 7.87.0)
CURLKHMATCH_OK (libcurl >= 7.19.6)
CURLKHMATCH_MISMATCH (libcurl >= 7.19.6)
CURLKHMATCH_MISSING (libcurl >= 7.19.6)
CURLKHMATCH_LAST (libcurl >= 7.19.6)
Intl
MIXED_NUMBERS
(Spoofchecker)
HIDDEN_OVERLAY
(Spoofchecker)
OpenSSL
OPENSSL_CMS_OLDMIMETYPE
PKCS7_NOOLDMIMETYPE
PCNTL
SIGINFO
PDO_ODBC
PDO_ODBC_TYPE
Posix
POSIX_SC_ARG_MAX
POSIX_SC_PAGESIZE
POSIX_SC_NPROCESSORS_CONF
POSIX_SC_NPROCESSORS_ONLN
POSIX_PC_LINK_MAX
POSIX_PC_MAX_CANON
POSIX_PC_MAX_INPUT
POSIX_PC_NAME_MAX
POSIX_PC_PATH_MAX
POSIX_PC_PIPE_BUF
POSIX_PC_CHOWN_RESTRICTED
POSIX_PC_NO_TRUNC
POSIX_PC_ALLOC_SIZE_MIN
POSIX_PC_SYMLINK_MAX
Sockets
The following socket options are now defined if they are supported:
SO_ATTACH_REUSEPORT_CBPF (Linux)
SO_DETACH_BPF (Linux)
SO_DETACH_FILTER (Linux)
TCP_QUICKACK (Linux)
IP_DONTFRAG (FreeBSD)
IP_MTU_DISCOVER (Linux)
IP_PMTUDISC_DO (Linux)
IP_PMTUDISC_DONT (Linux)
IP_PMTUDISC_WANT (Linux)
IP_PMTUDISC_PROBE (Linux)
IP_PMTUDISC_INTERFACE (Linux)
IP_PMTUDISC_OMIT (Linux)
AF_DIVERT (FreeBSD)
SOL_UDPLITE
UDPLITE_RECV_CSCOV
UDPLITE_SEND_CSCOV
SO_RERROR (NetBSD)
SO_ZEROIZE (OpenBSD)
SO_SPLICE (OpenBSD)
TCP_REPAIR (Linux)
SO_REUSEPORT_LB (FreeBSD)
IP_BIND_ADDRESS_NO_PORT (Linux)
Zip
ZipArchive::ER_DATA_LENGTH (libzip >= 1.10)
ZipArchive::ER_NOT_ALLOWED (libzip >= 1.10)
ZipArchive::AFL_RDONLY (libzip >= 1.10)
ZipArchive::AFL_IS_TORRENTZIP (libzip >= 1.10)
ZipArchive::AFL_WANT_TORRENTZIP (libzip >= 1.10)
ZipArchive::AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE
(libzip >= 1.10)
ZipArchive::FL_OPEN_FILE_NOW
ZipArchive::LENGTH_TO_END as default value for
ZipArchive::addFile and
ZipArchive::replaceFile
ZipArchive::LENGTH_UNCHECKED (libzip >= 1.10)
Backward Incompatible Changes
PHP Core
Programs that were very close to overflowing the call stack
Programs that were very close to overflowing the call stack may now throw an
Error when using more than
zend.max_allowed_stack_size-zend.reserved_stack_size bytes of stack
(fiber.stack_size-zend.reserved_stack_size for fibers).
Executing proc_get_status() multiple times
Executing proc_get_status multiple times will now always
return the right value on POSIX systems. Previously, only the first call
of the function returned the right value. Executing
proc_close after proc_get_status
will now also return the right exit code. Previously this would return
-1.
Internally, this works by caching the result on POSIX systems.
If the previous behaviour is required, it is possible to check the
"cached" key in the array returned by
proc_get_status to check whether the result was cached.
Zend Max Execution Timers
Zend Max Execution Timers is now enabled by default for ZTS builds on
Linux.
Uses of traits with static properties
Uses of traits with static properties will now redeclare static properties
inherited from the parent class. This will create a separate static
property storage for the current class. This is analogous to adding the
static property to the class directly without traits.
Assigning a negative index to an empty array
Assigning a negative index $n to an empty array will now make sure that the
next index is $n+1 instead of 0.
Class constant visibility variance check
Class constant visibility variance is now correctly checked when inherited
from interfaces.
WeakMap entries whose key maps to itself
WeakMap entries whose key maps to itself (possibly
transitively) may now be removed during cycle collection if the key is not
reachable except by iterating over the WeakMap (reachability via iteration is
considered weak).
Previously, such entries would never be automatically removed.
Date
The DateTime extension has introduced Date extension specific exceptions
and errors under the DateError and
DateException hierarchies, instead of warnings and
generic exceptions. This improves error handling, at the expense
of having to check for errors and exceptions.
DOM
Calling DOMChildNode::after,
DOMChildNode::before,
DOMChildNode::replaceWith
on a node that has no parent is now a no-op instead of a hierarchy
exception, which is the behaviour demanded by the DOM specification.
Using the DOMParentNode
and DOMChildNode methods without a document now
works instead of throwing a DOM_HIERARCHY_REQUEST_ERR
DOMException.
This is in line with the behaviour demanded by the DOM specification.
Calling DOMDocument::createAttributeNS without specifying
a prefix would incorrectly create a default namespace, placing the element
inside the namespace instead of the attribute. This bug is now fixed.
DOMDocument::createAttributeNS would previously
incorrectly throw a DOM_NAMESPACE_ERRNAMESPACE_ERR
DOMException when the prefix was already used for a
different URI. It now correctly chooses a different prefix when there's a
prefix name conflict.
New methods and properties were added to some DOM classes.
If a userland class inherits from these classes and declare a method or property
with the same name, the declarations must be compatible. Otherwise, a typical
compile error about incompatible declarations will be thrown.
See the list of new features
and new functions for
a list of the newly implemented methods and properties.
FFI
C functions that have a return type of void now return instead of
returning the following object object(FFI\CData:void) { }
Opcache
The opcache.consistency_checks
INI directive was removed. This feature was broken with the tracing JIT,
as well as with inheritance cache, and has been disabled without a way to
enable it since PHP 8.1.18 and PHP 8.2.5.
Both the tracing JIT and inheritance cache may modify shm after the script
has been persisted by invalidating its checksum. The attempted fix skipped
over the modifiable pointers but was rejected due to complexity. For this
reason, it was decided to remove the feature instead.
Phar
The type of Phar class constants are now declared.
Standard
The range function has had various changes:
A TypeError is now thrown when passing objects,
resources, or arrays as the boundary inputs.
A more descriptive ValueError is thrown when
passing 0 for $step.
A ValueError is now thrown when using a
negative $step for increasing ranges.
If $step is a float that can be interpreted
as an int, it is now done so.
A ValueError is now thrown if any argument
is infinity or NAN.
An E_WARNING is now emitted if
$start or $end is the empty
string. The value continues to be cast to the value 0.
An E_WARNING is now emitted if
$start or $end has more than
one byte, only if it is a non-numeric string.
An E_WARNING is now emitted if
$start or $end is cast to an
integer because the other boundary input is a number.
(e.g. range(5, 'z');).
An E_WARNING is now emitted if
$step is a float when trying to generate a range of
characters, except if both boundary inputs are numeric strings (e.g.
range('5', '9', 0.5); does not produce a warning).
range now produce a list of characters if one
of the boundary inputs is a string digit instead of casting the other input
to int (e.g. range('9', 'A');).
<?php
range('9', 'A'); // ["9", ":", ";", "<", "=", ">", "?", "@", "A"], as of PHP 8.3.0
range('9', 'A'); // [9, 8, 7, 6, 5, 4, 3, 2, 1, 0], prior to PHP 8.3.0
?>
number_format now handles negative
$decimals values by rounding
$num to abs($decimals) digits before the
decimal point. Previously, negative $decimals values
were ignored.
The file flags error check now catches all invalid flags.
Notably FILE_APPEND was previously silently accepted.
SNMP
The type of SNMP class constants are now declared.
Other Changes
Core changes
FFI
FFI::load is now allowed during preloading
when opcache.preload_user
is the current system user. Previously,
calling FFI::load was not possible
during preloading if the
opcache.preload_user
directive was set.
FPM
FPM CLI test now fails if the socket path is longer than supported by the OS.
Opcache
In the CLI and phpdbg SAPIs, preloading does not require the
opcache.preload_user
directive to be set anymore when running as root.
In other SAPIs, this directive is required when running as root because
preloading is done before the SAPI switches to an unprivileged user.
Streams
Blocking fread on a socket connection returns
immediately if there are any buffered data instead of waiting for more data.
A memory stream no longer fails if the seek offset is past the end.
Instead, the memory will be increased on the next write and the data between
the old end and the offset is filled with zero bytes, similar to how files work.
stat access operations like
file_exists and similar will now use real
path instead of the actual stream path. This is consistent with stream
opening.
Changes in SAPI Modules
CLI
The STDOUT, STDERR and
STDIN streams are no longer closed on resource
destruction which is mostly when the CLI finishes.
It is however still possible to explicitly close those streams using
fclose and similar.
Changed Functions
Core
gc_status has added the following 8 fields:
"running" => bool
"protected" => bool
"full" => bool
"buffer_size" => int
"application_time" => float: Total application
time, in seconds (including collector_time)
"collector_time" => float: Time spent collecting
cycles, in seconds (including destructor_time and free_time)
"destructor_time" => float: Time spent executing
destructors during cycle collection, in seconds
"free_time" => float: Time spent freeing values
during cycle collection, in seconds
class_alias now supports creating an alias of an
internal class.
Setting open_basedir at runtime
using ini_set('open_basedir', ...); no longer accepts paths
containing the parent directory (..). Previously,
only paths starting with .. were disallowed. This could
easily be circumvented by prepending ./ to the path.
User exception handlers now catch exceptions during shutdown.
The resultant HTML of highlight_string and
highlight_file has changed.
Whitespace between outer HTML tags is removed. Newlines and spaces
are no longer converted to HTML entities. The whole HTML is now wrapped in a
<pre> tag. The outer <span>
tag has been merged with the <code> tag.
Calendar
easter_date now supports years from 1970 to
2,000,000,000 on 64-bit systems, previously it only supported years in the
range from 1970 to 2037.
Curl
curl_getinfo now supports two new constants:
CURLINFO_CAPATH and
CURLINFO_CAINFO. If option is , the following
two additional keys are present:
"capath" and "cainfo".
DOM
Changed DOMCharacterData::appendData tentative
return type to true.
DOMDocument::loadHTML,
DOMDocument::loadHTMLFile, and
DOMDocument::loadXML now have a tentative
return type of bool. Previously, this was documented as having a return
type of DOMDocument|bool, but, as of PHP 8.0.0,
DOMDocument
cannot be returned as it is no longer statically callable.
Gd
The signature of imagerotate has changed.
The $ignore_transparent parameter has been removed,
as it was ignored since PHP 5.5.0.
Intl
datefmt_set_timezone (and its alias
IntlDateformatter::setTimeZone)
now returns on success, previously was returned.
IntlBreakiterator::setText now returns
on failure, previously was returned.
It now returns on success, previously was returned.
IntlChar::enumCharNames is now returning a boolean.
Previously it returned on success and on failure.
IntlDateFormatter::__construct throws an U_ILLEGAL_ARGUMENT_ERROR
exception when an invalid locale had been set.
MBString
mb_strtolower and mb_convert_case
implement conditional casing rules for the Greek letter sigma.
For mb_convert_case,
conditional casing only applies to MB_CASE_LOWER
and MB_CASE_TITLE modes, not to
MB_CASE_LOWER_SIMPLE and
MB_CASE_TITLE_SIMPLE.
mb_decode_mimeheader interprets underscores in
QPrint-encoded MIME encoded words as required by RFC 2047; they are
converted to spaces.
Underscores must be encoded as "=5F" in such MIME
encoded words.
In rare cases, mb_encode_mimeheader will transfer-encode
its input string where it would pass it through as raw ASCII in PHP 8.2.
mb_encode_mimeheader no longer drops NUL (zero)
bytes when QPrint-encoding the input string.
This previously caused strings in certain text encodings, especially
UTF-16 and UTF-32, to be corrupted by mb_encode_mimeheader.
mb_detect_encoding's "non-strict" mode now behaves
as described in the documentation.
Previously, it would return if the same byte (for example, the first
byte) of the input string was invalid in all candidate encodings.
More generally, it would eliminate candidate encodings from consideration
when an invalid byte was seen, and if the same input byte eliminated all
remaining encodings still under consideration, it would return .
On the other hand, if all candidate encodings but one were eliminated
from consideration, it would return the last remaining one without regard
for how many encoding errors might be encountered later in the string.
This is different from the behavior described in the documentation, which
says: "If strict is set to false, the closest matching encoding will be
returned."
mysqli
mysqli_fetch_object now raises a
ValueError instead of an Exception
when the $constructor_args argument is non empty with
the class not having constructor.
mysqli_poll now raises a ValueError
when neither the $read
nor the $error arguments are passed.
mysqli_field_seek and
mysqli_result::field_seek now specify the return
type as true instead of bool.
ODBC
odbc_autocommit now accepts for the
$enable parameter.
Passing has the same behaviour as passing only 1 parameter,
namely indicating if the autocommit feature is enabled or not.
PGSQL
pg_fetch_object now raises a
ValueError instead of an Exception
when the $constructor_args argument is non empty with
the class not having constructor.
pg_insert now raises a ValueError
instead of a E_WARNING when the table specified is invalid.
pg_insert and pg_convert raises
a ValueError or a TypeError
instead of a E_WARNING when the value/type of a field
does not match properly with a PostgreSQL's type.
The $row parameter of
pg_fetch_result,
pg_field_prtlen, and
pg_field_is_null is now nullable.
Random
Changed mt_srand and srand to
not check the number of arguments to determine whether a random seed should
be used. Passing will generate a random seed, 0
will use zero as the seed. The functions are now consistent with
Random\Engine\Mt19937::__construct.
Reflection
Return type of ReflectionClass::getStaticProperties
is no longer nullable.
Standard
E_NOTICEs emitted by unserialize
have been promoted to E_WARNING.
unserialize now emits a new E_WARNING
if the input contains unconsumed bytes.
array_pad is now only limited by the maximum number of
elements an array can have. Before, it was only possible to add at most 1048576
elements at a time.
strtok raises an E_WARNING in the
case token is not provided when starting tokenization.
password_hash will now chain the underlying
Random\RandomException
as the ValueError's $previous
Exception when salt generation fails.
If using an array as the $command
for proc_open, it must now have at least one
non empty element. Otherwise a ValueError
is thrown.
proc_open returns if $command
array is invalid command instead of resource object that produces warning later.
This was already the case for Windows but it is now also the case if a posix_spawn
implementation is in use (most Linux, BSD and MacOS platforms). There are still
some old platforms where this behavior is not changed as posix_spawn is not
supported there.
array_sum and array_product now
warn when values in the array cannot be converted to int/float.
Previously arrays and objects where ignored whilst every other value was
cast to int. Moreover, objects that define a numeric cast (e.g.
GMP) are now casted instead of ignored.
The $decimals of number_format
now properly handles negative integers.
Rounding with a negative value for $decimals means
that $num is rounded to $decimals
significant digits before the decimal point.
Previously negative $decimals were silently
ignored and the number got rounded to zero decimal places.
A new $before_needle argument has been added to
strrchr. It behaves like its counterpart in the
strstr or stristr functions.
str_getcsv and fgetcsv now return
an empty string instead of a string with a single null byte for the last field
which only contains an unterminated enclosure.
Other Changes to Extensions
Core
Using the increment/decrement
operators (++/--) on values of type
bool now emit warnings.
This is because it currently has no effect, but will behave like
$bool += 1 in the future.
Using the decrement
operator (--) on values of type null now emit warnings.
This is because it currently has no effect, but will behave like
$null -= 1 in the future.
Internal objects that implement an _IS_NUMBER cast but not a do_operator
handler that overrides addition and subtraction now can be incremented
and decrement as if one would do $o += 1 or $o -= 1
DOM
The DOM lifetime mechanism has been reworked such that implicitly removed
nodes can still be fetched. Previously this resulted in an exception.
SQLite3
The SQLite3 class now throws
SQLite3Exception (extends
Exception) instead of Exception.
The SQLite error code is now passed in the exception error code instead of
being included in the error message.
Changes to INI File Handling
The assert.* INI settings have been deprecated.
This comprises the following INI settings:
assert.active
assert.bail
assert.callback
assert.exception
assert.warning
If the value of the setting is equal to the default value, no deprecation
notice is emitted.
The zend.assertions INI setting
should be used instead.
zend.max_allowed_stack_size
is a new INI directive to set the maximum allowed stack size.
Possible values are 0 (detect the process or thread maximum stack size),
-1 (no limit), or a positive number of bytes.
The default is 0.
When it is not possible to detect the process or thread maximum stack
size, a known system default is used.
Setting this value too high has the same effect as disabling the stack size limit.
Fibers use
fiber.stack_size
as maximum allowed stack size.
An Error is thrown when the process call stack exceeds
zend.max_allowed_stack_size-zend.reserved_stack_size
bytes, to prevent stack-overflow-induced segmentation faults, with
the goal of making debugging easier.
The stack size increases during uncontrolled recursions involving internal functions
or the magic methods
__toString(),
__clone(),
__sleep(),
__destruct().
This is not related to stack buffer overflows, and is not a security feature.
zend.reserved_stack_size
is a new INI directive to set the reserved stack size, in bytes.
This is subtracted from the max allowed stack size,
as a buffer, when checking the stack size.
Performance
DOM
Looping over a DOMNodeList now uses caching. Therefore
requesting items no longer takes quadratic time by default.
Getting text content from nodes now avoids an allocation, resulting in a
performance gain.
DOMChildNode::remove now runs in O(1) performance.
Standard
The file flags error check is now about 7% faster.
SPL
RecursiveDirectoryIterator now performs less I/O
when looping over a directory.
New Features
PHP Core
Readonly Amendments
Anonymous classes may now be marked as readonly.
Readonly properties can now be reinitialized during cloning.
Typed Class Constants
Class, interface, trait, and enum constants now support type declarations.
Closures created from magic methods
Closures created from magic methods can now accept named arguments.
The final modifier with a method from a trait
The final modifier may now be used when using a method from a trait.
Override Attribute
Added the #[\Override] attribute to check that a method exists in a parent
class or implemented interface.
Fetch class constant dynamically syntax
Class constants can now be accessed dynamically using the
C::{$name} syntax.
Static variable Initializers
Static variable initializers can now contain arbitrary expressions.
Fallback value syntax for ini variables
php.ini now supports fallback/default value syntax.
<?php
/*
On /path/to/user.ini contains the following settings:
listen = localhost:${DRUPAL_FPM_PORT:-9000}
*/
$user_ini = parse_ini_file('/path/to/user.ini');
echo $user_ini['listen']; // localhost:9000
CLI
It is now possible to lint multiple files.
DOM
Added properties DOMElement::$className
and DOMElement::$id.
These are not binary-safe at the moment because of underlying limitations
of libxml2.
This means that the property values will be cut off at a NUL byte.
Added properties DOMNode::$isConnected
and DOMNameSpaceNode::$isConnected.
Added properties DOMNode::$parentElement
and DOMNameSpaceNode::$parentElement.
FFI
It is now possible to assign FFI\CData to other FFI\CData.
Meaning CData can now be assigned to structs and fields.
Opcache
opcache_get_status()['scripts'][n]['revalidate'] now contains
a Unix timestamp of when the next revalidation of the scripts timestamp is
due, dictated by the
opcache.revalidate_freq
INI directive.
POSIX
posix_getrlimit now takes an optional
$resource parameter to allow fetching a single resource limit.
posix_isatty now raises type warnings for integers
following the usual ZPP semantics.
posix_ttyname now raises type warnings for integers
following the usual ZPP semantics and value warnings for invalid file
descriptor integers.
Streams
Streams can now emit the STREAM_NOTIFY_COMPLETED
notification. This was previously not implemented.
Deprecated Features
PHP Core
Saner Increment/Decrement operators
Using the increment
operator (++) on empty, non-numeric,
or non-alphanumeric strings is now deprecated.
Moreover, incrementing non-numeric strings is soft deprecated.
That means no E_DEPRECATED diagnostic is emitted,
but this feature should not be used when producing new code.
The new str_increment function should be used instead.
Using the decrement
operator (--) on empty or non-numeric strings is now deprecated.
get_class()/get_parent_class() call without arguments
Calling get_class and get_parent_class
without arguments is now deprecated.
DBA
Calling dba_fetch with $dba as
the 3rd argument is now deprecated.
FFI
Calling FFI::cast, FFI::new,
and FFI::type statically is now deprecated.
Intl
The U_MULTIPLE_DECIMAL_SEP*E*RATORS
constant had been deprecated, using the
U_MULTIPLE_DECIMAL_SEP*A*RATORS
constant instead is recommended.
The NumberFormatter::TYPE_CURRENCY constant has been deprecated.
LDAP
Calling ldap_connect with separate
$hostname and $port is
deprecated.
MBString
Passing a negative $width to
mb_strimwidth is now deprecated.
Phar
Calling Phar::setStub with a
resource and a $length
is now deprecated. Such calls should be replaced by:
$phar->setStub(stream_get_contents($resource));
Random
The MT_RAND_PHP Mt19937 variant is deprecated.
Reflection
Calling ReflectionProperty::setValue with only one
parameter is deprecated.
To set static properties, pass as the first parameter.
Standard
The assert_options function is now deprecated.
The ASSERT_ACTIVE, ASSERT_BAIL,
ASSERT_CALLBACK, ASSERT_EXCEPTION,
and ASSERT_WARNING constants have been deprecated.
The assert.* INI settings have been deprecated.
See the
Changes to INI File Handling
page for further details.
SQLite3
Using exceptions is now preferred, warnings will be removed in the future.
Calling SQLite3::enableExceptions(false) will trigger a
deprecation warning in this version.
Zip
The ZipArchive::FL_RECOMPRESS constant is deprecated
and will be removed in a future version of libzip.
Windows Support
Core
Building with Visual Studio now requires at least Visual Studio 2019.
However, Visual Studio 2022 is recommended.
AVX(2) CPU support is now properly detected for MSVC builds.
Native AVX-512 builds are now supported via the
--enable-native-intrinsics=avx512
configure option.
New Classes, Enums, and Interfaces
Core
BCMath
DBA
DOM
ODBC
PCNTL
PDO_DBLIB
PDO_FIREBIRD
PDO_MYSQL
PDO_ODBC
PDO_PGSQL
PDO_SQLITE
Reflection
SOAP
Standard
New Functions
Core
BCMath
Date
DOM
Hash
Intl
MBString
Opcache
PCNTL
PDO_PGSQL
PGSQL
Reflection
The following methods relate to the new lazy object feature:
ReflectionClass::newLazyGhost
ReflectionClass::newLazyProxy
ReflectionClass::resetAsLazyGhost
ReflectionClass::resetAsLazyProxy
ReflectionClass::isUninitializedLazyObject
ReflectionClass::initializeLazyObject
ReflectionClass::markLazyObjectAsInitialized
ReflectionClass::getLazyInitializer
ReflectionProperty::skipLazyInitialization
ReflectionProperty::setRawValueWithoutLazyInitialization
Sodium
SPL
SOAP
Standard
Tidy
XMLReader
XMLWriter
XSL
Removed Extensions
These extensions have been moved to PECL and are no longer part of the PHP
distribution. New releases for the PECL packages will be published on an
ad-hoc basis according to user demand.
New Global Constants
Core
cURL
Intl
LDAP
libxml
MySQLi
OpenSSL
PCNTL
PGSQL
POSIX
Sockets
The following socket options are now defined if they are supported:
Sodium
Tokenizer
XML
Backward Incompatible Changes
Although not explicitly stated in this section,
every new function,
class, interface, enum,
or constant
may cause a redeclaration Error to be thrown.
PHP Core
exit behavioral change
The exit (and die) language
constructs now behave more like a function.
This means that they can now be passed like callables,
are affected by the strict_types declare statement,
and now perform the usual type coercions instead of casting any non-integer
value to a string.
As such, passing invalid types to exit and
die now consistently result in a
TypeError being thrown.
Recursion during comparison
Encountering recursion during comparison now results in an
Error exception instead of a
E_ERROR fatal error.
Indirect Modification of readonly Properties
Indirect modification of readonly properties within __clone()
is no longer allowed, e.g. $ref = &$this->readonly.
This was already forbidden for readonly initialization, and was an
oversight in the "readonly reinitialization during cloning" implementation.
Type Change of Constants
The PHP_DEBUG and PHP_ZTS
constants are now of type bool.
Previously they were of type int.
Temporary Filename Length
The name of uploaded files and files created by the
tempnam function are now 13 bytes longer.
The total length is still platform-dependent.
Removal of E_STRICT error level
The E_STRICT error level has been removed,
as it was no longer in use within the PHP engine.
The E_STRICT constant has been deprecated.
Extension Class Constants which are now Typed
The following extension class constants now declare a type on their
constants:
Date
Intl
PDO
Reflection
SPL
Sqlite
XMLReader
Resource to Object Migration
Several s have been migrated to s.
Return value checks using is_resource should be
replaced with checks for , unless specified otherwise.
DBA
The DBA functions now accept and return
Dba\Connection objects instead of
dba_connection s.
ODBC
The ODBC functions now accept and return
Odbc\Result objects instead of
odbc_result s.
The ODBC functions now accept and return
Odbc\Connection objects instead of
odbc_connection s.
SOAP
The SoapClient::$httpurl property is now a
Soap\Url object rather than a
soap_url .
Checks using is_resource (i.e.
is_resource($client->httpurl)) should be replaced with checks
for (i.e. $client->httpurl !== null).
The SoapClient::$sdl property is now a
Soap\Sdl object rather than a
soap_sdl .
Checks using is_resource (i.e.
is_resource($client->sdl)) should be replaced with checks
for (i.e. $client->sdl !== null).
New warnings and exceptions
New warnings and exceptions have been added which are triggered on
programming errors, i.e. invalid values provided as arguments.
Curl
curl_multi_select now throws a
ValueError if the
timeout parameter is less than
0 or greater than PHP_INT_MAX.
Gd
imagejpeg
imagewebp
imagepng
imageavif
now throw a ValueError when an invalid
quality is passed.
imageavif will now throw a
ValueError if an invalid
speed parameter value is passed.
imagescale will now throw a
ValueError if the
width or height
parameters underflows/overflows.
imagescale will now throw a
ValueError if an invalid
mode parameter value is passed.
imagefilter will now throw a
ValueError with the
IMG_FILTER_SCATTER filter
if the sub or plus
parameters underflows/overflows.
Gettext
bind_textdomain_codeset
textdomain
d*gettext
now throw a ValueError if
domain is the empty string.
Intl
resourcebundle_get,
ResourceBundle::get, and accessing offsets on
a ResourceBundle object now throw:
TypeError for invalid offset types
ValueError for an empty
ValueError if the integer index does
not fit in a signed 32 bit integer
IntlDateFormatter::__construct throws a
ValueError if the
locale is invalid.
NumberFormatter::__construct throws a
ValueError if the
locale is invalid.
MBString
mb_encode_numericentity and
mb_decode_numericentity now check that the
map is only composed of s,
if not a ValueError is now thrown.
mb_http_input now always throw a
ValueError if type
is invalid.
mb_http_output now check that the
encoding does not contain any null bytes,
if it does a ValueError is now thrown.
ODBC
odbc_fetch_row returns when
row is less than or equal to 0.
A warning is now emitted in this case.
PCNTL
The pcntl_sigprocmask,
pcntl_sigwaitinfo, and
pcntl_sigtimedwait functions now throw:
A ValueError if the
signals array is empty
(except for pcntl_sigprocmask if the
mode SIG_SETMASK)
A TypeError if a value of the
signals array is not an
A ValueError if a value of the
signals array is not a valid signal number
The pcntl_sigprocmask function now throws a
ValueError if the
mode is not one of SIG_BLOCK,
SIG_UNBLOCK, or SIG_SETMASK.
The pcntl_sigtimedwait function now throw:
A ValueError if
seconds is less than 0
A ValueError if
nanoseconds is less than 0
or greater than 1e9
A ValueError if both
seconds and nanoseconds
are 0
Session
Setting a non-positive value for session.gc_divisor
or a negative value for session.gc_probability
now emits a warning.
SimpleXML
Calling simplexml_import_dom with a non-XML object
now throws a TypeError instead of a
ValueError.
Standard
The round function now validates the value of the
mode and throw a
ValueError for invalid modes.
Previously, invalid modes would have been interpreted as
PHP_ROUND_HALF_UP.
The str_getcsv now throws
ValueErrors when the
separator and enclosure
arguments are not one byte long, or if the escape
argument is not one byte long nor the empty string.
This aligns the behaviour to be identical to the one of
fputcsv and fgetcsv.
The php_uname function now throws a
ValueError if the
mode is invalid.
The "allowed_classes" option for
unserialize now throws
TypeErrors and
ValueErrors if it is not an
array of class names.
XMLReader
Passing an invalid character encoding to
XMLReader::open or
XMLReader::XML now throws a
ValueError.
Passing a containing null bytes previously emitted a
warning and now throws a ValueError.
XMLWriter
Passing a containing null bytes previously emitted a
warning and now throws a ValueError.
XSL
XSLTProcessor::setParameter will now throw a
ValueError when its arguments contain null
bytes. This never actually worked correctly in the first place,
which is why it throws an exception now.
Calling XSLTProcessor::importStyleSheet with a
non-XML object now throws a TypeError
instead of a ValueError.
Failure to call a PHP function callback during evaluation now throws
instead of emitting a warning.
Date
number symbols in relative formats
once again accept multiple signs, e.g. +-2.
DOM
Some DOM methods previously returned or a
DOMException with code
DOM_PHP_ERR if a new node could not be allocated.
They now consistently throw a DOMException
with code DOM_INVALID_STATE_ERR.
This situation is extremely unlikely and the probability of being affected
is low.
As a result DOMImplementation::createDocument
now has a tentative return type of DOMDocument
instead of DOMDocument|false.
Previously, DOMXPath objects could be cloned,
but resulted in an unusable object.
This is no longer possible, and cloning a DOMXPath
object now throws an Error.
The DOMImplementation::getFeature method has been removed.
GMP
The GMP class is now final and cannot be extended
anymore.
MBString
On invalid strings (those with encoding errors),
mb_substr now interprets character indices in the same
manner as most other mbstring functions.
This means that character indices returned by mb_strpos
can be passed to mb_substr.
For SJIS-Mac (MacJapanese) strings, character indices passed to
mb_substr now refer to the indices of the Unicode
codepoints which are produced when the string is converted to Unicode.
This is significant because around 40 SJIS-Mac characters convert to a
sequence of multiple Unicode codepoints.
MySQLi
The unused and undocumented constant
MYSQLI_SET_CHARSET_DIR has been removed.
The MYSQLI_STMT_ATTR_PREFETCH_ROWS constant has been
removed. The feature is unavailable with mysqlnd.
The MYSQLI_CURSOR_TYPE_FOR_UPDATE and
MYSQLI_CURSOR_TYPE_SCROLLABLE constants have been
removed. This functionality was never implemented,
neither with mysqlnd nor with libmysql.
The unused MYSQLI_TYPE_INTERVAL constant, which is
currently a stub and an alias for MYSQLI_TYPE_ENUM,
has been removed.
MySQLnd
The error code reported for MySQL server wait timeouts has been changed from
2006 to 4031 for MySQL server
versions 8.0.24 and above.
Opcache
The maximum value of the
opcache.interned_strings_buffer
setting on 64bit architectures is now 32767.
Previously it was 4095.
JIT
The default configuration values for the JIT changed from
opcache.jit=tracing
and opcache.jit_buffer_size=0
to opcache.jit=disable
and opcache.jit_buffer_size=64M, respectively.
This does not affect the default observable behavior,
as the JIT is still disabled by default.
However, it is now disabled through the
opcache.jit setting,
rather than
opcache.jit_buffer_size.
This may affect users who previously enabled JIT through
opcache.jit_buffer_size
exclusively, without also specifying a JIT mode using
opcache.jit.
To enable JIT compilation, set the
opcache.jit config value accordingly.
If JIT compilation is enabled, PHP will now exit with a fatal error on
startup if the initialization of the JIT compiler failed for any reason.
PCNTL
The pcntl_sigprocmask,
pcntl_sigwaitinfo, and
pcntl_sigtimedwait functions now always
return on failure.
In some case previously it could return the value -1.
PCRE
The bundled pcre2lib has been updated to version 10.44.
As a consequence, this means {,3} is now recognized
as a quantifier instead of as text.
Furthermore, the meaning of some character classes in UCP mode has changed.
Consult the PCRE2 Changelog
for a full changelog.
PDO_DBLIB
The Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER and
Pdo\Dblib::ATTR_DATETIME_CONVERT attributes now act as
boolean attributes instead of integer attributes.
Thus setting the attribute via PDO::setAttribute
and retrieving it via PDO::getAttribute expects
and or return a bool.
PDO_FIREBIRD
The PDO::ATTR_AUTOCOMMIT attribute now act as
boolean attributes instead of integer attributes.
Thus setting the attribute via PDO::setAttribute
and retrieving it via PDO::getAttribute expects
and or return a bool.
The extension now exposes some Firebird C++ APIs,
therefore building this extension now requires a C++ compiler.
Moreover, the extension must now be compiled against fbclient 3.0 or higher.
PDO_MYSQL
The PDO::ATTR_AUTOCOMMIT,
PDO::ATTR_EMULATE_PREPARES, and
PDO::MYSQL_ATTR_DIRECT_QUERY attributes now act as
boolean attributes instead of integer attributes.
Thus setting the attribute via PDO::setAttribute
and retrieving it via PDO::getAttribute expects
and or return a bool.
PDO_PGSQL
The DSN's credentials, when set, are given priority over their PDO
constructor counterparts, being closer to the documentation states.
SimpleXML
SimpleXMLElement is not only a representation of an
XML element, but it is also a RecursiveIterator.
Prior to PHP 8.4.0, some of its methods (e.g.
SimpleXMLElement::asXML or
SimpleXMLElement::getName) and casting such
instances to would implicitly reset the iterator.
This could cause unexpected infinite loops as the iterator was rewound.
For example:
<?php
$xmlString = "<root><a><b>1</b><b>2</b><b>3</b></a></root>";
$xml = simplexml_load_string($xmlString);
$nodes = $xml->a->b;
foreach ($nodes as $nodeData) {
echo "nodeData: " . $nodeData . "\n";
$xml = $nodes->asXml();
}
would result in an infinite loop.
nodeData: 1
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
// ...
However, this behavior has now been corrected, and a
SimpleXMLElement will no longer implicitly reset
the iterator data, unless explicitly rewound.
Meaning the previous example would now result in:
nodeData: 1
nodeData: 2
nodeData: 3
would result in an infinite loop.
However, this behavior has now been corrected, and a
SimpleXMLElement will no longer implicitly reset
the iterator data, unless explicitly rewound.
Meaning the previous example would now result in:
SOAP
SoapClient::$typemap is now an array
rather than a resource.
Checks using is_resource (i.e.
is_resource($client->typemap)) should be
replaced with checks for (i.e. $client->typemap !== null).
The SOAP extension gained an optional dependency on the
session extension.
If PHP is built without the session extension and with the
--enable-rtld-now configure flag enabled,
startup errors will now occur if the SOAP
extension is also used.
To solve this either don't use rtld-now or load the session extension.
Standard
When using strcspn with
characters being the empty string,
the length of the string is now returned instead of incorrectly stopping
at the first null byte.
http_build_query now correctly handles backed enums.
stream_bucket_make_writeable and
stream_bucket_new will now return a
StreamBucket instance instead of an instance of
stdClass.
Tidy
Failures in the constructor now throw exceptions rather than emitting
warnings and having a broken object.
XML
The xml_set_*_handler
functions now declare and check for an effective
signature of callablestringnull for the
handler parameters.
Moreover, values of type string that correspond to method names,
of object set with xml_set_object are now checked to
see if the method exists on the class of the previously passed object.
This means that xml_set_object must now always be
called prior to setting method names as callables.
Passing an empty string to disable the handler is still allowed,
but deprecated.
However, as xml_set_object and passing
non-callable strings is deprecated.
It is recommended to change such instances with a callable
referring to the method directly.
Other Changes
Core changes
Closures
Closure names have been adjusted to include the parent function's name
and the line of definition to make them easier to distinguish, for example
within stack traces.
Fibers
Fiber switching during destructor execution is now allowed. It was previously
blocked due to conflicts with garbage collection.
Destructors may now be executed in a separate Fiber:
When garbage collection is triggered in a Fiber,
destructors called by the GC are executed in a separate Fiber:
the gc_destructor_fiber.
If this Fiber suspends, a new one is created to execute the remaining
destructors.
The previous gc_destructor_fiber is not referenced anymore by the GC
and may be collected if it's not referenced anywhere else.
Objects whose destructor is suspended will not be collected until the
destructor returns or the Fiber is collected.
Output Handlers
Output handler status flags passed to the flags
parameter of ob_start are now cleared.
output_add_rewrite_var now uses
url_rewriter.hosts
instead of
session.trans_sid_hosts
for selecting hosts that will be rewritten.
Changes in SAPI Modules
apache2handler
Support for EOL Apache 2.0 and 2.2 has been removed.
Minimum required Apache version is now 2.4.
CLI
The builtin server looks for an index file recursively by traversing parent
directories in case the specified file cannot be located.
This process was previously skipped if the path looked like it was
referring to a file, i.e. if the last path component contained a period.
In that case, a 404 error was returned.
The behavior has been changed to look for an index file in all cases.
FPM
Flushing headers without a body will now succeed.
Status page has a new field to display a memory peak.
The /dev/poll events.mechanism
setting for Solaris/Illumos had been retired.
Changed Functions
Core
trigger_error and user_error
now have a return type of true instead of bool.
DOM
DOMDocument::registerNodeClass
now has a tentative return type of true instead of
bool.
It could only ever return in practice.
Hash
hash_update
now has a tentative return type of true instead of
bool.
It could only ever return in practice.
Intl
NumberFormatter::ROUND_TOWARD_ZERO and
NumberFormatter::ROUND_AWAY_FROM_ZERO
have been added as aliases for
NumberFormatter::ROUND_DOWN and
NumberFormatter::ROUND_UP
to be consistent with the new
PHP_ROUND_* modes.
ResourceBundle::get
now has a tentative return type of ResourceBundle|array|string|int|null.
The idn_to_ascii and idn_to_utf8
functions now always throw ValueErrors
if the domain name is empty or too long.
The idn_to_ascii and idn_to_utf8
functions now always throw ValueError
if the variant parameter is not
INTL_IDNA_VARIANT_UTS46.
LibXML
libxml_set_streams_context now immediately throws a
TypeError when a non-stream-context
resource is passed to the function,
instead of throwing later when the stream context is used.
MBString
The behavior of mb_strcut is more consistent
now on invalid UTF-8 and UTF-16 strings.
There is no behavioural change for valid UTF-8 and UTF-16 strings.
ODBC
The row of
odbc_fetch_object,
odbc_fetch_array, and
odbc_fetch_into now have a default value of ,
consistent with odbc_fetch_row.
Previously, the default values were
-1,
-1,
and 0,
respectively.
OpenSSL
The extra_attributes in
openssl_csr_new sets the CSR
attributes instead of subject DN, which incorrectly done previously.
The dn in
openssl_csr_new allows setting an array
of values for a single entry.
New serial_hex added to
openssl_csr_sign to allow setting serial numbers
in the hexadecimal format.
Parsing ASN.1 UTCTime with openssl_x509_parse
fails if seconds are omitted for OpenSSL version below 3.2
(-1 is returned for such fields).
OpenSSL version above 3.3 did not load such certificates already.
PDO
It is now possible to fetch the value of the
PDO::ATTR_STRINGIFY_FETCHES attribute with
PDO::getAttribute.
A new PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE
has been added to retrieve the memory usage of query results with
PDO::getAttribute for drivers that support it.
PDO_FIREBIRD
It is now possible to fetch the value of the
FB_ATTR_DATE_FORMAT,
FB_ATTR_TIME_FORMAT,
FB_ATTR_TIMESTAMP_FORMAT,
attributes with
PDO::getAttribute.
Added new attributes to specify transaction isolation level and access mode.
Five constants relating to this functionality have been added:
Pdo\Firebird::TRANSACTION_ISOLATION_LEVEL
Pdo\Firebird::READ_COMMITTED
Pdo\Firebird::REPEATABLE_READ
Pdo\Firebird::SERIALIZABLE
Pdo\Firebird::WRITABLE_TRANSACTION
When using persistent connections, there is now a liveliness check in the
constructor.
The content that is built changes depending on the value of
FB_API_VER in
ibase.h.
A new static method Pdo\Firebird::getApiVersion
can be used to obtain this information.
This information is also now referenced in phpinfo.
Five new data types are now available:
INT128
DEC16
DEC34
TIMESTAMP_TZ
TIME_TZ
.
These are available starting with Firebird 4.0.
PDO_MYSQL
It is now possible to fetch the value of the
PDO::ATTR_FETCH_TABLE_NAMES attribute with
PDO::getAttribute.
PDO_PGSQL
Support retrieving the memory usage of queries for
PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE.
If the column is of type FLOAT4OID or
FLOAT8OID the value will now be returned as a
float instead of a string.
PGSQL
The conditions parameter of
pg_select is now optional and accepts an empty array.
Phar
The
Phar::setAlias
Phar::setDefaultStub
methods now have a tentative return type of true
instead of bool.
POSIX
posix_isatty now sets the error number when the
file descriptor/stream argument is invalid.
Reflection
ReflectionGenerator::getFunction
may now be called after the generator finished executing.
Sockets
The backlog parameter of
socket_create_listen now has a default value of
SOMAXCONN.
Previously, it was 128.
Sodium
The sodium_crypto_aead_aes256gcm_*
functions are now available on aarch64 CPUs with the ARM cryptographic
extensions.
SPL
The
SplPriorityQueue::insert
SplPriorityQueue::recoverFromCorruption
SplHeap::insert
SplHeap::recoverFromCorruption
methods now have a tentative return type of true
instead of bool.
SplObjectStorage now implements
SeekableIterator.
Standard
The default 'cost' value for the PASSWORD_BCRYPT
hashing algorithm for password_hash has been increased from
10 to 12.
debug_zval_dump now indicates whether an array is packed.
long2ip now has a return type of string
instead of string|false.
highlight_string now has a return type of
string|true instead of string|bool.
print_r now has a return type of
string|true instead of string|bool.
Rounding with round
The mode parameter of the
round function has been widened to
RoundingMode|int,
accepting instances of a new RoundingMode enum.
Four new modes have been added to the round function:
RoundingMode::PositiveInfinity
RoundingMode::NegativeInfinity
RoundingMode::TowardsZero
RoundingMode::AwayFromZero
The internal implementation for rounding to integers has been rewritten
to be easier to verify for correctness and to be easier to maintain.
Some rounding bugs have been fixed as a result of the rewrite.
For example previously rounding 0.49999999999999994
to the nearest integer would have resulted in 1.0
instead of the correct result 0.0.
Additional inputs might also be affected and result in different outputs
compared to earlier PHP versions.
Fixed a bug caused by "pre-rounding" of the round function.
Previously, using "pre-rounding" to treat a value like 0.285
(actually 0.28499999999999998) as a decimal number
and round it to 0.29.
However, "pre-rounding" incorrectly rounds certain numbers,
so this fix removes "pre-rounding" and changes the way numbers are compared,
so that the values are correctly rounded as decimal numbers.
The maximum precision that can be handled by round
has been extended by one digit.
For example, round(4503599627370495.5) returned in
4503599627370495.5,
but now returns 4503599627370496.
Other Changes to Extensions
cURL
The minimum libcurl version required is now 7.61.0.
The CURLOPT_DNS_USE_GLOBAL_CACHE option no longer
has any effect, and is silently ignored.
This underlying feature was deprecated in libcurl 7.11.1,
and removed in libcurl 7.62.0.
GMP
Casting a GMP object to bool is now
possible instead of emitting a E_RECOVERABLE_ERROR.
The casting behaviour is overloaded such that a GMP
object representing the value 0 is cast to .
LibXML
The minimum libxml2 version required is now 2.9.4.
Intl
The behaviour of Intl class has been normalized to always throw
Error exceptions when attempting to use
a non-initialized object, or when cloning fails.
MBString
Unicode data tables have been updated to Unicode 16.0.
MySQLnd
Support for the new VECTOR data type from MySQL 9.
OpenSSL
The minimum OpenSSL version required is now 1.1.1.
PDO_PGSQL
The minimum libpq version required is now 10.0.
PGSQL
The minimum libpq version required is now 10.0.
SPL
Out of bounds accesses in SplFixedArray now throw
exceptions of type OutOfBoundsException
instead of RuntimeException.
Because OutOfBoundsException is a child
class of RuntimeException no behavioural
changes are exhibited when attempting to catch those exceptions.
XSL
The typed properties XSLTProcessor::$cloneDocument
and XSLTProcessor::$doXInclude are now declared.
Zlib
The minimum zlib version required is now 1.2.11.
Performance
Core
Improved the performance of floating point number parsing and formatting in
ZTS builds under highly concurrent loads.
This affects the printf family of functions as well
as serialization functions such as json_encode,
or serialize.
sprintf using only %s and
%d specifiers will be compiled into the equivalent
string interpolation, avoiding the overhead of a function call and
repeatedly parsing the format string.
BCMath
Improved performance of number conversions and operations.
DOM
The performance of DOMNode::C14N is greatly
improved for the case without an xpath query.
This can give a time improvement of easily two order of
magnitude for documents with tens of thousands of nodes.
Improved performance and reduce memory consumption of XML serialization.
Reduced memory usage of node classes.
FTP
Improved the performance of FTP uploads up to a factor of 10x for large
uploads.
Hash
Added SSE2 and SHA-NI implementations of SHA-256.
This improves the performance on supported CPUs by ~1.3x (SSE2),
and 3x - 5x (SHA-NI).
Credit to Colin Percival / Tarsnap for this optimization.
MBString
mb_strcut is much faster now for UTF-8
and UTF-16 strings.
Looking up mbstring encoding names is much faster now.
The performance of converting SJIS-win to Unicode is greatly improved.
MySQLnd
Improved the performance of MySQLnd quoting.
PCRE
Improved the performance of named capture groups.
Random
Improved the performance of Random\Randomizer,
with a specific focus on the
Random\Randomizer::getBytes,
and Random\Randomizer::getBytesFromString methods.
SimpleXML
Improved performance and reduce memory consumption of XML serialization.
Standard
The performance of strspn and
strcspn is greatly improved.
They now run in linear time instead of being bounded by quadratic time.
Improved the performance of strpbrk.
get_browser is much faster now,
up to 1.5x - 2.5x for some test cases.
New Features
PHP Core
Property Hooks
Object properties may now have additional logic associated with their
get and set operations.
Depending on the usage, that may or may not make the property virtual,
that is, it has no backing value at all.
Asymmetric Property Visibility
Object properties may now have their set visibility
controlled separately from the get visibility.
Lazy Objects
It is now possible to create objects whose initialization is deferred until
they are accessed. Libraries and frameworks can leverage these lazy objects
to defer fetching data or dependencies required for initialization.
#[\Deprecated] attribute
The new Deprecated attribute can be used to mark functions, methods,
and class constants as deprecated. The behavior of functionality deprecated with this
attribute matches the behavior of the existing deprecation mechanism for functionality
provided by PHP itself. The only exception is that the emitted error code is
E_USER_DEPRECATED instead of E_DEPRECATED.
Existing deprecations in functionality provided by PHP itself have been updated to use
the attribute, improving the emitted error messages by including a short explanation.
Parsing RFC1867 (multipart) requests in non-POST HTTP requests
Added request_parse_body function that allows parsing
RFC1867 (multipart) requests in non-POST HTTP requests.
Chaining expressions without parentheses
New expressions with constructor arguments are now dereferencable, meaning
they allow chaining method calls, property accesses, etc. without enclosing
the expression in parentheses.
Improved Debugging Info for WeakReference
Getting the debug info for WeakReference will now
also output the object it references, or if the reference is no
longer valid.
Improved Debugging Info for Closure
The output of Closure::__debugInfo now includes
the name, file, and line of the Closure.
Defining Identical Symbols in Different Namespace Blocks
Exiting a namespace now clears seen symbols.
This allows using a symbol in a namespace block, even if a previous
namespace block declared a symbol with the same name.
cURL
curl_version returns an additional
feature_list value, which is an associative array
of all known cURL features, and whether they are supported ()
or not ().
Added CURL_HTTP_VERSION_3 and
CURL_HTTP_VERSION_3ONLY constants (available
since libcurl 7.66 and 7.88) as available options for
CURLOPT_HTTP_VERSION.
Added CURLOPT_PREREQFUNCTION as a cURL option that
accepts a callable to be called after the connection is made,
but before the request is sent.
This callable must return either CURL_PREREQFUNC_OK or
CURL_PREREQFUNC_ABORT to allow or abort the request.
Added CURLOPT_SERVER_RESPONSE_TIMEOUT,
which was formerly known as CURLOPT_FTP_RESPONSE_TIMEOUT.
Both constants hold the same value.
Added CURLOPT_DEBUGFUNCTION as a cURL option that
accepts a callable that gets called during the request lifetime
with the CurlHandle object,
an integer containing the debug message type, and a string containing the
debug message.
The debug message type is one of the following constants:
CURLINFO_TEXT
CURLINFO_HEADER_IN
CURLINFO_HEADER_OUT
CURLINFO_DATA_IN
CURLINFO_DATA_OUT
CURLINFO_SSL_DATA_IN
CURLINFO_SSL_DATA_OUT
Once this option is set, CURLINFO_HEADER_OUT
must not be set because it uses the same libcurl functionality.
The curl_getinfo now returns an additional
posttransfer_time_us key, containing the number of
microseconds from the start until the last byte is sent.
When a redirect is followed, the time from each request is added together.
This value can also be retrieved by passing
CURLINFO_POSTTRANSFER_TIME_T to the
curl_getinfo option parameter.
This requires libcurl 8.10.0 or later.
DOM
Added the Dom namespace with new classes as counterparts
to the existing DOM classes (e.g. Dom\Node is the new
DOMNode).
These classes are compatible with HTML 5 and are WHATWG spec-compliant;
solving long-standing bugs in the DOM extension.
The old DOM classes remain available for backwards compatibility.
Added the DOMNode::compareDocumentPosition
with its associated constants:
DOMNode::DOCUMENT_POSITION_DISCONNECTED
DOMNode::DOCUMENT_POSITION_PRECEDING
DOMNode::DOCUMENT_POSITION_FOLLOWING
DOMNode::DOCUMENT_POSITION_CONTAINS
DOMNode::DOCUMENT_POSITION_CONTAINED_BY
DOMNode::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
It is now possible to pass any callable to
DOMXPath::registerPhpFunctions.
Furthermore, with DOMXPath::registerPhpFunctionNs,
callbacks can now be registered that will use native function call syntax
rather than using php:function('name').
Intl
Added the NumberFormatter::ROUND_HALFODD to
complement the existing NumberFormatter::ROUND_HALFEVEN
functionality.
OpenSSL
Added support for Curve25519 + Curve448 based keys.
Specifically x25519, ed25519, x448 and ed448 fields are supported in
openssl_pkey_new,
openssl_pkey_get_details,
openssl_sign, and
openssl_verify were extended to support those keys.
Implement PASSWORD_ARGON2 password hashing.
Requires OpenSSL 3.2 and NTS build.
PCRE
The bundled pcre2lib has been updated to version 10.44.
As a consequence, LoongArch JIT support has been added, spaces
are now allowed between braces in Perl-compatible items, and
variable-length lookbehind assertions are now supported.
With pcre2lib version 10.44, the maximum length of named capture groups
has changed from 32 to 128.
Added support for the r (PCRE2_EXTRA_CASELESS_RESTRICT)
modifier, as well as the (?r) mode modifier.
When enabled along with the case-insensitive modifier (i),
the expression locks out mixing of ASCII and non-ASCII characters.
PDO
Added support for driver-specific subclasses in order to better support
database-specific functionalities.
The new classes are instantiatable either via calling the
PDO::connect method or by instantiating one
of the driver-specific subclasses directly.
Added support for driver specific SQL parsers.
When a driver-specific parser is not available, the default parser is used.
The default parser supports:
single and double-quoted literals, with doubling as escaping mechanism
two-dashes and non-nested C-style comments
PDO_MYSQL
Added a custom parser supporting:
single and double-quoted literals, with doubling and backslash as escaping
mechanism
backtick literal identifiers and with doubling as escaping mechanism
two dashes followed by at least 1 whitespace, non-nested C-style comments,
and hash-comments
PDO_PGSQL
Added a custom parser supporting:
single and double-quoted literals, with doubling as escaping mechanism
C-style "escape" string literals (E'string')
dollar-quoted string literals
two-dashes and C-style comments (non-nested)
support for ?? as escape sequence for the
? operator
PDO_SQLITE
Added a custom parser supporting:
single, double-quoted, and backtick literals, with doubling as
escaping mechanism
square brackets quoting for identifiers
two-dashes and C-style comments (non-nested)
Phar
Added support for the Unix timestamp extension for Zip archives.
Readline
Added ability to change the .php_history path through
the PHP_HISTFILE environment variable.
Reflection
ReflectionAttribute now contains a
name property to improve the debugging experience.
ReflectionClassConstant::__toString and
ReflectionProperty::__toString now returns the
attached doc comments.
Multiple new methods and constants which are related to the lazy objects
feature have been added:
ReflectionClass::newLazyGhost
ReflectionClass::newLazyProxy
ReflectionClass::resetAsLazyGhost
ReflectionClass::resetAsLazyProxy
ReflectionClass::isUninitializedLazyObject
ReflectionClass::initializeLazyObject
ReflectionClass::markLazyObjectAsInitialized
ReflectionClass::getLazyInitializer
ReflectionProperty::skipLazyInitialization
ReflectionProperty::setRawValueWithoutLazyInitialization
ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE
ReflectionClass::SKIP_DESTRUCTOR
SOAP
Added support for clark notation for namespaces in class map.
It is now possible to specify entries in a class map with clark notation
to resolve a type with a specific namespace to a specific class.
For example: '{http://example.com}foo' => 'FooClass'.
Instances of DateTimeInterface that are
passed to xsd:datetime or similar elements are now
serialized as such instead of being serialized as an empty string.
Session persistence now works with a shared session module.
Standard
Added a new RoundingMode enum with clearer naming
and improved discoverability compared to the
PHP_ROUND_* constants.
Moreover, four new rounding modes were added which are only available via
the new RoundingMode enum.
XSL
It is now possible to use parameters that contain both single and double
quotes.
It is now possible to pass any callable to
XSLTProcessor::registerPhpFunctions.
Added XSLTProcessor::$maxTemplateDepth and
XSLTProcessor::$maxTemplateVars
to control the recursion depth of XSL template evaluation.
Zip
Added the ZipArchive::ER_TRUNCATED_ZIP
constant, which was added in libzip 1.11.
Deprecated Features
PHP Core
Implicitly nullable parameter
A parameter's type is implicitly widened to accept null
if the default value for it is .
The following code:
<?php
function foo(T1 $a = null) {}
should be converted to:
<?php
function foo(T1|null $a = null) {}
or
<?php
function foo(?T1 $a = null) {}
However, if such a parameter declaration is followed by a mandatory
parameter:
<?php
function foo(T1 $a, T2 $b = null, T3 $c) {}
It must be converted to:
<?php
function foo(T1 $a, T2|null $b, T3 $c) {}
or
<?php
function foo(T1 $a, ?T2 $b, T3 $c) {}
as optional parameter before required ones are deprecated.
Raising zero to the power of negative number
Raising a number to the power of a negative number is equivalent to taking
the reciprocal of the number raised to the positive opposite of the power.
That is, 10-2 is the same as
1 / 102.
Therefore raising 0 to the power of a negative number
corresponds to dividing by 0, i.e.
0-2 is the same as
1 / 02, or
1 / 0. Thus, this behavior has been deprecated.
This affects the exponentiation operator **
and the pow function.
If the IEEE 754 semantics are desired one should use the new
fpow function.
Using underscore _ as class name
Naming a class _ is now deprecated:
<?php
class _ {}
Classes whose names start with an underscore are not
deprecated:
<?php
class _MyClass {}
Using trigger_error with
E_USER_ERROR
Calling trigger_error with
error_level being equal to
E_USER_ERROR is now deprecated.
Such usages should be replaced by either throwing an exception,
or calling exit, whichever is more appropriate.
The E_STRICT constant
Because the E_STRICT error level was removed,
this constant is now deprecated.
cURL
The CURLOPT_BINARYTRANSFER constant is now deprecated.
Date
The DatePeriod::__construct(string $isostr, int $options = 0)
signature has been deprecated.
Use DatePeriod::createFromISO8601String instead.
The SUNFUNCS_RET_TIMESTAMP,
SUNFUNCS_RET_STRING,
and SUNFUNCS_RET_DOUBLE constants are now deprecated.
This follows from the deprecation of the date_sunset and
date_sunrise functions in PHP 8.1.0.
DBA
Passing or to dba_key_split is now
deprecated.
It would always return in those cases.
DOM
The DOM_PHP_ERR constant is now deprecated.
The following properties have been formally deprecated:
DOMDocument::$actualEncoding
DOMDocument::$config
DOMEntity::$actualEncoding
DOMEntity::$encoding
DOMEntity::$version
Hash
Passing invalid options to hash functions is now deprecated.
Intl
Calling intlcal_set or
IntlCalendar::set
with more than two arguments is deprecated.
Use either IntlCalendar::setDate or
IntlCalendar::setDateTime instead.
Calling intlgregcal_create_instance or
IntlGregorianCalendar::__construct
with more than two arguments is deprecated.
Use either IntlGregorianCalendar::createFromDate or
IntlGregorianCalendar::createFromDateTime instead.
LDAP
Calling ldap_connect
with more than two arguments is deprecated.
Use ldap_connect_wallet instead.
Calling ldap_exop
with more than four arguments is deprecated.
Use ldap_exop_sync instead.
MySQLi
The mysqli_ping function and
mysqli::ping method
are now deprecated as the reconnect feature was removed in PHP 8.2.0.
The mysqli_kill function and
mysqli::kill method
are now deprecated.
If this functionality is needed a SQL KILL command
can be used instead.
The mysqli_refresh function and
mysqli::refresh method
are now deprecated.
If this functionality is needed a SQL FLUSH command
can be used instead.
All MYSQLI_REFRESH_*
constants have been deprecated as well.
Passing the mode parameter to
mysqli_store_result explicitly has been deprecated.
As the MYSQLI_STORE_RESULT_COPY_DATA constant was
only used in conjunction with this function it has also been deprecated.
PDO_PGSQL
Using escaped question marks (??) inside
dollar-quoted strings is deprecated.
Because PDO_PGSQL now has its own SQL parser with dollar-quoted strings
support, it is no longer necessary to escape question marks inside them.
PGSQL
The 2 arguments signature of pg_fetch_result,
pg_field_prtlen, and
pg_field_is_null is now deprecated.
Use the 3 arguments signature with row set to
instead.
Random
lcg_value is now deprecated,
as the function is broken in multiple ways.
Use Random\Randomizer::getFloat instead.
Reflection
Calling ReflectionMethod::__construct
with one arguments is deprecated.
Use ReflectionMethod::createFromMethodName instead.
Session
Calling session_set_save_handler
with more than two arguments is deprecated.
Use the two arguments signature instead.
Changing the value of the
session.sid_length and
session.sid_bits_per_character
INI settings is deprecated.
Update the session storage backend to accept 32 character hexadecimal
session IDs and stop changing these two INI settings instead.
Changing the value of the
session.use_only_cookies,
session.use_trans_sid,
session.trans_sid_tags,
session.trans_sid_hosts, and
session.referer_check
INI settings is deprecated.
The SID constant is also deprecated.
SOAP
Passing an int to
SoapServer::addFunction is now deprecated.
If all PHP functions need to be provided flatten the array returned by
get_defined_functions.
The SOAP_FUNCTIONS_ALL constant is now deprecated.
SPL
The SplFixedArray::__wakeup method is now
deprecated, as it implements
SplFixedArray::__serialize and
SplFixedArray::__unserialize
which need to be overwritten instead.
Using the default value for the escape parameter for the
SplFileObject::setCsvControl,
SplFileObject::fputcsv, and
SplFileObject::fgetcsv is now deprecated.
It must be passed explicitly either positionally or via named arguments.
This does not apply to SplFileObject::fputcsv
and SplFileObject::fgetcsv if
SplFileObject::setCsvControl was used to set a
new default value.
Standard
Calling stream_context_set_option
with two arguments is deprecated.
Use stream_context_set_options instead.
Unserializing strings using the uppercase S tag
with unserialize is deprecated.
Using the default value for the escape parameter for the
fputcsv,
fgetcsv, and
str_getcsv is now deprecated.
It must be passed explicitly either positionally or via named arguments.
XML
The xml_set_object function has been deprecated.
Passing non-callable strings to the
xml_set_*
functions is now deprecated.
New functions
Closure
Closure::call
CSPRNG
random_bytes
random_int
Error Handling and Logging
error_clear_last
Generator
Generator::getReturn
GNU Multiple Precision
gmp_random_seed
Math
intdiv
PCRE
preg_replace_callback_array
PHP Options/Info
gc_mem_caches
get_resources
POSIX
posix_setrlimit
Reflection
ReflectionParameter::getType
ReflectionParameter::hasType
ReflectionFunctionAbstract::getReturnType
ReflectionFunctionAbstract::hasReturnType
Zip
ZipArchive::setCompressionIndex
ZipArchive::setCompressionName
Zlib Compression
inflate_add
deflate_add
inflate_init
deflate_init
Removed Extensions and SAPIs
Removed Extensions
ereg
mssql
mysql
sybase_ct
Removed SAPIs
aolserver
apache
apache_hooks
apache2filter
caudium
continuity
isapi
milter
nsapi
phttpd
pi3web
roxen
thttpd
tux
webjames
New Classes and Interfaces
Intl
IntlChar
Reflection
ReflectionGenerator
ReflectionType
Session Handling
SessionUpdateTimestampHandlerInterface
Exception Hierarchy
Throwable
Error
TypeError
ParseError
AssertionError
ArithmeticError
DivisionByZeroError
Changes in SAPI Modules
FPM
Unqualified listen ports now listen on both
IPv4 and IPv6
In PHP 5, a listen directive with only a
port number would listen on all interfaces, but only on IPv4. PHP 7 will
now accept requests made via both IPv4 and IPv6.
This does not affect directives which include specific IP addresses; these
will continue to only listen on that address and protocol.
New Global Constants
Core Predefined Constants
PHP_INT_MIN
GD
IMG_WEBP (as of PHP 7.0.10)
JSON
JSON_ERROR_INVALID_PROPERTY_NAME
JSON_ERROR_UTF16
LibXML
LIBXML_BIGLINES
PCRE
PREG_JIT_STACKLIMIT_ERROR
POSIX
POSIX_RLIMIT_AS
POSIX_RLIMIT_CORE
POSIX_RLIMIT_CPU
POSIX_RLIMIT_DATA
POSIX_RLIMIT_FSIZE
POSIX_RLIMIT_LOCKS
POSIX_RLIMIT_MEMLOCK
POSIX_RLIMIT_MSGQUEUE
POSIX_RLIMIT_NICE
POSIX_RLIMIT_NOFILE
POSIX_RLIMIT_NPROC
POSIX_RLIMIT_RSS
POSIX_RLIMIT_RTPRIO
POSIX_RLIMIT_RTTIME
POSIX_RLIMIT_SIGPENDING
POSIX_RLIMIT_STACK
POSIX_RLIMIT_INFINITY
Zlib
ZLIB_ENCODING_RAW
ZLIB_ENCODING_DEFLATE
ZLIB_ENCODING_GZIP
ZLIB_FILTERED
ZLIB_HUFFMAN_ONLY
ZLIB_FIXED
ZLIB_RLE
ZLIB_DEFAULT_STRATEGY
ZLIB_BLOCK
ZLIB_FINISH
ZLIB_FULL_FLUSH
ZLIB_NO_FLUSH
ZLIB_PARTIAL_FLUSH
ZLIB_SYNC_FLUSH
Backward incompatible changes
Other Changes
Loosening Reserved Word Restrictions
Globally reserved words as property, constant, and method names within classes,
interfaces, and traits are now allowed. This reduces the surface of BC breaks
when new keywords are introduced and avoids naming restrictions on APIs.
This is particularly useful when creating internal DSLs with fluent interfaces:
The only limitation is that the class keyword still
cannot be used as a constant name, otherwise it would conflict with the
class name resolution syntax (ClassName::class).
Removal of date.timezone Warning
Previously, a warning was emitted if the
date.timezone INI setting had not
been set prior to using any date- or time-based functions. Now, this warning
has been removed (with
date.timezone still defaulting to
UTC).
New features
Scalar type declarations
Scalar
type declarations
come in two flavours: coercive (default) and strict. The following types
for parameters can now be enforced (either coercively or strictly): strings
(string), integers (int), floating-point
numbers (float), and booleans (bool). They
augment the other types introduced in PHP 5: class names, interfaces,
array and callable.
To enable strict mode, a single directive must be placed at the
top of the file. This means that the strictness of typing for scalars is
configured on a per-file basis. This directive not only affects the type
declarations of parameters, but also a function's return type (see
return type declarations,
built-in PHP functions, and functions from loaded
extensions.
Full documentation and examples of scalar type declarations can be found in
the
type declaration
reference.
Return type declarations
PHP 7 adds support for
return type declarations.
Similarly to
argument type declarations,
return type declarations specify the type of the value that will be
returned from a function. The same
types
are available for return type declarations as are available for argument
type declarations.
Full documentation and examples of return type declarations can be found in
the
return type declarations.
reference.
Null coalescing operator
The null coalescing operator (??) has been added as
syntactic sugar for the common case of needing to use a ternary in
conjunction with isset. It returns its first operand
if it exists and is not ; otherwise it returns its second operand.
Spaceship operator
The spaceship operator is used for comparing two expressions. It returns -1, 0
or 1 when $a is respectively less than, equal to, or greater
than $b. Comparisons are performed according to PHP's usual
type comparison rules.
Constant arrays using define
Array constants can now be defined with
define. In PHP 5.6, they could only be defined with
.
Anonymous classes
Support for anonymous classes has been added via new
class. These can be used in place of full class definitions for
throwaway objects:
Full documentation can be found in the
anonymous class reference.
Unicode codepoint escape syntax
This takes a Unicode codepoint in hexadecimal form, and outputs that
codepoint in UTF-8 to a double-quoted string or a heredoc. Any valid
codepoint is accepted, with leading 0's being optional.
Closure::call
Closure::call is a more performant, shorthand way
of temporarily binding an object scope to a closure and invoking it.
Filtered unserialize
This feature seeks to provide better security when unserializing objects on
untrusted data. It prevents possible code injections by enabling the
developer to whitelist classes that can be unserialized.
IntlChar
The new IntlChar class seeks to expose additional
ICU functionality. The class itself defines a number of static methods and
constants that can be used to manipulate unicode characters.
In order to use this class, the Intl extension must be installed.
Expectations
Expectations are a
backwards compatible enhancement to the older assert
function. They allow for zero-cost assertions in production code, and
provide the ability to throw custom exceptions when the assertion fails.
While the old API continues to be maintained for compatibility,
assert is now a language construct, allowing the first
parameter to be an expression rather than just a string to be
evaluated or a bool value to be tested.
Full details on this feature, including how to configure it in both
development and production environments, can be found on the manual page
of the assert language construct.
Group use declarations
Classes, functions and constants being imported from the same
can now be grouped together in a single statement.
Generator Return Expressions
This feature builds upon the generator functionality introduced into PHP 5.5.
It enables for a return statement to be used within a
generator to enable for a final expression to be returned (return by
reference is not allowed). This value can be fetched using the new
Generator::getReturn() method, which may only be used
once the generator has finished yielding values.
Being able to explicitly return a final value from a generator is a handy
ability to have. This is because it enables for a final value to be returned
by a generator (from perhaps some form of coroutine computation) that can be
specifically handled by the client code executing the generator. This is far
simpler than forcing the client code to firstly check whether the final
value has been yielded, and then if so, to handle that value specifically.
Generator delegation
Generators can now delegate to another generator,
Traversable object or array
automatically, without needing to write boilerplate in the outermost
generator by using the construct.
Integer division with intdiv
The new intdiv function performs an integer division
of its operands and returns it.
Session options
session_start now accepts an array of
options that override the
session configuration directives
normally set in php.ini.
These options have also been expanded to support
session.lazy_write, which is
on by default and causes PHP to only overwrite any session file if the
session data has changed, and read_and_close, which is
an option that can only be passed to session_start to
indicate that the session data should be read and then the session should
immediately be closed unchanged.
For example, to set
session.cache_limiter to
private and immediately close the session after reading
it:
preg_replace_callback_array
The new preg_replace_callback_array function enables
code to be written more cleanly when using the
preg_replace_callback function. Prior to PHP 7,
callbacks that needed to be executed per regular expression required the
callback function to be polluted with lots of branching.
Now, callbacks can be registered to each regular expression using an
associative array, where the key is a regular expression and the value is a
callback.
CSPRNG Functions
Two new functions have been added to generate cryptographically secure
integers and strings in a cross platform way:
random_bytes and random_int.
list can always unpack objects implementing
ArrayAccess
Previously, list was not guaranteed to operate
correctly with objects implementing ArrayAccess.
This has been fixed.
Other Features
Class member access on cloning has been added,
e.g. (clone $foo)-bar().
Changed functions
PHP Core
debug_zval_dump now prints "int" instead of "long",
and "float" instead of "double"
dirname now optionally takes a second parameter,
depth, to get the name of the directory
depth levels up from the current directory.
getrusage is now supported on Windows.
mktime and gmmktime functions
no longer accept is_dst parameter.
preg_replace function no longer supports
"\e" (PREG_REPLACE_EVAL). preg_replace_callback
should be used instead.
setlocale function no longer accepts category
passed as string. LC_* constants must be used instead.
exec, system and passthru
functions have NULL byte protection now.
shmop_open now returns a resource instead of an int,
which has to be passed to shmop_size,
shmop_write, shmop_read,
shmop_close and shmop_delete.
substr and iconv_substr now return an empty string,
if string is equal to start characters long.
xml_parser_free is no longer sufficient to free the
parser resource, if it references an object and this object references that
parser resource. In this case it is necessary to additionally unset the $parser.
Deprecated features in PHP 7.0.x
PHP 4 style constructors
PHP 4 style constructors (methods that have the same name as the class they
are defined in) are deprecated, and will be removed in the future. PHP 7
will emit E_DEPRECATED if a PHP 4 constructor is the
only constructor defined within a class. Classes that implement a
__construct method are unaffected.
Static calls to non-static methods
Static calls to methods that
are not declared static are deprecated, and may be
removed in the future.
password_hash salt option
The salt option for the password_hash function has been
deprecated to prevent developers from generating their own (usually insecure)
salts. The function itself generates a cryptographically secure salt when no
salt is provided by the developer - therefore custom salt generation should not
be needed.
capture_session_meta SSL context option
The capture_session_meta SSL context option has been
deprecated. SSL metadata is now available through the
stream_get_meta_data function.
LDAP deprecations
The following function has been deprecated:
ldap_sort
Other backward incompatible changes
New objects cannot be assigned by reference
The result of the statement can no longer be assigned to a variable
by reference:
Invalid class, interface and trait names
The following names cannot be used to name classes, interfaces or traits:
bool
int
float
string
Furthermore, the following names should not be used. Although they will not
generate an error in PHP 7.0, they are reserved for future use and should
be considered deprecated.
resource
object
mixed
numeric
ASP and script PHP tags removed
Support for using ASP and script tags to delimit PHP code has been removed.
The affected tags are:
Removed ASP and script tags
Calls from incompatible context removed
Previously deprecated in PHP 5.6,
static calls made to a non-static method with an incompatible context will
now result in the called method having an undefined
$this variable and a deprecation warning being issued.
is now a right associative operator
The construct no longer requires parentheses, and has been changed
to a right associative operator with precedence between
print and =. This can result in
changed behaviour:
Parentheses can be used to disambiguate those cases.
Functions cannot have multiple parameters with the same name
It is no longer possible to define two or more function parameters with the
same name. For example, the following function will trigger an
E_COMPILE_ERROR:
Functions inspecting arguments report the current parameter value
func_get_arg, func_get_args,
debug_backtrace and exception backtraces will no longer
report the original value that was passed to a parameter, but will instead
provide the current value (which might have been modified).
Switch statements cannot have multiple default blocks
It is no longer possible to define two or more default blocks in a switch
statement. For example, the following switch statement will trigger an
E_COMPILE_ERROR:
$HTTP_RAW_POST_DATA removed
$HTTP_RAW_POST_DATA is no longer available. The
php://input
stream should be used instead.
# comments in INI files removed
Support for prefixing comments with # in INI files has been
removed. ; (semi-colon) should be used instead. This change
applies to , as well as files handled by
parse_ini_file and parse_ini_string.
JSON extension replaced with JSOND
The JSON extension has been replaced with JSOND, causing three minor BC
breaks. Firstly, a number must not end in a decimal point (i.e.
34. must be changed to either 34.0 or
34). Secondly, when using scientific notation, the
e exponent must not immediately follow a decimal point
(i.e. 3.e3 must be changed to either
3.0e3 or 3e3).
Finally, an empty string is no longer considered valid JSON.
Internal function failure on overflow
Previously, internal functions would silently truncate numbers produced from
float-to-integer coercions when the float was too large to represent as an
integer. Now, an E_WARNING will be emitted and will be returned.
Fixes to custom session handler return values
Any predicate functions implemented by custom session handlers that return
either or -1 will be fatal errors. If any value
from these functions other than a boolean, -1, or
0 is returned, then it will fail and an E_WARNING will be
emitted.
Sort order of equal elements
The internal sorting algorithm has been improved, what may result in
different sort order of elements, which compare as equal, than before.
Don't rely on the order of elements which compare as equal; it might change
anytime.
Misplaced break and continue statements
break and continue statements outside of
a loop or switch control structure are now detected at
compile-time instead of run-time as before, and trigger an
E_COMPILE_ERROR.
Constant disallowed as break and continue argument
break and continue statements no longer
allow their argument to be a constant, and trigger a
E_COMPILE_ERROR.
Mhash is not an extension anymore
The Mhash extension has been fully integrated into the Hash extension. Therefore, it is no longer
possible to detect Mhash support with extension_loaded;
use function_exists instead. Furthermore, Mhash is no
longer reported by get_loaded_extensions and related
features.
declare(ticks)
The declare(ticks)
directive does no longer leak into different compilation units.
Changes to string handling
Hexadecimal strings are no longer considered numeric
Strings containing hexadecimal numbers are no longer considered to be
numeric. For example:
filter_var can be used to check if a
string contains a hexadecimal number, and also to convert a
string of that type to an int:
\u{ may cause errors
Due to the addition of the new
Unicode codepoint escape syntax,
strings containing a literal \u{ followed by an invalid
sequence will cause a fatal error. To avoid this, the leading backslash
should be escaped.
Changes to
Minor changes have been made to the behaviour of the control
structure, primarily around the handling of the internal array pointer and
modification of the array being iterated over.
no longer changes the internal array pointer
Prior to PHP 7, the internal array pointer was modified while an array was
being iterated over with . This is no longer the case, as shown
in the following example:
by-value operates on a copy of the array
When used in the default by-value mode, will now operate on a
copy of the array being iterated rather than the array itself. This means
that changes to the array made during iteration will not affect the values
that are iterated.
by-reference has improved iteration behaviour
When iterating by-reference, will now do a better job of
tracking changes to the array made during iteration. For example,
appending to an array while iterating will now result in the appended
values being iterated over as well:
Iteration of non-Traversable objects
Iterating over a non-Traversable object will now
have the same behaviour as iterating over by-reference arrays. This
results in the
improved behaviour when modifying an array during iteration
also being applied when properties are added to or removed from the
object.
Changes to variable handling
PHP 7 now uses an abstract syntax tree when parsing source files. This has
permitted many improvements to the language which were previously
impossible due to limitations in the parser used in earlier versions of
PHP, but has resulted in the removal of a few special cases for consistency
reasons, which has resulted in backward compatibility breaks. These cases
are detailed in this section.
Changes to the handling of indirect variables, properties, and methods
Indirect access to variables, properties, and methods will now be
evaluated strictly in left-to-right order, as opposed to the previous mix
of special cases. The table below shows how the order of evaluation has
changed.
Old and new evaluation of indirect expressions
Expression
PHP 5 interpretation
PHP 7 interpretation
$$foo['bar']['baz']
${$foo['bar']['baz']}
($$foo)['bar']['baz']
$foo->$bar['baz']
$foo->{$bar['baz']}
($foo->$bar)['baz']
$foo->$bar['baz']()
$foo->{$bar['baz']}()
($foo->$bar)['baz']()
Foo::$bar['baz']()
Foo::{$bar['baz']}()
(Foo::$bar)['baz']()
Old and new evaluation of indirect expressions
Code that used the old right-to-left evaluation order must be rewritten to
explicitly use that evaluation order with curly braces (see the above
middle column). This will make the code both forwards compatible with PHP
7.x and backwards compatible with PHP 5.x.
This also affects the keyword. The curly brace syntax can be
used to emulate the previous behaviour if required:
Changes to list handling
list no longer assigns variables in reverse order
list will now assign values to variables in the
order they are defined, rather than reverse order. In general, this only
affects the case where list is being used in
conjunction with the array [] operator, as shown below:
In general, it is recommended not to rely on the order in which
list assignments occur, as this is an implementation
detail that may change again in the future.
Empty list assignments have been removed
list constructs can no longer be empty. The following
are no longer allowed:
list cannot unpack strings
list can no longer unpack string
variables. str_split should be used instead.
Array ordering when elements are automatically created during by reference
assignments has changed
The order of the elements in an array has changed when those elements have
been automatically created by referencing them in a by reference
assignment. For example:
Parentheses around function arguments no longer affect behaviour
In PHP 5, using redundant parentheses around a function argument could
quiet strict standards warnings when the function argument was passed by
reference. The warning will now always be issued.
Removed functions
call_user_method and
call_user_method_array
These functions were deprecated in PHP 4.1.0 in favour of
call_user_func and
call_user_func_array. You may also want to consider
using
variable functions
and/or the
...
operator.
All ereg* functions
All ereg functions were removed.
PCRE is a recommended alternative.
mcrypt aliases
The deprecated mcrypt_generic_end function has been
removed in favour of mcrypt_generic_deinit.
Additionally, the deprecated mcrypt_ecb,
mcrypt_cbc, mcrypt_cfb and
mcrypt_ofb functions have been removed in favour of
using mcrypt_decrypt with the appropriate
MCRYPT_MODE_* constant.
All ext/mysql functions
All ext/mysql functions were removed. For
details about choosing a different MySQL API, see
Choosing a MySQL API.
All ext/mssql functions
All ext/mssql functions were removed.
PDO_SQLSRV
PDO_ODBC
SQLSRV
Unified ODBC API
intl aliases
The deprecated datefmt_set_timezone_id and
IntlDateFormatter::setTimeZoneID aliases have been
removed in favour of datefmt_set_timezone and
IntlDateFormatter::setTimeZone, respectively.
set_magic_quotes_runtime
set_magic_quotes_runtime, along with its alias
magic_quotes_runtime, have been removed. They were
deprecated in PHP 5.3.0, and became effectively non-functional with the
removal of magic quotes in PHP 5.4.0.
set_socket_blocking
The deprecated set_socket_blocking alias has been
removed in favour of stream_set_blocking.
dl in PHP-FPM
dl can no longer be used in PHP-FPM. It remains
functional in the CLI and embed SAPIs.
GD Type1 functions
Support for PostScript Type1 fonts has been removed from the GD extension,
resulting in the removal of the following functions:
imagepsbbox
imagepsencodefont
imagepsextendfont
imagepsfreefont
imagepsloadfont
imagepsslantfont
imagepstext
Using TrueType fonts and their associated functions is recommended instead.
Changes to error and exception handling
Many fatal and recoverable fatal errors have been converted to exceptions in
PHP 7. These error exceptions inherit from the Error
class, which itself implements the Throwable
interface (the new base interface all exceptions inherit).
This means that custom error handlers may no longer be triggered because
exceptions may be thrown instead (causing new fatal errors for uncaught
Error exceptions).
A fuller description of how errors operate in PHP 7 can be found
on the PHP 7 errors page. This
migration guide will merely enumerate the changes that affect backward
compatibility.
set_exception_handler is no longer guaranteed to
receive Exception objects
Code that implements an exception handler registered with
set_exception_handler using a type declaration of
Exception will cause a fatal error when an
Error object is thrown.
If the handler needs to work on both PHP 5 and 7, you should remove the
type declaration from the handler, while code that is being migrated to
work on PHP 7 exclusively can simply replace the
Exception type declaration with
Throwable instead.
Internal constructors always throw exceptions on failure
Previously, some internal classes would return or an unusable object
when the constructor failed. All internal classes will now throw an
Exception in this case in the same way that user
classes already had to.
Parse errors throw ParseError
Parser errors now throw a ParseError object. Error
handling for eval should now include a block
that can handle this error.
E_STRICT notices severity changes
All of the E_STRICT notices have been reclassified to
other levels. E_STRICT constant is retained, so calls like
error_reporting(E_ALL|E_STRICT) will not cause an error.
E_STRICT notices severity changes
Situation
New level/behaviour
Indexing by a resource
E_NOTICE
Abstract static methods
Notice removed, triggers no error
"Redefining" a constructor
Notice removed, triggers no error
Signature mismatch during inheritance
E_WARNING
Same (compatible) property in two used traits
Notice removed, triggers no error
Accessing static property non-statically
E_NOTICE
Only variables should be assigned by reference
E_NOTICE
Only variables should be passed by reference
E_NOTICE
Calling non-static methods statically
E_DEPRECATED
E_STRICT notices severity changes
Changes to int handling
Invalid octal literals
Previously, octal literals that contained invalid numbers were silently
truncated (0128 was taken as 012).
Now, an invalid octal literal will cause a parse error.
Negative bitshifts
Bitwise shifts by negative numbers will now throw an
ArithmeticError:
Out of range bitshifts
Bitwise shifts (in either direction) beyond the bit width of an
int will always result in 0. Previously, the behaviour of
such shifts was architecture dependent.
Changes to Division By Zero
Previously, when 0 was used as the divisor for either the divide (/) or
modulus (%) operators, an E_WARNING would be emitted and
false would be returned. Now, the divide operator
returns a float as either +INF, -INF, or NAN, as specified by IEEE 754. The modulus operator E_WARNING
has been removed and will throw a DivisionByZeroError
exception.
Removed INI directives
Removed features
The following INI directives have been removed as their associated features
have also been removed:
always_populate_raw_post_data
asp_tags
xsl.security_prefs
The xsl.security_prefs directive has been removed.
Instead, the XsltProcessor::setSecurityPrefs
method should be called to control the security preferences on a
per-processor basis.
None besides functions from the standard C library which are
always available.
Factorial function using GMP
<?php
function fact($x)
{
$return = 1;
for ($i=2; $i <= $x; $i++) {
$return = gmp_mul($return, $i);
}
return $return;
}
echo gmp_strval(fact(1000)) . "\n";
?>
Factorial function using GMP
This will calculate factorial of 1000 (pretty big number)
very fast.
As of PHP 8.1.0, crypt can be built against a system crypt library
by specifying the --with-external-libcrypt configure option.
For Argon2 password hashing, either
libargon2 is required or, as of
PHP 8.4.0, OpenSSL version 3.2 or later. As of PHP 7.3.0, libargon2 version
20161029 or later is required if libargon2 is used.
However, to enable Argon2 password hashing, PHP must be built either with
libargon2 support using the
--with-password-argon2 configure option
or, starting from PHP 8.4.0, with OpenSSL using
--with-openssl and
--with-openssl-argon2.
Prior to PHP 8.1.0, it was possible to specify the argon2 directory with
--with-password-argon2[=DIR].
Get error message from last internationalization function called.
Description of an error occurred in the last API function call.
intl_get_error_message example
<?php
if( Collator::getAvailableLocales() === false ) {
show_error( intl_get_error_message() );
}
?>
intl_get_error_message example
intl_error_name
intl_get_error_code
intl_is_failure
collator_get_error_message
numfmt_get_error_message
errorCode
is a value that returned by functions:
intl_get_error_code,
collator_get_error_code .
is a value that returned by functions:
intl_get_error_code,
collator_get_error_code .
if it the code indicates some failure, and
in case of success or a warning.
intl_is_failure example
<?php
function check( $err_code )
{
var_export( intl_is_failure( $err_code ) );
echo "\n";
}
check( U_ZERO_ERROR );
check( U_USING_FALLBACK_WARNING );
check( U_ILLEGAL_ARGUMENT_ERROR );
?>
false
false
true
intl_is_failure example
intl_get_error_code
collator_get_error_code
Collator-getErrorCode
Useful to handle errors occurred in static methods when there's no object to
get error code from.
Error code returned by the last API function call.
intl_get_error_code example
<?php
$coll = collator_create( '<bad_param>' );
if( !$coll ) {
handle_error( intl_get_error_code() );
}
?>
intl_get_error_code example
intl_is_failure
intl_error_name
intl_get_error_message
collator_get_error_code
numfmt_get_error_code
Return ICU error code name.
errorCode
ICU error code.
ICU error code.
The returned string will be the same as the name of the error code
constant.
intl_error_name example
<?php
$coll = collator_create( 'en_RU' );
$err_code = collator_get_error_code( $coll );
printf( "Symbolic name for %d is %s\n.", $err_code, intl_error_name( $err_code ) );
?>
Symbolic name for -128 is U_USING_FALLBACK_WARNING.
intl_error_name example
intl_is_failure
intl_get_error_code
intl_get_error_message
MySQL Drivers and Plugins
PHP offers several MySQL drivers and plugins for accessing and
handling MySQL.
The differences and functionality of the MySQL extensions are described
within the overview of this section.
The extensions listed support the MySQL protocol.
Examples of compatible database servers are
MariaDB Server,
MySQL Server,
Percona Server for MySQL,
and
TiDB.
Overview of the MySQL PHP drivers
Introduction
There are several PHP APIs
for accessing the MySQL database. Users can choose between the
mysqli or
PDO_MySQL extensions.
This guide explains the
terminology used to describe
each API, information about
choosing which API to
use, and also information to help choose which MySQL
library to use with
the API.
Here is a simple example PHP script using the tokenizer that
will read in a PHP file, strip all comments from the source
and print the pure code only.
Strip comments with the tokenizer
Stream Errors
As with any file or socket related function, an operation on a stream
may fail for a variety of normal reasons (i.e.: Unable to connect to remote
host, file not found, etc...). A stream related call may also fail because
the desired stream is not registered on the running system. See the array returned
by stream_get_wrappers for a list of streams supported by your
installation of PHP. As with most PHP internal functions
if a failure occurs an E_WARNING message will be generated
describing the nature of the error.
Stream Filters
A filter is a final piece of code which may perform
operations on data as it is being read from or written to a stream.
Any number of filters may be stacked onto a stream. Custom
filters can be defined in a PHP script using
stream_filter_register or in an extension.
To access the list of currently
registered filters, use stream_get_filters.
Using file_get_contents
to retrieve data from multiple sources
<?php
/* Read local file from /home/bar */
$localfile = file_get_contents("/home/bar/foo.txt");
/* Identical to above, explicitly naming FILE scheme */
$localfile = file_get_contents("file:///home/bar/foo.txt");
/* Read remote file from www.example.com using HTTP */
$httpfile = file_get_contents("http://www.example.com/foo.txt");
/* Read remote file from www.example.com using HTTPS */
$httpsfile = file_get_contents("https://www.example.com/foo.txt");
/* Read remote file from ftp.example.com using FTP */
$ftpfile = file_get_contents("ftp://user:pass@ftp.example.com/foo.txt");
/* Read remote file from ftp.example.com using FTPS */
$ftpsfile = file_get_contents("ftps://user:pass@ftp.example.com/foo.txt");
?>
Using file_get_contents
to retrieve data from multiple sources
Making a POST request to an https server
<?php
/* Send POST request to https://secure.example.com/form_action.php
* Include form elements named "foo" and "bar" with dummy values
*/
$sock = fsockopen("ssl://secure.example.com", 443, $errno, $errstr, 30);
if (!$sock) die("$errstr ($errno)\n");
$data = "foo=" . urlencode("Value for Foo") . "&bar=" . urlencode("Value for Bar");
fwrite($sock, "POST /form_action.php HTTP/1.0\r\n");
fwrite($sock, "Host: secure.example.com\r\n");
fwrite($sock, "Content-type: application/x-www-form-urlencoded\r\n");
fwrite($sock, "Content-length: " . strlen($data) . "\r\n");
fwrite($sock, "Accept: */*\r\n");
fwrite($sock, "\r\n");
fwrite($sock, $data);
$headers = "";
while ($str = trim(fgets($sock, 4096)))
$headers .= "$str\n";
echo "\n";
$body = "";
while (!feof($sock))
$body .= fgets($sock, 4096);
fclose($sock);
?>
Making a POST request to an https server
Writing data to a compressed file
<?php
/* Create a compressed file containing an arbitrary string
* File can be read back using compress.zlib stream or just
* decompressed from the command line using 'gzip -d foo-bar.txt.gz'
*/
$fp = fopen("compress.zlib://foo-bar.txt.gz", "wb");
if (!$fp) die("Unable to create file.");
fwrite($fp, "This is a test.\n");
fclose($fp);
?>
Writing data to a compressed file
Example class registered as stream wrapper
The example below implements a var:// protocol handler that allows
read/write access to a named global variable using standard filesystem
stream functions such as fread. The var:// protocol
implemented below, given the URL "var://foo" will read/write data
to/from $GLOBALS["foo"].
A Stream for reading/writing global variables
<?php
class VariableStream {
var $position;
var $varname;
function stream_open($path, $mode, $options, &$opened_path)
{
$url = parse_url($path);
$this->varname = $url["host"];
$this->position = 0;
return true;
}
function stream_read($count)
{
$ret = substr($GLOBALS[$this->varname], $this->position, $count);
$this->position += strlen($ret);
return $ret;
}
function stream_write($data)
{
$left = substr($GLOBALS[$this->varname], 0, $this->position);
$right = substr($GLOBALS[$this->varname], $this->position + strlen($data));
$GLOBALS[$this->varname] = $left . $data . $right;
$this->position += strlen($data);
return strlen($data);
}
function stream_tell()
{
return $this->position;
}
function stream_eof()
{
return $this->position >= strlen($GLOBALS[$this->varname]);
}
function stream_seek($offset, $whence)
{
switch ($whence) {
case SEEK_SET:
if ($offset < strlen($GLOBALS[$this->varname]) && $offset >= 0) {
$this->position = $offset;
return true;
} else {
return false;
}
break;
case SEEK_CUR:
if ($offset >= 0) {
$this->position += $offset;
return true;
} else {
return false;
}
break;
case SEEK_END:
if (strlen($GLOBALS[$this->varname]) + $offset >= 0) {
$this->position = strlen($GLOBALS[$this->varname]) + $offset;
return true;
} else {
return false;
}
break;
default:
return false;
}
}
function stream_metadata($path, $option, $var)
{
if($option == STREAM_META_TOUCH) {
$url = parse_url($path);
$varname = $url["host"];
if(!isset($GLOBALS[$varname])) {
$GLOBALS[$varname] = '';
}
return true;
}
return false;
}
}
stream_wrapper_register("var", "VariableStream")
or die("Failed to register protocol");
$myvar = "";
$fp = fopen("var://myvar", "r+");
fwrite($fp, "line1\n");
fwrite($fp, "line2\n");
fwrite($fp, "line3\n");
rewind($fp);
while (!feof($fp)) {
echo fgets($fp);
}
fclose($fp);
var_dump($myvar);
?>
line1
line2
line3
string(18) "line1
line2
line3
"
A Stream for reading/writing global variables
Observability
Information on installing and configuring FPM can be found in the
installation and configuration section of
the PHP manual.
This function returns a unique identifier for the current thread.
Returns the thread id as an integer.
zend_thread_id example
<?php
$thread_id = zend_thread_id();
echo 'Current thread id is: ' . $thread_id;
?>
Current thread id is: 7864
zend_thread_id example
This function is only available if PHP has been built with ZTS (Zend
Thread Safety) support and debug mode (--enable-debug).
curl_setopt
Enables the use of an abstract Unix domain socket instead of
establishing a TCP connection to a host and sets the path to
the given string. This option shares the same semantics
as CURLOPT_UNIX_SOCKET_PATH. These two options
share the same storage and therefore only one of them can be set
per handle.
Available as of PHP 7.3.0 and cURL 7.53.0.
Sets a string with the contents
of the Accept-Encoding: header sent in an HTTP request.
Set to to disable sending the Accept-Encoding: header.
Defaults to .
Available as of cURL 7.21.6.
The maximum number of milliseconds to wait for a server
to connect back to cURL when an active FTP connection is used.
This option accepts any value that can be cast to a valid int.
Defaults to 60000 milliseconds.
Available as of cURL 7.24.0.
The scope id value to use when connecting to IPv6 addresses.
This option accepts any value that can be cast to a valid int.
Defaults to 0.
Available as of cURL 7.19.0.
Pass a string with the filename for cURL to use as the Alt-Svc cache file to read existing cache contents from and
possibly also write it back to a after a transfer, unless CURLALTSVC_READONLYFILE
is set via CURLOPT_ALTSVC_CTRL.
Available as of PHP 8.2.0 and cURL 7.64.1.
Populate the bitmask with the correct set of features to instruct cURL how to handle Alt-Svc for the
transfers using this handle. cURL only accepts Alt-Svc headers over HTTPS. It will also only complete
a request to an alternative origin if that origin is properly hosted over HTTPS.
Setting any bit will enable the alt-svc engine.
Set to any of the
CURLALTSVC_* constants.
Defaults to Alt-Svc handling being disabled.
Available as of PHP 8.2.0 and cURL 7.64.1.
Setting this option to 1 will cause FTP uploads
to append to the remote file instead of overwriting it.
Defaults to 0.
Available as of cURL 7.17.0.
to automatically set the Referer: field in
requests where it follows a Location: redirect.
Defaults to 0.
Available as of cURL 7.1.0.
Provides AWS V4 signature authentication on HTTP(S) header as a string.
This option overrides any other authentication types that have been set in
CURLOPT_HTTPAUTH. This method cannot be combined with other authentication types.
Available as of PHP 8.2.0 and cURL 7.75.0.
This constant is no longer used as of PHP 5.5.0.
Deprecated as of PHP 8.4.0.
The size of the buffer to use for each read. There is no guarantee
this request will be fulfilled, however.
This option accepts any value that can be cast to a valid int.
Defaults to CURL_MAX_WRITE_SIZE (currently, 16kB).
Available as of cURL 7.10.
A string with the name of a file holding one or more certificates to verify the
peer with. This only makes sense when used in combination with
CURLOPT_SSL_VERIFYPEER. Might require an absolute path.
Available as of cURL 7.4.2.
A string with the name of a PEM file holding one or more certificates to verify the
peer with. This option overrides CURLOPT_CAINFO.
Available as of PHP 8.2.0 and cURL 7.77.0.
A string with a directory that holds multiple CA certificates.
Use this option alongside CURLOPT_SSL_VERIFYPEER.
Available as of cURL 7.9.8.
Sets the maximum time in seconds any in memory cached CA certificate store
may be kept and reused for new connections.
This option accepts any value that can be cast to a valid int.
Defaults to 86400 (24 hours).
Available as of PHP 8.3.0 and cURL 7.87.0
to output SSL certification information to STDERR
on secure transfers.
Requires CURLOPT_VERBOSE to be on to have an effect.
Defaults to .
Available as of cURL 7.19.1.
The number of seconds to wait while trying to connect. Use 0 to
wait indefinitely.
This option accepts any value that can be cast to a valid int.
Defaults to 300.
Available as of cURL 7.7.0.
The number of milliseconds to wait while trying to connect.
Use 0 to wait indefinitely.
If cURL is built to use the standard system name resolver, that
portion of the connect will still use full-second resolution for
timeouts with a minimum timeout allowed of one second.
This option accepts any value that can be cast to a valid int.
Defaults to 300000.
Available as of cURL 7.16.2.
tells the library to perform all the required proxy authentication
and connection setup, but no data transfer. This option is implemented for
HTTP, SMTP and POP3.
Defaults to .
Available as of cURL 7.15.2.
Connect to a specific host and port instead of the URL's host and port.
Accepts an array of strings with the format
HOST:PORT:CONNECT-TO-HOST:CONNECT-TO-PORT.
Available as of PHP 7.0.7 and cURL 7.49.0.
A string with the contents of the Cookie: header to be used in the HTTP request.
Note that multiple cookies are separated with a semicolon followed
by a space (e.g., fruit=apple; colour=red).
Available as of cURL 7.1.0.
A string with the name of the file containing the cookie data.
The cookie file can be in Netscape format, or just plain HTTP-style headers dumped into a file.
If the name is an empty string, no cookies are loaded, but cookie
handling is still enabled.
Available as of cURL 7.1.0.
A string with the name of a file to save all internal cookies to when
the handle's destructor is called.
Available as of cURL 7.9.0.
As of PHP 8.0.0, curl_close is a no-op
and does not destroy the handle.
If cookies need to be written prior to the handle being automatically
destroyed, run curl_setopt($ch, CURLOPT_COOKIELIST, "FLUSH");.
As of PHP 8.0.0, curl_close is a no-op
and does not destroy the handle.
If cookies need to be written prior to the handle being automatically
destroyed, run curl_setopt($ch, CURLOPT_COOKIELIST, "FLUSH");.
A cookie string (i.e. a single line in Netscape/Mozilla format, or a regular
HTTP-style Set-Cookie header) adds that single cookie to the internal cookie store.
ALL
erases all cookies held in memory
SESS
erases all session cookies held in memory
FLUSH
writes all known cookies to the file specified by CURLOPT_COOKIEJAR
RELOAD
loads all cookies from the files specified by CURLOPT_COOKIEFILE
.
Available as of cURL 7.14.1.
to mark this as a new cookie "session". It will force cURL
to ignore all cookies it is about to load that are "session cookies"
from the previous session. By default, cURL always stores and
loads all cookies, independent if they are session cookies or not.
Session cookies are cookies without expiry date and they are meant
to be alive and existing for this "session" only.
Available as of cURL 7.9.7.
to convert Unix newlines to CRLF newlines
on transfers.
Available as of cURL 7.1.0.
Pass a string naming a file with the concatenation of
CRL (Certificate Revocation List) (in PEM format)
to use in the certificate validation that occurs during the SSL exchange.
When cURL is built to use GnuTLS,
there is no way to influence the use of CRL passed
to help in the verification process.
When cURL is built with OpenSSL support,
X509_V_FLAG_CRL_CHECK
and X509_V_FLAG_CRL_CHECK_ALL are both set,
requiring CRL check against all the elements of the certificate chain
if a CRL file is passed.
Also note that CURLOPT_CRLFILE implies
CURLSSLOPT_NO_PARTIALCHAIN
as of cURL 7.71.0 due to an OpenSSL bug.
Available as of cURL 7.19.0.
A custom request method to use instead of
GET or HEAD when doing
a HTTP request. This is useful for doing
DELETE or other, more obscure HTTP requests.
Valid values are things like GET,
POST, CONNECT and so on;
i.e. Do not enter a whole HTTP request line here. For instance,
entering GET /index.html HTTP/1.0\r\n\r\n
would be incorrect.
This option accepts a string or .
Available as of cURL 7.1.0.
Don't do this without making sure the server supports the custom
request method first.
Don't do this without making sure the server supports the custom
request method first.
A string with the default protocol to use if the URL is missing a scheme name.
Available as of PHP 7.0.7 and cURL 7.45.0.
Setting this option to 1 will have different effects
based on the protocol it is used with.
FTP and SFTP based URLs will list only the names of files in a directory.
POP3 will list the email message or messages on the POP3 server.
For FILE, this option has no effect
as directories are always listed in this mode.
Using this option with CURLOPT_WILDCARDMATCH
will prevent the latter from having any effect.
Defaults to 0.
Available as of cURL 7.17.0.
to not allow URLs that include a username.
Usernames are allowed by default.
Available as of PHP 7.3.0 and cURL 7.61.0.
The number of seconds to keep DNS entries in memory. This
option is set to 120 (2 minutes) by default.
This option accepts any value that can be cast to a valid int.
Available as of cURL 7.9.3.
Set the name of the network interface that the DNS resolver should bind to.
This must be an interface name (not an address).
This option accepts a string or .
Available as of PHP 7.0.7 and cURL 7.33.0
Set the local IPv4 address that the resolver should bind to.
The argument should contain a single numerical IPv4 address.
This option accepts a string or .
Available as of PHP 7.0.7 and cURL 7.33.0.
Set the local IPv6 address that the resolver should bind to.
The argument should contain a single numerical IPv6 address.
This option accepts a string or .
Available as of PHP 7.0.7 and cURL 7.33.0.
Pass a string with a comma-separated list of DNS servers to be used
instead of the system default
(e.g.: 192.168.1.100,192.168.1.101:8080).
Available as of cURL 7.24.0.
to shuffle the order of all returned addresses so that they will be used
in a random order, when a name is resolved and more than one IP address is returned.
This may cause IPv4 to be used before IPv6 or vice versa.
Available as of PHP 7.3.0 and cURL 7.60.0.
to use a global DNS cache. This option is not thread-safe.
It is conditionally enabled by default if PHP is built for non-threaded use
(CLI, FCGI, Apache2-Prefork, etc.).
Available as of cURL 7.9.3 and deprecated as of cURL 7.11.1.
As of PHP 8.4, this option no longer has any effect.
Set to 2 to verify the DNS-over-HTTPS server's SSL certificate name fields against the host name.
Available as of PHP 8.2.0 and cURL 7.76.0.
Set to 1 to enable and 0 to disable
verification of the authenticity of the DNS-over-HTTPS server's SSL certificate.
Available as of PHP 8.2.0 and cURL 7.76.0.
Set to 1 to enable and 0 to disable
the verification of the status of the DNS-over-HTTPS server certificate
using the "Certificate Status Request" TLS extension (OCSP stapling).
Available as of PHP 8.2.0 and cURL 7.76.0.
Provides the DNS-over-HTTPS URL.
This option accepts a string or .
Available as of PHP 8.1.0 and cURL 7.62.0.
Like CURLOPT_RANDOM_FILE, except a filename
to an Entropy Gathering Daemon socket.
Available as of cURL 7.7.0 and deprecated as of cURL 7.84.0.
The contents of the Accept-Encoding: header as a string.
This enables decoding of the response. Supported encodings are:
identity
deflate
gzip
.
If an empty string is set,
a header containing all supported encoding types is sent.
Available as of cURL 7.10 and deprecated as of cURL 7.21.6.
The timeout for Expect: 100-continue responses in milliseconds.
Defaults to 1000 milliseconds.
This option accepts any value that can be cast to a valid int.
Available as of PHP 7.0.7 and cURL 7.36.0.
to fail verbosely if the HTTP code returned
is greater than or equal to 400. The default behavior is to return
the page normally, ignoring the code.
Available as of cURL 7.1.0.
Accepts a file handle resource
to the file that the transfer should be written to.
The default is STDOUT (the browser window).
Available as of cURL 7.1.0 and deprecated as of cURL 7.9.7.
Set to to attempt to retrieve the modification
date of the remote document. This value can be retrieved using
the CURLINFO_FILETIME option with
curl_getinfo.
Available as of cURL 7.5.0.
Pass a callable that will be used for wildcard matching.
The signature of the callback should be:
intcallback
resourcecurlHandle
stringpattern
stringstring
curlHandle
The cURL handle.
pattern
The wildcard pattern.
string
The string to run the wildcard pattern matching on.
The callback should return
CURL_FNMATCHFUNC_MATCH if pattern matches the string,
CURL_FNMATCHFUNC_NOMATCH if not
or CURL_FNMATCHFUNC_FAIL if an error occurred.
Available as of cURL 7.21.0.
The cURL handle.
The wildcard pattern.
The string to run the wildcard pattern matching on.
Set to to follow any Location: header that the server sends as
part of the HTTP header.
See also CURLOPT_MAXREDIRS.
This constant is not available when open_basedir
is enabled.
Available as of cURL 7.1.0.
Set to to force the connection to explicitly
close when it has finished processing, and not be pooled for reuse.
Available as of cURL 7.7.0.
Set to to force the use of a new connection
instead of a cached one.
Available as of cURL 7.7.0.
Set to to append to the remote file instead of
overwriting it.
Available as of cURL 7.1.0 and deprecated as of cURL 7.16.4.
An alias of
CURLOPT_TRANSFERTEXT. Use that instead.
Available as of cURL 7.1, deprecated as of cURL 7.11.1
and last available in cURL 7.15.5.
Removed as of PHP 7.3.0.
Set to to only list the names of an FTP directory.
Available as of cURL 7.1.0 and deprecated as of cURL 7.16.4.
A string which will be used to get the IP address to use for the FTP PORT instruction. The PORT instruction tells
the remote server to connect to our specified IP address. The
string may be a plain IP address, a hostname,
a network interface name (under Unix),
or just a plain - to use the system's default IP address.
This option accepts a string or .
Available as of cURL 7.1.0.
Set the FTP over SSL authentication method (if activated) to any of the
CURLFTPAUTH_* constants.
Defaults to CURLFTPAUTH_DEFAULT.
Available as of cURL 7.12.2.
Pass a string that will be sent as account information over FTP
(using the ACCT command) after username and password has been provided
to the server.
Set to to disable sending the account information.
Defaults to .
Available as of cURL 7.13.0.
Pass a string that will be used to try to authenticate over FTP
if the USER/PASS negotiation fails.
Available as of cURL 7.15.5.
Set to to create missing directories when an FTP operation
encounters a path that currently doesn't exist.
Available as of cURL 7.10.7.
Tell cURL which method to use to reach a file on a FTP(S) server. Possible values are
any of the CURLFTPMETHOD_* constants.
Defaults to CURLFTPMETHOD_MULTICWD.
Available as of cURL 7.15.1.
A timeout in seconds cURL will wait for a response from an FTP server.
This option overrides CURLOPT_TIMEOUT.
This option accepts any value that can be cast to a valid int.
This option name is replaced with CURLOPT_SERVER_RESPONSE_TIMEOUT,
available as of PHP 8.4.0.
Available as of cURL 7.10.8 and deprecated as of cURL 7.85.0.
If this option is set to 1
cURL will not use the IP address the server suggests
in its 227-response to cURL's PASV command
but will use the IP address it used for the connection.
The port number received from the 227-response will not be ignored by cURL.
Defaults to 1 as of cURL 7.74.0
and 0 prior to that.
Available as of cURL 7.15.0.
Available as of cURL 7.11.0 and deprecated as of cURL 7.16.4.
This option makes cURL use CCC (Clear Command Channel)
which shuts down the SSL/TLS layer after authenticating
making the rest of the control channel communication unencrypted.
Use one of the CURLFTPSSL_CCC_* constants.
Defaults to CURLFTPSSL_CCC_NONE.
Available as of cURL 7.16.1.
Set to to use EPRT (and LPRT) when doing active FTP downloads.
Set to to disable EPRT and LPRT and use PORT only.
Available as of cURL 7.10.5.
Set to to first try an EPSV command for FTP transfers before reverting back to PASV.
Set to to disable EPSV.
Available as of cURL 7.9.2.
Set to 1 to send a PRET command
before PASV (and EPSV).
Has no effect when using the active FTP transfers mode.
Defaults to 0.
Available as of cURL 7.20.0.
Set to CURLGSSAPI_DELEGATION_FLAG
to allow unconditional GSSAPI credential delegation.
Set to CURLGSSAPI_DELEGATION_POLICY_FLAG
to delegate only if the OK-AS-DELEGATE flag is set
in the service ticket.
Defaults to CURLGSSAPI_DELEGATION_NONE.
Available as of cURL 7.22.0.
Head start for IPv6 for the happy eyeballs algorithm. Happy eyeballs attempts
to connect to both IPv4 and IPv6 addresses for dual-stack hosts,
preferring IPv6 first for timeout milliseconds.
Defaults to CURL_HET_DEFAULT, which is currently 200 milliseconds.
This option accepts any value that can be cast to a valid int.
Available as of PHP 7.3.0 and cURL 7.59.0
to send an HAProxy PROXY protocol v1 header at the start of the connection.
The default action is not to send this header.
Available as of PHP 7.3.0 and cURL 7.60.0.
Set to to include the headers in the output sent to the callback
defined by CURLOPT_WRITEFUNCTION.
Available as of cURL 7.1.0.
A callable with the following signature:
intcallback
resourcecurlHandle
stringheaderData
curlHandle
The cURL handle.
headerData
The header data which must be written by the callback.
The callback should return the number of bytes written.
Available as of cURL 7.7.2.
The cURL handle.
The header data which must be written by the callback.
Send HTTP headers to both proxy and host or separately.
Possible values are any of the
CURLHEADER_* constants.
Defaults to CURLHEADER_SEPARATE as of cURL
7.42.1, and CURLHEADER_UNIFIED prior to that.
Available as of PHP 7.0.7 and cURL 7.37.0.
string with HSTS (HTTP Strict Transport Security) cache file name
or to allow HSTS without reading from or writing to any file
and clear the list of files to read HSTS data from.
Available as of PHP 8.2.0 and cURL 7.74.0.
Accepts a bitmask of HSTS (HTTP Strict Transport Security) features
defined by the CURLHSTS_* constants.
Available as of PHP 8.2.0 and cURL 7.74.0.
Whether to allow HTTP/0.9 responses. Defaults to as of cURL 7.66.0;
formerly it defaulted to .
Available as of PHP 7.3.15 and 7.4.3, respectively, and cURL 7.64.0.
An array of HTTP 200 responses that will be treated as valid responses and not as errors.
Available as of cURL 7.10.3.
A bitmask of HTTP authentication method(s) to use. The options are:
CURLAUTH_BASIC
CURLAUTH_DIGEST
CURLAUTH_GSSNEGOTIATE
CURLAUTH_NTLM
CURLAUTH_AWS_SIGV4
CURLAUTH_ANY
CURLAUTH_ANYSAFE
.
If more than one method is used, cURL will poll the server to see
what methods it supports and pick the best one.
CURLAUTH_ANY sets all bits. cURL will automatically select
the one it finds most secure.
CURLAUTH_ANYSAFE sets all bits except CURLAUTH_BASIC.
cURL will automatically select the one it finds most secure.
Available as of cURL 7.10.6.
Set to to reset the HTTP request method to GET. Since GET is the default, this is only necessary if the request
method has been changed.
Available as of cURL 7.8.1.
An array of HTTP header fields to set, in the format
array('Content-type: text/plain', 'Content-length: 100')
Available as of cURL 7.1.0.
to tunnel through a given HTTP proxy.
Available as of cURL 7.3.0.
to get the raw HTTP response body.
Available as of cURL 7.16.2.
If set to 0, transfer decoding is disabled.
If set to 1, transfer decoding is enabled.
cURL does chunked transfer decoding by default
unless this option is set to 0.
Defaults to 1.
Available as of cURL 7.16.2.
Set to one of the
CURL_HTTP_VERSION_* constants
for cURL to use the specified HTTP version.
Available as of cURL 7.9.1.
If set to 1,
ignore the Content-Length header in the HTTP response
and ignore asking for or relying on it for FTP transfers.
Defaults to 0.
Available as of cURL 7.14.1.
Accepts a file handle resource
to the file that the transfer should be read from when uploading.
Available as of cURL 7.1.0 and deprecated as of cURL 7.9.7.
Use CURLOPT_READDATA instead.
The expected size, in bytes, of the file when uploading a file to
a remote site. Note that using this option will not stop cURL
from sending more data, as exactly what is sent depends on
CURLOPT_READFUNCTION.
This option accepts any value that can be cast to a valid int.
Available as of cURL 7.1.0.
Set to a string with the name of the outgoing network interface to use.
This can be an interface name, an IP address or a host name.
Available as of cURL 7.1.0.
Allows an application to select what kind of IP addresses to use when
resolving host names. This is only interesting when using host names that
resolve addresses using more than one version of IP.
Set to one of the
CURL_IPRESOLVE_* constants.
Defaults to CURL_IPRESOLVE_WHATEVER.
Available as of cURL 7.10.8.
If set to a string naming a file holding a CA certificate in PEM format,
an additional check against the peer certificate is performed
to verify the issuer is indeed the one associated
with the certificate provided by the option.
For the result of the check to be considered a failure,
this option should be used in combination with the
CURLOPT_SSL_VERIFYPEER option.
Available as of cURL 7.19.0.
Pass a string with binary data of a CA SSL certificate in PEM format.
If set, an additional check against the peer certificate is performed
to verify the issuer is the one associated with the certificate provided by the option.
Available as of PHP 8.1.0 and cURL 7.71.0.
Set to to keep sending the request body if the HTTP code returned is equal to or larger than 300.
The default action would be to stop sending
and close the stream or connection. Suitable for manual NTLM authentication.
Most applications do not need this option.
Available as of PHP 7.3.0 and cURL 7.51.0.
Set to a string with the password required to use the CURLOPT_SSLKEY
or CURLOPT_SSH_PRIVATE_KEYFILE private key.
Setting this option to disables using a password for these options.
Available as of cURL 7.17.0.
The KRB4 (Kerberos 4) security level. Any of the following string values
(in order from least to most powerful) are valid:
clear
safe
confidential
private
.
If the string does not match one of these,
private is used. Setting this option to
will disable KRB4 security. Currently KRB4 security only works
with FTP transactions.
Available as of cURL 7.3.0 and deprecated as of cURL 7.17.0.
Set the kerberos security level for FTP and also enables kerberos awareness.
This should be set to one of the following strings:
clear
safe
confidential
private
.
If the string is set but does not match one of these,
private is used.
Setting this option to will disable kerberos support for FTP.
Defaults to .
Available as of cURL 7.16.4.
Sets the local port number of the socket used for the connection.
This option accepts any value that can be cast to a valid int.
Defaults to 0.
Available as of cURL 7.15.2.
The number of attempts cURL makes to find a working local port number,
starting with the one set with CURLOPT_LOCALPORT.
This option accepts any value that can be cast to a valid int.
Defaults to 1.
Available as of cURL 7.15.2.
Can be used to set protocol specific login options, such as the
preferred authentication mechanism via AUTH=NTLM or AUTH=*, and should be used in conjunction with the
CURLOPT_USERNAME option.
Available as of PHP 7.0.7 and cURL 7.34.0.
The transfer speed, in bytes per second, that the transfer should be
below during the count of CURLOPT_LOW_SPEED_TIME
seconds before PHP considers the transfer too slow and aborts.
This option accepts any value that can be cast to a valid int.
Available as of cURL 7.1.0.
The number of seconds the transfer speed should be below
CURLOPT_LOW_SPEED_LIMIT before PHP considers
the transfer too slow and aborts.
This option accepts any value that can be cast to a valid int.
Available as of cURL 7.1.0.
Set a string with the authentication address (identity)
of a submitted message that is being relayed to another server.
The address should not be specified within a pair of angled brackets
().
If an empty string is used then a pair of brackets are sent by cURL
as required by RFC 2554.
Available as of cURL 7.25.0.
Set a string with the sender's email address when sending SMTP mail.
The email address should be specified with angled brackets
() around it,
which if not specified are added automatically.
If this parameter is not specified then an empty address is sent
to the SMTP server which might cause the email to be rejected.
Available as of cURL 7.20.0.
Set to an array of strings
with the recipients to pass to the server in an SMTP mail request.
Each recipient should be specified within a pair of angled brackets
().
If an angled bracket is not used as the first character,
cURL assumes a single email address has been provided
and encloses that address within brackets.
Available as of cURL 7.20.0.
Set to 1 to allow RCPT TO command
to fail for some recipients which makes cURL ignore errors
for individual recipients and proceed with the remaining accepted recipients.
If all recipients trigger failures and this flag is specified,
cURL aborts the SMTP conversation
and returns the error received from to the last RCPT TO command.
Replaced by CURLOPT_MAIL_RCPT_ALLOWFAILS as of cURL 8.2.0.
Available as of PHP 8.2.0 and cURL 7.69.0.
Deprecated as of cURL 8.2.0.
The maximum idle time allowed for an existing connection to be considered for reuse.
Default maximum age is set to 118 seconds.
This option accepts any value that can be cast to a valid int.
Available as of PHP 8.2.0 and cURL 7.65.0.
The maximum amount of persistent connections that are allowed.
When the limit is reached, the oldest one in the cache is closed
to prevent increasing the number of open connections.
This option accepts any value that can be cast to a valid int.
Available as of cURL 7.7.0.
Sets the maximum accepted size (in bytes) of a file to download.
If the file requested is found larger than this value,
the transfer is aborted
and CURLE_FILESIZE_EXCEEDED is returned.
Passing 0 disables this option,
and passing a negative size returns a
CURLE_BAD_FUNCTION_ARGUMENT.
If the file size is not known prior to the start of download,
this option has no effect.
For setting a size limit above 2GB,
CURLOPT_MAXFILESIZE_LARGE should be used.
As of cURL 8.4.0, this option also stops ongoing transfers
if they reach this threshold.
This option accepts any value that can be cast to a valid int.
Defaults to 0.
Available as of cURL 7.10.8.
The maximum file size in bytes allowed to download. If the file requested is found larger than this value,
the transfer will not start and CURLE_FILESIZE_EXCEEDED will be returned.
The file size is not always known prior to download, and for such files this option has no effect even if
the file transfer ends up being larger than this given limit.
This option accepts any value that can be cast to a valid int.
Available as of PHP 8.2.0 and cURL 7.11.0.
The maximum time in seconds, since the creation of the connection, that is allowed for an existing
connection to have for it to be considered for reuse. If a connection is found in the cache that is older
than this value, it will instead be closed once any in-progress transfers are complete.
Default is 0 seconds, meaning the option is disabled and all connections are eligible for reuse.
This option accepts any value that can be cast to a valid int.
Available as of PHP 8.2.0 and cURL 7.80.0.
The maximum amount of HTTP redirections to follow. Use this option alongside CURLOPT_FOLLOWLOCATION.
Default value of 20 is set to prevent infinite redirects.
Setting to -1 allows inifinite redirects, and 0 refuses all redirects.
Available as of cURL 7.5.0.
If a download exceeds this speed (counted in bytes per second) on
cumulative average during the transfer, the transfer will pause to
keep the average rate less than or equal to the parameter value.
Defaults to unlimited speed.
This option accepts any value that can be cast to a valid int.
Available as of cURL 7.15.5.
If an upload exceeds this speed (counted in bytes per second) on
cumulative average during the transfer, the transfer will pause to
keep the average rate less than or equal to the parameter value.
Defaults to unlimited speed.
This option accepts any value that can be cast to a valid int.
Available as of cURL 7.15.5.
Set to a bitmask of CURLMIMEOPT_*
constants. Currently there is only one available option:
CURLMIMEOPT_FORMESCAPE.
Available as of PHP 8.3.0 and cURL 7.81.0.
Set to to be completely silent with regards to
the cURL functions.
Use CURLOPT_RETURNTRANSFER instead.
Available as of cURL 7.1.0, deprecated as of cURL 7.8.0
and last available in cURL 7.15.5.
Removed as of PHP 7.3.0.
Set to to scan the ~/.netrc
file to find a username and password for the remote site that
a connection is being established with.
Available as of cURL 7.1.0.
Set a string containing the full path name to a .netrc file.
If this option is omitted and CURLOPT_NETRC is set,
cURL checks for a .netrc file
in the current user's home directory.
Available as of cURL 7.11.0.
Sets the value of the permissions (int) that is set on newly created directories
on the remote server. The default value is 0755.
The only protocols that can use this are
sftp://, scp://
and file://.
Available as of cURL 7.16.4.
Sets the value of the permissions (as an int) that are set on newly created files
on the remote server. The default value is 0644.
The only protocols that can use this are
sftp://, scp://
and file://.
Available as of cURL 7.16.4.
Set to to exclude the body from the output.
For HTTP(S), cURL makes a HEAD request. For most other protocols,
cURL is not asking for the body data at all.
Changing this to will result in body data being included in the output.
Available as of cURL 7.1.0.
Set to to disable the progress meter for cURL transfers.
PHP automatically sets this option to , this should only be
changed for debugging purposes.
Available as of cURL 7.1.0.
PHP automatically sets this option to , this should only be
changed for debugging purposes.
Set a string consisting of a comma separated list of hostnames
that do not require a proxy to get reached.
Each name in this list is matched as either a domain
which contains the hostname or the hostname itself.
The only wildcard available in the string
is a single * character which matches all hosts,
effectively disabling the proxy.
Setting this option to an empty string enables the proxy for all hostnames.
Since cURL 7.86.0, IP addresses set with this option
can be provided using CIDR notation.
Available as of cURL 7.19.4.
to ignore any cURL function that causes a
signal to be sent to the PHP process. This is turned on by default
in multi-threaded SAPIs so timeout options can still be used.
Available as of cURL 7.10.
A callable with the following signature:
stringcallback
resourcecurlHandle
stringpasswordPrompt
intmaximumPasswordLength
curlHandle
The cURL handle.
passwordPrompt
A password prompt.
maximumPasswordLength
The maximum length of the password.
The callback should return a string containing the password.
Available as of cURL 7.4.2, deprecated as of cURL 7.11.1
and last available in cURL 7.15.5.
Removed as of PHP 7.3.0.
The cURL handle.
A password prompt.
The maximum length of the password.
Set to a string with the password to use in authentication.
Available as of cURL 7.19.1.
Set to for cURL not alter URL paths before passing them on to the server.
Defaults to , which squashes sequences of /../
or /./ that may exist in the URL's path part
which is supposed to be removed according to RFC 3986 section 5.2.4.
Available as of PHP 7.0.7 and cURL 7.42.0.
Set a string with the pinned public key.
The string can be the file name of the pinned public key
in a PEM or DER file format. The string can also be any
number of base64 encoded sha256 hashes preceded by sha256// and
separated by ;.
Available as of PHP 7.0.7 and cURL 7.39.0.
Set to to wait for an existing connection to confirm
whether it can do multiplexing and use it if it can
before creating and using a new connection.
Available as of PHP 7.0.7 and cURL 7.43.0.
An int with an alternative port number to connect to
instead of the one specified in the URL or the default port for the used protocol.
Available as of cURL 7.1.0.
Set to to do a HTTP POST request.
This request uses the application/x-www-form-urlencoded header.
Defaults to .
Available as of cURL 7.1.0.
The full data to post in a HTTP POST operation.
This parameter can either be
passed as a urlencoded string like 'para1=val1para2=val2...'
or as an array with the field name as key and field data as value.
If value is an array, the
Content-Type header will be set to
multipart/form-data.
Files can be sent using CURLFile or CURLStringFile,
in which case value must be an array.
Available as of cURL 7.1.0.
An array of FTP command strings
to execute on the server after the FTP request has been performed.
Available as of cURL 7.1.0.
Set to a bitmask of CURL_REDIR_POST_301,
CURL_REDIR_POST_302 and CURL_REDIR_POST_303
if the HTTP POST method should be maintained
when CURLOPT_FOLLOWLOCATION is set and a
specific type of redirect occurs.
Available as of cURL 7.19.1.
Set a string holding the host name or dotted numerical
IP address to be used as the preproxy that cURL connects to before
it connects to the HTTP(S) proxy specified in the
CURLOPT_PROXY option for the upcoming request.
The preproxy can only be a SOCKS proxy and it should be prefixed with
[scheme]:// to specify which kind of socks is used.
A numerical IPv6 address must be written within [brackets].
Setting the preproxy to an empty string explicitly disables the use of a preproxy.
To specify port number in this string, append :[port]
to the end of the host name. The proxy's port number may optionally be
specified with the separate option CURLOPT_PROXYPORT.
Defaults to using port 1080 for proxies if a port is not specified.
Available as of PHP 7.3.0 and cURL 7.52.0.
Set an array of FTP command strings to pass to the server
after the transfer type is set.
These commands are not performed when a directory listing is performed,
only for file transfers.
Available as of cURL 7.9.5.
Any data that should be associated with this cURL handle. This data
can subsequently be retrieved with the
CURLINFO_PRIVATE option of
curl_getinfo. cURL does nothing with this data.
When using a cURL multi handle, this private data is typically a
unique key to identify a standard cURL handle.
Available as of cURL 7.10.3.
A callable with the following signature:
intcallback
resourcecurlHandle
intbytesToDownload
intbytesDownloaded
intbytesToUpload
intbytesUploaded
curlHandle
The cURL handle.
bytesToDownload
The total number of bytes expected to be downloaded in this transfer.
bytesDownloaded
The number of bytes downloaded so far.
bytesToUpload
The total number of bytes expected to be uploaded in this transfer.
bytesUploaded
The number of bytes uploaded so far.
The callback should return an int with a non-zero value to abort the transfer
and set a CURLE_ABORTED_BY_CALLBACK error.
The callback is only called when the CURLOPT_NOPROGRESS
option is set to .
Available as of cURL 7.1.0 and deprecated as of cURL 7.32.0.
Use CURLOPT_XFERINFOFUNCTION instead.
The cURL handle.
The total number of bytes expected to be downloaded in this transfer.
The number of bytes downloaded so far.
The total number of bytes expected to be uploaded in this transfer.
The number of bytes uploaded so far.
The callback is only called when the CURLOPT_NOPROGRESS
option is set to .
Bitmask of CURLPROTO_* values.
If used, this bitmask limits what protocols cURL may use in the transfer.
Defaults to CURLPROTO_ALL, ie. cURL will accept all protocols it supports.
See also CURLOPT_REDIR_PROTOCOLS.
Available as of cURL 7.19.4 and deprecated as of cURL 7.85.0.
Set to a string with a comma separated list
of case insensitive protocol names (URL schemes) to allow in the transfer.
Set to ALL to enable all protocols.
By default, cURL accepts all protocols it was built with support for.
Available protocols are:
DICT
FILE
FTP
FTPS
GOPHER
GOPHERS
HTTP
HTTPS
IMAP
IMAPS
LDAP
LDAPS
MQTT
POP3
POP3S
RTMP
RTMPE
RTMPS
RTMPT
RTMPTE
RTMPTS
RTSP
SCP
SFTP
SMB
SMBS
SMTP
SMTPS
TELNET
TFTP
WS
WSS
.
Available as of PHP 8.3.0 and cURL 7.85.0.
A string with the HTTP proxy to tunnel requests through.
This should be the hostname, the dotted numerical IP address
or a numerical IPv6 address written within [brackets].
Available as of cURL 7.1.0.
A bitmask of the HTTP authentication method(s)
(CURLAUTH_* constants)
to use for the proxy connection.
For proxy authentication, only CURLAUTH_BASIC and
CURLAUTH_NTLM are currently supported.
Defaults to CURLAUTH_BASIC.
Available as of cURL 7.10.7.
An array of custom HTTP header strings to pass to proxies.
Available as of PHP 7.0.7 and cURL 7.37.0.
Set a string with the password to be used for authentication with the proxy.
Available as of cURL 7.19.1.
An int with the port number of the proxy to connect to.
This port number can also be set in CURLOPT_PROXY.
Setting this to zero makes cURL use the default proxy port number
or the port number specified in the proxy URL string.
Available as of cURL 7.1.0.
Sets the type of the proxy to one of the
CURLPROXY_* constants.
Defaults to CURLPROXY_HTTP.
Available as of cURL 7.10.
Set a string with the username to be used for authentication with the proxy.
Available as of cURL 7.19.1.
A string with a username and password formatted as
[username]:[password] to use for the
connection to the proxy.
Available as of cURL 7.1.0.
The path to proxy Certificate Authority (CA) bundle. Set the path as a
string naming a file holding one or more certificates to
verify the HTTPS proxy with.
This option is for connecting to an HTTPS proxy, not an HTTPS server.
Defaults set to the system path where cURL's cacert bundle is assumed
to be stored.
Available as of PHP 7.3.0 and cURL 7.52.0.
A string with the name of a PEM file holding one or more certificates to verify the HTTPS proxy with.
This option is for connecting to an HTTPS proxy, not an HTTPS server.
Defaults set to the system path where cURL's cacert bundle is assumed
to be stored.
Available as of PHP 8.2.0 and cURL 7.77.0.
A string with the directory holding multiple CA certificates
to verify the HTTPS proxy with.
Available as of PHP 7.3.0 and cURL 7.52.0.
Set to a string with the file name
with the concatenation of CRL (Certificate Revocation List)
in PEM format to use in the certificate validation that occurs during
the SSL exchange.
Available as of PHP 7.3.0 and cURL 7.52.0.
Proxy issuer SSL certificate filename string.
Available as of PHP 8.1.0 and cURL 7.71.0.
A string with the proxy issuer SSL certificate.
Available as of PHP 8.1.0 and cURL 7.71.0.
Set the string be used as the password required to use the
CURLOPT_PROXY_SSLKEY private key.
A passphrase is not needed to load a certificate
but one is needed to load a private key.
This option is for connecting to an HTTPS proxy, not an HTTPS server.
Available as of PHP 7.3.0 and cURL 7.52.0.
Set the pinned public key for HTTPS proxy.
The string can be the file name of the pinned public key
which is expected to be in a PEM
or DER file format.
The string can also be any number of base64 encoded sha256 hashes
preceded by sha256// and separated by ;.
Available as of PHP 7.3.0 and cURL 7.52.0.
A string with the proxy authentication service name.
Available as of PHP 7.0.7, cURL 7.43.0 (for HTTP proxies) and cURL 7.49.0 (for SOCKS5 proxies).
A string with the file name of the client certificate used to connect to the HTTPS proxy.
The default format is P12 on Secure Transport and PEM on other engines,
and can be changed with CURLOPT_PROXY_SSLCERTTYPE.
With NSS or Secure Transport, this can also be the nickname of the certificate
used for authentication as it is named in the security database.
If a file from the current directory is to be used,
it must be prefixed with ./
in order to avoid confusion with a nickname.
Available as of PHP 7.3.0 and cURL 7.52.0.
A string with the format of the client certificate used when connecting to an HTTPS proxy.
Supported formats are PEM and DER, except with Secure Transport.
OpenSSL (versions 0.9.3 and later) and Secure Transport
(on iOS 5 or later, or OS X 10.7 or later) also support P12 for
PKCS#12-encoded files. Defaults to PEM.
Available as of PHP 7.3.0 and cURL 7.52.0.
A string with the SSL proxy client certificate.
Available as of PHP 8.1.0 and cURL 7.71.0.
A string with the file name of the private key
used for connecting to the HTTPS proxy.
The default format is PEM and can be changed with
CURLOPT_PROXY_SSLKEYTYPE.
(iOS and Mac OS X only) This option is ignored if cURL was built against
Secure Transport. Available if built with TLS enabled.
Available as of PHP 7.3.0 and cURL 7.52.0.
A string with the format of the private key.
Supported formats are:
PEM
DER
ENG
.
Available as of PHP 7.3.0 and cURL 7.52.0.
A string with the private key for connecting to the HTTPS proxy.
Available as of PHP 8.1.0 and cURL 7.71.0.
Set the preferred HTTPS proxy TLS version to one of the
CURL_SSLVERSION_*
constants.
Defaults to CURL_SSLVERSION_DEFAULT.
It is better to not set this option and leave the default
CURL_SSLVERSION_DEFAULT
which will attempt to figure out the remote SSL protocol version.
Available as of PHP 7.3.0 and cURL 7.52.0.
It is better to not set this option and leave the default
CURL_SSLVERSION_DEFAULT
which will attempt to figure out the remote SSL protocol version.
A string with a colon-separated list of ciphers
to use for the connection to the HTTPS proxy.
When used with OpenSSL commas and spaces are also acceptable as separators,
and !, - and +
can be used as operators.
Available as of PHP 7.3.0 and cURL 7.52.0.
Set proxy SSL behavior options, which is a bitmask of the
CURLSSLOPT_* constants.
Available as of PHP 7.3.0 and cURL 7.52.0.
Set to 2 to verify in the HTTPS proxy's certificate name fields against the proxy name.
When set to 0 the connection succeeds regardless of the names used in the certificate.
Use that ability with caution!
Set to 1 in cURL 7.28.0 and earlier as a debug option.
Set to 1 in cURL 7.28.1 to 7.65.3 CURLE_BAD_FUNCTION_ARGUMENT is returned.
As of cURL 7.66.0 1 and 2 is treated as the same value.
Defaults to 2.
In production environments the value of this option should be kept at 2.
Available as of PHP 7.3.0 and cURL 7.52.0.
Set to to stop cURL from verifying the peer's certificate.
Alternate certificates to verify against can be
specified with the CURLOPT_CAINFO option
or a certificate directory can be specified with the
CURLOPT_CAPATH option.
When set to , the peer certificate verification succeeds regardless.
by default.
Available as of PHP 7.3.0 and cURL 7.52.0.
A string with a colon-separated list of ciphers to use for the connection to the TLS 1.3 connection to a proxy.
This option is currently used only when cURL is built to use OpenSSL 1.1.1 or later.
When using a different SSL backend the TLS 1.3 cipher suites can be set
with the CURLOPT_PROXY_SSL_CIPHER_LIST option.
Available as of PHP 7.3.0 and cURL 7.61.0.
A string with the password to use for the TLS authentication method specified with the
CURLOPT_PROXY_TLSAUTH_TYPE option. Requires that the
CURLOPT_PROXY_TLSAUTH_USERNAME option to also be set.
Available as of PHP 7.3.0 and cURL 7.52.0.
The method of the TLS authentication used for the HTTPS connection.
Supported method is SRP.
Secure Remote Password (SRP) authentication for TLS provides mutual authentication
if both sides have a shared secret. To use TLS-SRP, the
CURLOPT_PROXY_TLSAUTH_USERNAME and
CURLOPT_PROXY_TLSAUTH_PASSWORD options must also be set.
Available as of PHP 7.3.0 and cURL 7.52.0.
Secure Remote Password (SRP) authentication for TLS provides mutual authentication
if both sides have a shared secret. To use TLS-SRP, the
CURLOPT_PROXY_TLSAUTH_USERNAME and
CURLOPT_PROXY_TLSAUTH_PASSWORD options must also be set.
The username to use for the HTTPS proxy TLS authentication method specified with the
CURLOPT_PROXY_TLSAUTH_TYPE option. Requires that the
CURLOPT_PROXY_TLSAUTH_PASSWORD option to also be set.
Available as of PHP 7.3.0 and cURL 7.52.0.
Set to 1 to set the transfer mode (binary or ASCII)
for FTP transfers done via an HTTP proxy, by appending
type=a or type=i to the URL.
Without this setting or it being set to 0,
CURLOPT_TRANSFERTEXT has no effect
when doing FTP via a proxy.
Defaults to 0.
Available as of cURL 7.18.0.
to HTTP PUT a file. The file to PUT must
be set with CURLOPT_READDATA and
CURLOPT_INFILESIZE.
Available as of cURL 7.1.0 and deprecated as of cURL 7.12.1.
Set to for cURL to skip cleanup of resources
when recovering from a timeout.
This allows for a swift termination of the cURL process
at the expense of a possible leak of associated resources.
Available as of PHP 8.3.0 and cURL 7.87.0.
An array of FTP command strings to execute on the server prior to the FTP request.
Available as of cURL 7.1.0.
A string with a filename to be used to seed the random number generator for SSL.
Available as of cURL 7.7.0 and deprecated as of cURL 7.84.0.
A string with the range(s) of data to retrieve in the format X-Y where X or Y are optional. HTTP transfers
also support several intervals, separated with commas in the format
X-Y,N-M.
Set to to disable requesting a byte range.
Available as of cURL 7.1.0.
Sets a file pointer resource that will be used by the file read function
set with CURLOPT_READFUNCTION.
Available as of cURL 7.9.7.
A callable with the following signature:
stringcallback
resourcecurlHandle
resourcestreamResource
intmaxAmountOfDataToRead
curlHandle
The cURL handle.
streamResource
Stream resource provided to cURL through the option
CURLOPT_READDATA.
maxAmountOfDataToRead
The maximum amount of data to be read.
The callback should return a string
with a length equal or smaller than the amount of data requested,
typically by reading it from the passed stream resource. It should
return an empty string to signal EOF.
Available as of cURL 7.1.0.
The cURL handle.
Stream resource provided to cURL through the option
CURLOPT_READDATA.
The maximum amount of data to be read.
Bitmask of CURLPROTO_* values
which limit what protocols cURL may use in a transfer that it follows to in
a redirect when CURLOPT_FOLLOWLOCATION is enabled.
This allows limiting specific transfers to only be allowed to use a subset
of protocols in redirections.
As of cURL 7.19.4, by default cURL will allow all protocols
except for FILE and SCP.
Prior to cURL 7.19.4, cURL would unconditionally follow to all supported protocols.
See also CURLOPT_PROTOCOLS for protocol constant values.
Available as of cURL 7.19.4 and deprecated as of cURL 7.85.0.
Set to a string with a comma separated list
of case insensitive protocol names (URL schemes)
to allow to follow to in a redirect when
CURLOPT_FOLLOWLOCATION is enabled.
Set to ALL to enable all protocols.
As of cURL 7.65.2 it defaults to FTP,
FTPS, HTTP and HTTPS.
From cURL 7.40.0 to 7.65.1, this defaults to all protocols except
FILE, SCP, SMB and
SMBS.
Prior to cURL 7.40.0, this defaults to all protocols except
FILE and SCP.
Available protocols are:
DICT
FILE
FTP
FTPS
GOPHER
GOPHERS
HTTP
HTTPS
IMAP
IMAPS
LDAP
LDAPS
MQTT
POP3
POP3S
RTMP
RTMPE
RTMPS
RTMPT
RTMPTE
RTMPTS
RTSP
SCP
SFTP
SMB
SMBS
SMTP
SMTPS
TELNET
TFTP
WS
WSS
.
Available as of PHP 8.3.0 and cURL 7.85.0.
A string with the contents of the Referer:
header to be used in a HTTP request.
Available as of cURL 7.1.0.
A string to use in the upcoming request
instead of the path as extracted from the URL.
Available as of PHP 7.3.0 and cURL 7.55.0.
Provide an array of colon-separated strings
with custom addresses for specific host and port pairs in the following format:
array(
"example.com:80:127.0.0.1",
"example2.com:443:127.0.0.2",
)
Available as of cURL 7.21.3.
The offset, in bytes, to resume a transfer from.
This option accepts any value that can be cast to a valid int.
Available as of cURL 7.1.0.
to return the transfer as a string of the
return value of curl_exec instead of outputting
it directly.
Set an int with the CSEQ number to issue for the next RTSP request.
Useful if the application is resuming a previously broken connection.
The CSEQ increments from this new number henceforth.
Defaults to 0.
Available as of cURL 7.20.0.
Sets the kind of RTSP request to make.
Must be one of the CURL_RTSPREQ_*
constants.
Available as of cURL 7.20.0.
Set an int with the CSEQ number to expect
for the next RTSP Server to Client request.
This feature (listening for Server requests) is unimplemented.
Defaults to 0.
Available as of cURL 7.20.0.
Set a string with the value of the current RTSP Session ID for the handle.
Once this value is set to any non- value,
cURL returns CURLE_RTSP_SESSION_ERROR
if the ID received from the server does not match.
If set to , cURL automatically sets the ID
the first time the server sets it in a response.
Defaults to
Available as of cURL 7.20.0.
Sets a string with the stream URI to operate on.
If not set, cURL defaults to operating on generic server options
by passing * in the place of the RTSP Stream URI.
When working with RTSP, CURLOPT_RTSP_STREAM_URI
indicates what URL to send to the server in the request header
while the CURLOPT_URL indicates
where to make the connection to.
Available as of cURL 7.20.0.
Set the Transport: header for this RTSP session.
Available as of cURL 7.20.0.
Always , what disables support for the @ prefix for
uploading files in CURLOPT_POSTFIELDS, which
means that values starting with @ can be safely
passed as fields. CURLFile may be used for
uploads instead.
The authorization identity (authzid) string for the transfer. Only applicable to the PLAIN SASL
authentication mechanism where it is optional. When not specified, only the authentication identity
(authcid) as specified by the username will be sent to the server, along with the password.
The server will derive the authzid from the authcid when not provided, which it will then use internally.
Available as of PHP 8.2.0 and cURL 7.66.0.
to enable sending the initial response in the first packet.
Available as of PHP 7.0.7 and cURL 7.31.0.
A string with the authentication service name.
Available as of PHP 7.0.7 and cURL 7.43.0.
A result of curl_share_init. Makes the cURL
handle to use the data from the shared handle.
Available as of cURL 7.10.
The SOCKS5 authentication method(s) to use. The options are:
CURLAUTH_BASIC
CURLAUTH_GSSAPI
CURLAUTH_NONE
.
When more than one method is set, cURL will poll the server to see
what methods it supports and pick the best one.
Defaults to CURLAUTH_BASIC|CURLAUTH_GSSAPI.
Set the actual username and password with the CURLOPT_PROXYUSERPWD option.
Available as of PHP 7.3.0 and cURL 7.55.0.
Set to 1 to enable and 0 to disable
the unprotected exchange of the protection mode negotiation
as part of the GSSAPI negotiation.
Available as of cURL 7.19.4.
Set a string holding the name of the SOCKS5 service.
Defaults to rcmd.
Available as of cURL 7.19.4 and deprecated as of cURL 7.49.0.
Use CURLOPT_PROXY_SERVICE_NAME instead.
A bitmask consisting of one or more of the following constants:
CURLSSH_AUTH_PUBLICKEY
CURLSSH_AUTH_PASSWORD
CURLSSH_AUTH_HOST
CURLSSH_AUTH_KEYBOARD
CURLSSH_AUTH_AGENT
CURLSSH_AUTH_ANY
.
Defaults to CURLSSH_AUTH_ANY.
Available as of cURL 7.16.1.
to enable, to disable built-in SSH compression.
Note that the server can disregard this request.
Defaults to .
Available as of PHP 7.3.0 and cURL 7.56.0.
A callable that will be called when SSH host key verification is needed.
The callback must have the following signature:
intcallback
resourcecurlHandle
intkeyType
stringkey
intkeyLength
curlHandle
The cURL handle.
keyType
One of the CURLKHTYPE_* key types.
key
The key to check.
keyLength
The length of the key in bytes.
This callback overrides CURLOPT_SSH_KNOWNHOSTS.
Available as of PHP 8.3.0 and cURL 7.84.0.
The cURL handle.
One of the CURLKHTYPE_* key types.
The key to check.
The length of the key in bytes.
A string containing 32 hexadecimal digits which should contain the
MD5 checksum of the remote host's public key, and cURL will reject
the connection to the host unless the md5sums match.
This option is only for SCP and SFTP transfers.
Available as of cURL 7.17.1.
A string with the base64-encoded SHA256 hash
of the remote host's public key.
The transfer will fail if the given hash does not match the hash the remote host provides.
Available as of PHP 8.2.0 and cURL 7.80.0.
Set to the filename of the known_host file to use
which should use the OpenSSH file format as supported by libssh2.
Available as of cURL 7.19.6.
The file name for a private key. If not used, cURL defaults to
$HOME/.ssh/id_dsa if the HOME environment variable is set,
and just id_dsa in the current directory if HOME is not set.
If the file is password-protected, set the password with
CURLOPT_KEYPASSWD.
Available as of cURL 7.16.1.
The file name for a public key. If not used, cURL defaults to
$HOME/.ssh/id_dsa.pub if the HOME environment variable is set,
and just id_dsa.pub in the current directory if HOME is not set.
Available as of cURL 7.16.1.
The name of a file containing a PEM formatted certificate.
Available as of cURL 7.1.0.
The password required to use the
CURLOPT_SSLCERT certificate.
Available as of cURL 7.1.0 and deprecated as of cURL 7.17.0.
A string with the format of the certificate. Supported formats are:
PEM
DER
ENG
P12
.
P12 (for PKCS#12-encoded files) is available as of OpenSSL 0.9.3.
Defaults to PEM.
Available as of cURL 7.9.3.
A string with the SSL client certificate.
Available as of PHP 8.1.0 and cURL 7.71.0.
The string identifier for the crypto engine of the private SSL key
specified in CURLOPT_SSLKEY.
Available as of cURL 7.9.3.
The string identifier for the crypto engine used for asymmetric crypto
operations.
Available as of cURL 7.9.3.
The name of a file containing a private SSL key.
Available as of cURL 7.9.3.
The secret password needed to use the private SSL key specified in
CURLOPT_SSLKEY.
Since this option contains a sensitive password, remember to keep
the PHP script it is contained within safe.
Available as of cURL 7.9.3 and deprecated as of cURL 7.17.0.
Since this option contains a sensitive password, remember to keep
the PHP script it is contained within safe.
The key type of the private SSL key specified in
CURLOPT_SSLKEY. Supported key types are:
PEM
DER
ENG
.
Defaults to PEM.
Available as of cURL 7.9.3.
A string private key for client cert.
Available as of PHP 8.1.0 and cURL 7.71.0.
One of
the CURL_SSLVERSION_* constants.
It is better to not set this option and leave the defaults.
As setting this to
CURL_SSLVERSION_SSLv2
or
CURL_SSLVERSION_SSLv3
is very dangerous, given the known
vulnerabilities in SSLv2 and SSLv3.
Defaults to CURL_SSLVERSION_DEFAULT.
Available as of cURL 7.1.0.
It is better to not set this option and leave the defaults.
As setting this to
CURL_SSLVERSION_SSLv2
or
CURL_SSLVERSION_SSLv3
is very dangerous, given the known
vulnerabilities in SSLv2 and SSLv3.
A colon-separated string of ciphers to use
for the TLS 1.2 (1.1, 1.0) connection.
Available as of cURL 7.9.
A colon delimited list of elliptic curve algorithms. For example,
X25519:P-521 is a valid list of two elliptic curves.
This option defines the client's key exchange algorithms in the SSL handshake,
if the SSL backend cURL is built to use supports it.
Available as of PHP 8.2.0 and cURL 7.73.0.
to disable ALPN in the SSL handshake (if the SSL backend
cURL is built to use supports it), which can be used to
negotiate http2.
Available as of PHP 7.0.7 and cURL 7.36.0.
to disable NPN in the SSL handshake (if the SSL backend
cURL is built to use supports it), which can be used to
negotiate http2.
Available as of PHP 7.0.7 and cURL 7.36.0, and deprecated as of cURL 7.86.0.
to enable and to disable TLS false start
which is a mode where a TLS client starts sending application data
before verifying the server's Finished message.
Available as of PHP 7.0.7 and cURL 7.42.0.
Set SSL behavior options, which is a bitmask of the
CURLSSLOPT_* constants.
Defaults to none of the bits being set.
Available as of PHP 7.0.7. and cURL 7.25.0.
Set to 0 to disable and 1 to enable
SSL session-ID caching.
By default all transfers are done using the cache enabled.
Available as of cURL 7.16.0.
2 to verify that a Common Name field or a Subject Alternate Name
field in the SSL peer certificate matches the provided hostname.
0 to not check the names.
1 should not be used.
In production environments the value of this option
should be kept at 2 (default value). Support for value 1 removed in cURL 7.28.1.
Available as of cURL 7.8.1.
to stop cURL from verifying the peer's
certificate. Alternate certificates to verify against can be
specified with the CURLOPT_CAINFO option
or a certificate directory can be specified with the
CURLOPT_CAPATH option.
Defaults to as of cURL 7.10.
Default bundle of CA certificates installed as of cURL 7.10.
Available as of cURL 7.4.2.
to enable and to disable verification of the certificate's status.
Available as of PHP 7.0.7 and cURL 7.41.0.
Accepts a file handle resource pointing to
an alternative location to output errors to instead of
STDERR.
Available as of cURL 7.1.0.
Set the numerical stream weight (a number between 1 and 256).
Available as of PHP 7.0.7 and cURL 7.46.0.
to suppress proxy CONNECT response headers from the user callback functions
CURLOPT_HEADERFUNCTION and CURLOPT_WRITEFUNCTION,
when CURLOPT_HTTPPROXYTUNNEL is used and a CONNECT request is made.
Defaults to .
Available as of PHP 7.3.0 and cURL 7.54.0.
to enable and to disable TCP Fast Open.
Available as of PHP 7.0.7 and cURL 7.49.0.
If set to 1, TCP keepalive probes will be sent. The delay and
frequency of these probes can be controlled by the CURLOPT_TCP_KEEPIDLE
and CURLOPT_TCP_KEEPINTVL options, provided the operating system
supports them. If set to 0 (default) keepalive probes are disabled.
The maximum number of probes can be set with the CURLOPT_TCP_KEEPCNT
option.
Available as of cURL 7.25.0.
Sets the delay, in seconds, that the operating system will wait while the connection is
idle before sending keepalive probes, if CURLOPT_TCP_KEEPALIVE is
enabled. Not all operating systems support this option.
The default is 60.
Available as of cURL 7.25.0.
Sets the interval, in seconds, that the operating system will wait between sending
keepalive probes, if CURLOPT_TCP_KEEPALIVE is enabled.
Not all operating systems support this option.
The default is 60.
Available as of cURL 7.25.0.
Sets the maximum number of TCP keep-alive probes.
The default is 9.
Available as of PHP 8.4.0 and cURL 8.9.0.
to disable TCP's Nagle algorithm, which tries to minimize
the number of small packets on the network.
Defaults to .
Available as of cURL 7.11.2.
Set an array of strings to pass to the telnet negotiations.
The variables should be in the format option=value.
cURL supports the options TTYPE,
XDISPLOC and NEW_ENV.
Available as of cURL 7.7.0.
Set the blocksize to use for TFTP data transmission.
Valid range is 8-65464 bytes.
The default of 512 bytes is used if this option is not specified.
The specified block size is only used if supported by the remote server.
If the server does not return an option acknowledgment
or returns an option acknowledgment with no block size,
the default of 512 bytes is used.
Available as of cURL 7.19.4.
to not send TFTP options requests.
Defaults to .
Available as of PHP 7.0.7 and cURL 7.48.0.
Set how CURLOPT_TIMEVALUE is treated.
Use CURL_TIMECOND_IFMODSINCE to return the
page only if it has been modified since the time specified in
CURLOPT_TIMEVALUE. If it hasn't been modified,
a 304 Not Modified header will be returned
assuming CURLOPT_HEADER is .
Use CURL_TIMECOND_IFUNMODSINCE for the reverse
effect. Use CURL_TIMECOND_NONE to ignore
CURLOPT_TIMEVALUE and always return the page.
CURL_TIMECOND_NONE is the default.
Prior to cURL 7.46.0 the default was
CURL_TIMECOND_IFMODSINCE.
Available as of cURL 7.1.0.
The maximum number of seconds to allow cURL functions to execute.
Defaults to 0, meaning that functions never time out during transfer.
Available as of cURL 7.1.0.
The maximum number of milliseconds to allow cURL functions to
execute.
If cURL is built to use the standard system name resolver, that
portion of the connect will still use full-second resolution for
timeouts with a minimum timeout allowed of one second.
Defaults to 0, meaning that functions never time out during transfer.
Available as of cURL 7.16.2.
The time in seconds since January 1st, 1970. The time will be used
by CURLOPT_TIMECONDITION.
Defaults to 0.
Available as of cURL 7.1.0.
The time in seconds since January 1st, 1970. The time will be used
by CURLOPT_TIMECONDITION. Defaults to zero.
The difference between this option and CURLOPT_TIMEVALUE
is the type of the argument. On systems where 'long' is only 32 bit wide,
this option has to be used to set dates beyond the year 2038.
Available as of PHP 7.3.0 and cURL 7.59.0.
A string with a colon-separated list of ciphers
to use for the connection to the TLS 1.3 connection.
This option is currently used only when cURL is built to use OpenSSL 1.1.1 or later.
When using a different SSL backend the TLS 1.3 cipher suites can be set
with the CURLOPT_SSL_CIPHER_LIST option.
Available as of PHP 7.3.0 and cURL 7.61.0.
Set a password to use for the TLS authentication method specified
with the CURLOPT_TLSAUTH_TYPE option. Requires that
the CURLOPT_TLSAUTH_USERNAME option also be set.
This feature relies on TLS SRP which does not work with TLS 1.3.
Available as of cURL 7.21.4.
Set a string with the method of the TLS authentication.
Supported method is SRP
(TLS Secure Remote Password authentication).
Available as of cURL 7.21.4.
Set a string with the username to use for the TLS authentication method
specified with the CURLOPT_TLSAUTH_TYPE option.
Requires that the CURLOPT_TLSAUTH_PASSWORD option
also be set.
This feature relies on TLS SRP which does not work with TLS 1.3.
Available as of cURL 7.21.4.
Set to 1 to enable and 0 to disable
requesting compressed Transfer Encoding in the outgoing
HTTP request. If the server responds with a compressed
Transfer Encoding,
cURL will automatically uncompress it on reception.
Defaults to 0.
Available as of cURL 7.21.6.
to use ASCII mode for FTP transfers.
For LDAP, it retrieves data in plain text instead of HTML. On
Windows systems, it will not set STDOUT to binary
mode.
Defaults to .
Available as of cURL 7.1.1.
Enables the use of Unix domain sockets as connection endpoint and
sets the path to the given string.
Set to to disable.
Defaults to .
Available as of PHP 7.0.7 and cURL 7.40.0.
to keep sending the username and password
when following locations (using
CURLOPT_FOLLOWLOCATION), even when the
hostname has changed.
Defaults to .
Available as of cURL 7.10.4.
Some protocols have "connection upkeep" mechanisms. These mechanisms usually send some traffic
on existing connections in order to keep them alive. This option defines the connection upkeep interval.
Currently, the only protocol with a connection upkeep mechanism is HTTP/2. When the connection upkeep
interval is exceeded, an HTTP/2 PING frame is sent on the connection.
Defaults to CURL_UPKEEP_INTERVAL_DEFAULT
which is currently 60 seconds.
Available as of PHP 8.2.0 and cURL 7.62.0.
to prepare for and perform an upload.
Defaults to .
Available as of cURL 7.1.0.
Preferred buffer size in bytes for the cURL upload buffer.
The upload buffer size by default is 64 kilobytes. The maximum buffer size allowed to be set is 2 megabytes.
The minimum buffer size allowed to be set is 16 kilobytes.
Available as of PHP 8.2.0 and cURL 7.62.0.
The URL to fetch. This can also be set when initializing a
session with curl_init.
Available as of cURL 7.1.0.
Sets the desired level of SSL/TLS for the transfer
when using FTP, SMTP, POP3, IMAP, etc.
These are all protocols that start out plain text
and get "upgraded" to SSL using the STARTTLS command.
Set to one of the
CURLUSESSL_* constants.
Available as of cURL 7.17.0.
The contents of the User-Agent: header to be
used in a HTTP request.
Available as of cURL 7.1.0.
The user name to use in authentication.
Available as of cURL 7.19.1.
A username and password formatted as
[username]:[password] to use for the
connection.
Available as cURL 7.1.0.
to output verbose information. Writes
output to STDERR, or the file specified using
CURLOPT_STDERR.
Defaults to .
Available as of cURL 7.1.0.
Set to 1 to transfer multiple files
according to a filename pattern.
The pattern can be specified as part of the
CURLOPT_URL option,
using an fnmatch-like pattern (Shell Pattern Matching)
in the last part of URL (filename).
Available as of cURL 7.21.0.
A callable with the following signature:
intcallback
resourcecurlHandle
stringdata
curlHandle
The cURL handle.
data
The data to be written.
The data must be saved by the callback
and the callback must return the exact number of bytes written
or the transfer will be aborted with an error.
Available as of cURL 7.1.0.
The cURL handle.
The data to be written.
Accepts a file handle resource to the file that the header part of the transfer is written to.
Available as of cURL 7.1.0.
Accepts a bitmask setting WebSocket behavior options.
The only available option is CURLWS_RAW_MODE.
Defaults to 0.
Available as of PHP 8.3.0 and cURL 7.86.0.
A callable with the following signature:
intcallback
resourcecurlHandle
intbytesToDownload
intbytesDownloaded
intbytesToUpload
intbytesUploaded
curlHandle
The cURL handle.
bytesToDownload
The total number of bytes expected to be downloaded in this transfer.
bytesDownloaded
The number of bytes downloaded so far.
bytesToUpload
The total number of bytes expected to be uploaded in this transfer.
bytesUploaded
The number of bytes uploaded so far.
Return 1 to abort the transfer
and set a CURLE_ABORTED_BY_CALLBACK error.
Available as of PHP 8.2.0 and cURL 7.32.0.
The cURL handle.
The total number of bytes expected to be downloaded in this transfer.
The number of bytes downloaded so far.
The total number of bytes expected to be uploaded in this transfer.
The number of bytes uploaded so far.
A timeout in seconds cURL will wait for a response from an
FTP, SFTP, IMAP,
SCP, SMTP, or a POP3 server.
This option replaces the existing CURLOPT_FTP_RESPONSE_TIMEOUT
option which is deprecated in cURL 7.85.0.
Available as of PHP 8.4.0.
Specifies the OAuth 2.0 access token.
Set to to disable.
Defaults to .
Available as of PHP 7.0.7 and cURL 7.33.0.
A callable with the following signature that gets called after the
connection is established, but before the request payload (for example, the
GET/POST/DELETE request of an HTTP connection) is sent, and can be used to abort
or allow the connection depending on the source and destination IP address and
port numbers:
intcallback
CurlHandlecurlHandle
stringdestination_ip
stringlocal_ip
intdestination_port
intlocal_port
curlHandle
The cURL handle.
destination_ip
The primary IP of the remote server established with this connection.
For FTP, this is the IP for the control connection.
IPv6 addresses are represented without surrounding brackets.
local_ip
The originating IP for this connection.
IPv6 addresses are represented without surrounding brackets.
destination_port
The primary port number on the remote server established with this connection.
For FTP, this is the port for the control connection.
This can be a TCP or a UDP port number depending on the protocol.
local_port
The originating port number for this connection.
This can be a TCP or a UDP port number depending on the protocol.
Return CURL_PREREQFUNC_OK to allow the request, or
CURL_PREREQFUNC_ABORT to abort the transfer.
Available as of PHP 8.4.0 and cURL 7.80.0.
The cURL handle.
The primary IP of the remote server established with this connection.
For FTP, this is the IP for the control connection.
IPv6 addresses are represented without surrounding brackets.
The originating IP for this connection.
IPv6 addresses are represented without surrounding brackets.
The primary port number on the remote server established with this connection.
For FTP, this is the port for the control connection.
This can be a TCP or a UDP port number depending on the protocol.
The originating port number for this connection.
This can be a TCP or a UDP port number depending on the protocol.
Available as of PHP 8.4.0.
This option requires CURLOPT_VERBOSE option enabled.
A callable to replace the standard cURL verbose output.
This callback gets called during various stages of the request with verbose debug information.
The callback should match the following signature:
voidcallback
CurlHandlecurlHandle
inttype
stringdata
curlHandle
The cURL handle.
type
One of the following constants indicating the type of the data value:
CURLINFO_TEXT
(int)
Informational text.
CURLINFO_HEADER_IN
(int)
Header (or header-like) data received from the peer.
CURLINFO_HEADER_OUT
(int)
Header (or header-like) data sent to the peer.
CURLINFO_DATA_IN
(int)
Unprocessed protocol data received from the peer.
Even if the data is encoded or compressed, it is not provided decoded nor decompressed to this callback.
CURLINFO_DATA_OUT
(int)
Protocol data sent to the peer.
CURLINFO_SSL_DATA_IN
(int)
SSL/TLS (binary) data received from the peer.
CURLINFO_SSL_DATA_OUT
(int)
SSL/TLS (binary) data sent to the peer.
data
Verbose debug data of the type indicate by the type parameter.
The cURL handle.
One of the following constants indicating the type of the data value:
Informational text.
Header (or header-like) data received from the peer.
Header (or header-like) data sent to the peer.
Unprocessed protocol data received from the peer.
Even if the data is encoded or compressed, it is not provided decoded nor decompressed to this callback.
Protocol data sent to the peer.
SSL/TLS (binary) data received from the peer.
SSL/TLS (binary) data sent to the peer.
Verbose debug data of the type indicate by the type parameter.
cURL protocol constants
Available as of cURL 7.19.4.
Available as of cURL 7.19.4.
Available as of cURL 7.19.4.
Available as of cURL 7.19.4.
Available as of cURL 7.19.4.
Available as of cURL 7.21.2.
Available as of cURL 7.19.4.
Available as of cURL 7.19.4.
Available as of cURL 7.20.0.
Available as of cURL 7.20.0.
Available as of cURL 7.19.4.
Available as of cURL 7.19.4.
Available as of PHP 8.2.0 and cURL 7.71.0.
Available as of cURL 7.20.0.
Available as of cURL 7.20.0.
Available as of cURL 7.21.0.
Available as of cURL 7.21.0.
Available as of cURL 7.21.0.
Available as of cURL 7.21.0.
Available as of cURL 7.21.0.
Available as of cURL 7.21.0.
Available as of cURL 7.20.0.
Available as of cURL 7.19.4.
Available as of cURL 7.19.4.
Available as of PHP 7.0.7 and cURL 7.40.0.
Available as of PHP 7.0.7 and cURL 7.40.0.
Available as of cURL 7.20.0.
Available as of cURL 7.20.0.
Available as of cURL 7.19.4.
Available as of cURL 7.19.4.
curl_share_setopt
Shares/unshares the connection cache.
Available as of PHP 7.3.0 and cURL 7.10.3.
Shares/unshares cookie data.
Available as of cURL 7.10.3.
Shares/unshares DNS cache.
Note that when you use cURL multi handles,
all handles added to the same multi handle will share DNS cache by default.
Available as of cURL 7.10.3.
Shares/unshares the Public Suffix List.
Available as of PHP 7.3.0 and cURL 7.61.0.
Shares/unshares SSL session IDs, reducing the time spent
on the SSL handshake when reconnecting to the same server.
Note that SSL session IDs are reused within the same handle by default.
Available as of cURL 7.10.3.
Available as of cURL 7.10.3.
Specifies a type of data that should be shared.
Available as of cURL 7.10.3.
Specifies a type of data that will be no longer shared.
Available as of cURL 7.10.3.
curl_multi_* status constants
An easy handle already added to a multi handle was attempted to get added a second time.
Available as of cURL 7.32.1.
An easy handle was not good/valid. It could mean that it is not an easy handle at all, or possibly that the handle already is in use by this or another multi handle.
Available as of cURL 7.9.6.
The passed-in handle is not a valid multi handle.
Available as of cURL 7.9.6.
As of cURL 7.20.0, this constant is not used.
Before cURL 7.20.0, this status could be returned by
curl_multi_exec when curl_multi_select
or a similar function was called before it returned any other constant.
Available as of cURL 7.9.6.
Internal libcurl error.
Available as of cURL 7.9.6.
No errors.
Available as of cURL 7.9.6.
Ran out of memory while processing multi handles.
Available as of cURL 7.9.6.
curl_getinfo
Time in seconds it took from the start until the SSL/SSH connect/handshake to the remote host was completed
Time, in microseconds, it took from the start until the SSL/SSH connect/handshake to the remote host was completed.
Available as of PHP 7.3.0 and cURL 7.61.0
Default built-in CA certificate path.
Available as of PHP 8.3.0 and cURL 7.84.0
Default built-in CA path string.
Available as of PHP 8.3.0 and cURL 7.84.0
TLS certificate chain
Info on unmet time conditional
Time in seconds it took to establish the connection
Total time taken, in microseconds, from the start until the connection to the remote host (or proxy) was completed.
Available as of PHP 7.3.0 and cURL 7.61.0
Content length of download, read from Content-Length: field
The content-length of the download. This is the value read from the Content-Length: field. -1 if the size isn't known.
Available as of PHP 7.3.0 and cURL 7.55.0
Specified size of upload
The specified size of the upload. -1 if the size isn't known.
Available as of PHP 7.3.0 and cURL 7.55.0
Content-Type of the requested document.
NULL indicates server did not send valid Content-Type header
All known cookies
Get the last used HTTP method.
Last effective URL
Remote time of the retrieved document, with the CURLOPT_FILETIME enabled; if -1 is returned the time of the document is unknown
Remote time of the retrieved document (as Unix timestamp), an alternative to CURLINFO_FILETIME to allow systems with 32 bit long variables to extract dates outside of the 32bit timestamp range.
Available as of PHP 7.3.0 and cURL 7.59.0
Entry path in FTP server
The request string sent. For this to work, add the CURLINFO_HEADER_OUT option to the handle by calling curl_setopt
Total size of all headers received
Bitmask indicating the authentication method(s) available according to the previous response
The last response code.
As of cURL 7.10.8, this is a legacy alias of CURLINFO_RESPONSE_CODE.
The CONNECT response code
The version used in the last HTTP connection. The return value will be one of the defined CURL_HTTP_VERSION_* constants or 0 if the version can't be determined.
Available as of PHP 7.3.0 and cURL 7.50.0
The last enum value in the underlying CURLINFO enum
in libcurl.
Local (source) IP address of the most recent connection
Local (source) port of the most recent connection
Time in seconds until name resolving was complete
Time in microseconds from the start until the name resolving was completed.
Available as of PHP 7.3.0 and cURL 7.61.0
Number of connections curl had to create to achieve the previous transfer
Errno from a connect failure. The number is OS and system specific.
Time in seconds from start until just before file transfer begins
Time taken from the start until the file transfer is just about to begin, in microseconds.
Available as of PHP 7.3.0 and cURL 7.61.0
IP address of the most recent connection
Destination port of the most recent connection
Private data associated with this cURL handle, previously set with the CURLOPT_PRIVATE option of curl_setopt
The protocol used in the last HTTP connection. The returned value will be exactly one of the CURLPROTO_* values.
Available as of PHP 7.3.0 and cURL 7.52.0
Bitmask indicating the proxy authentication method(s) available according to the previous response
The detailed (SOCKS) proxy error code when the most recent transfer returned a CURLE_PROXY error. The returned value will be exactly one of the CURLPX_* values. The error code will be CURLPX_OK if no response code was available.
Available as of PHP 8.2.0 and cURL 7.73.0
The result of the certificate verification that was requested (using the CURLOPT_PROXY_SSL_VERIFYPEER option). Only used for HTTPS proxies.
Available as of PHP 7.3.0 and cURL 7.52.0
Number of redirects, with the CURLOPT_FOLLOWLOCATION option enabled
Time in seconds of all redirection steps before final transaction was started, with the CURLOPT_FOLLOWLOCATION option enabled
Total time, in microseconds, it took for all redirection steps include name lookup, connect, pretransfer and transfer before final transaction was started.
Available as of PHP 7.3.0 and cURL 7.61.0
With the CURLOPT_FOLLOWLOCATION option disabled: redirect URL found in the last transaction, that should be requested manually next. With the CURLOPT_FOLLOWLOCATION option enabled: this is empty. The redirect URL in this case is available in CURLINFO_EFFECTIVE_URL
The Referer header.
Available as of PHP 8.2.0 and cURL 7.76.0
Total size of issued requests, currently only for HTTP requests
The last response code.
Available as of cURL 7.10.8
The information from the Retry-After header, or zero if there was no valid header.
Available as of PHP 8.2.0 and cURL 7.66.0
Next RTSP client CSeq
Recently received CSeq
Next RTSP server CSeq
RTSP session ID
The URL scheme used for the most recent connection.
Available as of PHP 7.3.0 and cURL 7.52.0
Total number of bytes downloaded
Total number of bytes that were downloaded. The number is only for the latest transfer and will be reset again for each new transfer.
Available as of PHP 7.3.0 and cURL 7.50.0
Total number of bytes uploaded
Total number of bytes that were uploaded.
Available as of PHP 7.3.0 and cURL 7.50.0
Average download speed
The average download speed in bytes/second that curl measured for the complete download.
Available as of PHP 7.3.0 and cURL 7.50.0
Average upload speed
The average upload speed in bytes/second that curl measured for the complete upload.
Available as of PHP 7.3.0 and cURL 7.50.0
OpenSSL crypto-engines supported
Result of SSL certification verification requested by setting CURLOPT_SSL_VERIFYPEER
Time in seconds until the first byte is about to be transferred
Time, in microseconds, it took from the start until the first byte is received.
Available as of PHP 7.3.0 and cURL 7.61.0
Total transaction time in seconds for last transfer
Total time in microseconds for the previous transfer, including name resolving, TCP connect etc.
Available as of PHP 7.3.0 and cURL 7.61.0
Time it took from the start until the last byte is sent, in microseconds.
Available as of PHP 8.4.0 and cURL 8.10.0
cURL error constants
Aborted by callback. A callback returned "abort" to libcurl.
Unrecognized transfer encoding.
The download could not be resumed because the specified offset was out of the file boundary.
A function was called with a bad parameter.
Failed to connect to host or proxy.
Could not resolve host. The given remote host was not resolved.
Could not resolve proxy. The given proxy host could not be resolved.
Early initialization code failed.
This is likely to be an internal error or problem,
or a resource problem where something fundamental could not get done at init time.
Maximum file size exceeded.
A file given with FILE:// could not be opened.
Most likely because the file path does not identify an existing file
or due to the lack of appropriate file permissions.
An internal failure to lookup the host used for the new connection.
This was either a unexpected reply to a 'RETR' command
or a zero byte transfer complete.
The FTP REST command returned error.
This should never happen if the server is sane.
The FTP PORT command returned error.
This mostly happens when a good enough address has not been specified for libcurl to use.
See CURLOPT_FTPPORT.
FTP servers return a 227-line as a response to a PASV command.
If libcurl fails to parse that line, this return code is passed back.
After having sent the FTP password to the server, libcurl expects a proper reply.
This error code indicates that an unexpected code was returned.
libcurl failed to get a sensible result back from the server
as a response to either a PASV or a EPSV command. The server is flawed.
The server sent data libcurl could not parse.
This error code is known as CURLE_WEIRD_SERVER_REPLY
as of cURL 7.51.0.
Function not found. A required zlib function was not found.
Nothing was returned from the server, and under the circumstances,
getting nothing is considered an error.
This is an odd error that mainly occurs due to internal confusion.
This is returned if CURLOPT_FAILONERROR is set
and the HTTP server returns an error code that is greater than or equal to 400.
LDAP cannot bind. LDAP bind operation failed.
LDAP search failed.
All fine. Proceed as usual.
Operation timeout.
The specified time-out period was reached according to the conditions.
A memory allocation request failed.
A file transfer was shorter or larger than expected.
This happens when the server first reports an expected transfer size,
and then delivers data that does not match the previously given size.
Proxy handshake error.
CURLINFO_PROXY_ERROR provides extra details on the specific problem.
Available as of PHP 8.2.0 and cURL 7.73.0
There was a problem reading a local file or an error returned by the read callback.
Failure with receiving network data.
Failed sending network data.
An unspecified error occurred during the SSH session.
Available as of cURL 7.16.1.
Problem with reading the SSL CA cert.
Problem with the local client certificate.
Could not use specified cipher.
A problem occurred somewhere in the SSL/TLS handshake.
Reading the message in the error buffer provides more details on the problem.
Could be certificates (file formats, paths, permissions), passwords, and others.
The specified crypto engine was not found.
Failed setting the selected SSL crypto engine as default.
Failed to match the pinned key specified with
CURLOPT_PINNEDPUBLICKEY.
Too many redirects. When following redirects, libcurl hit the maximum amount.
The limit can be set with CURLOPT_MAXREDIRS.
The URL passed to libcurl used a protocol that libcurl does not support.
The issue might be a compile-time option that was not used,
a misspelled protocol string or just a protocol libcurl has no code for.
The URL was not properly formatted.
The server sent data libcurl could not parse.
This error code was known as CURLE_FTP_WEIRD_SERVER_REPLY
before cURL 7.51.0.
Available as of PHP 7.3.0 and cURL 7.51.0
An error occurred when writing received data to a local file,
or an error was returned to libcurl from a write callback.
curl_pause
Pause sending and receiving data.
Available as of cURL 7.18.0.
Unpause sending and receiving data.
Available as of cURL 7.18.0.
Pause receiving data.
Available as of cURL 7.18.0.
Unpause receiving data.
Available as of cURL 7.18.0.
Pause sending data.
Available as of cURL 7.18.0.
Unpause sending data.
Available as of cURL 7.18.0.
curl_multi_setopt
Specifies the chunk length threshold for pipelining in bytes.
Available as of PHP 7.0.7 and cURL 7.30.0
Specifies the size threshold for pipelining penalty in bytes.
Available as of PHP 7.0.7 and cURL 7.30.0
Specifies the maximum amount of simultaneously open connections
that libcurl may cache.
By default the size will be enlarged to fit four times the number
of handles added via curl_multi_add_handle.
When the cache is full, curl closes the oldest one in the cache
to prevent the number of open connections from increasing.
Available as of cURL 7.16.3.
Specifies the maximum number of concurrent streams for connections
that cURL should support on connections using HTTP/2.
Valid values range from 1
to 2147483647 (2^31 - 1).
The value passed here would be honored
based on other system resources properties.
Default is 100.
Available as of PHP 8.2.0 and cURL 7.67.0.
Specifies the maximum number of connections to a single host.
Available as of PHP 7.0.7 and cURL 7.30.0
Specifies the maximum number of requests in a pipeline.
Available as of PHP 7.0.7 and cURL 7.30.0
Specifies the maximum number of simultaneously open connections.
Available as of PHP 7.0.7 and cURL 7.30.0
Pass 1 to enable or 0 to disable. Enabling pipelining on a multi
handle will make it attempt to perform HTTP Pipelining as far as
possible for transfers using this handle. This means that adding
a second request that can use an already existing connection will "pipe"
the second request on the same connection.
As of cURL 7.43.0, the value is a bitmask,
and passing 2 will try to multiplex the new
transfer over an existing HTTP/2 connection.
Passing 3 instructs cURL to ask for pipelining and multiplexing
independently of each other.
As of cURL 7.62.0, setting the pipelining bit has no effect.
Instead of integer literals, the CURLPIPE_* constants can also be used.
Available as of cURL 7.16.0.
Pass a callable that will be registered to handle server
pushes and should have the following signature:
intpushfunction
resourceparent_ch
resourcepushed_ch
arrayheaders
parent_ch
The parent cURL handle (the request the client made).
pushed_ch
A new cURL handle for the pushed request.
headers
The push promise headers.
The push function is supposed to return either
CURL_PUSH_OK if it can handle the push, or
CURL_PUSH_DENY to reject it.
Available as of PHP 7.1.0 and cURL 7.44.0
The parent cURL handle (the request the client made).
A new cURL handle for the pushed request.
The push promise headers.
Installing OCI8 from PECL Using the pecl Command
The OCI8 extension can be added to an existing PHP installation by using
the PECL repository.
If you are behind a firewall, set PEAR's proxy, for example:
pear config-set http_proxy http://my-proxy.example.com:80/
Run
pecl install oci8
For PHP 7, use pecl install oci8-2.2.0
When prompted, enter either the value of $ORACLE_HOME, or
instantclient,/path/to/instant/client/lib.
Note: Do not enter variable names like $ORACLE_HOME
or $HOME because pecl will not
expand them. Instead, enter an expanded path, for
example /opt/oracle/product/19c/dbhome_1
or instantclient,/Users/myname/Downloads/instantclient_19_8
If you get an error oci8_dtrace_gen.h: No such file or
directory, it means PHP was built
with DTrace Dynamic Tracing enabled.
Install using:
$ export PHP_DTRACE=yes
$ pecl install oci8
Edit your file and add the line:
extension=oci8.so
Make sure the
directive extension_dir is
set to the directory that oci8.so was installed
in.
If you are behind a firewall, set PEAR's proxy, for example:
pear config-set http_proxy http://my-proxy.example.com:80/
Run
pecl install oci8
For PHP 7, use pecl install oci8-2.2.0
When prompted, enter either the value of $ORACLE_HOME, or
instantclient,/path/to/instant/client/lib.
Note: Do not enter variable names like $ORACLE_HOME
or $HOME because pecl will not
expand them. Instead, enter an expanded path, for
example /opt/oracle/product/19c/dbhome_1
or instantclient,/Users/myname/Downloads/instantclient_19_8
If you get an error oci8_dtrace_gen.h: No such file or
directory, it means PHP was built
with DTrace Dynamic Tracing enabled.
Install using:
$ export PHP_DTRACE=yes
$ pecl install oci8
Edit your file and add the line:
extension=oci8.so
Make sure the
directive extension_dir is
set to the directory that oci8.so was installed
in.
Installing OCI8 from PECL Using phpize
To install OCI8 on an existing PHP installation when
the pecl command is not available, manually download
the PECL OCI8 package,
e.g. oci8-3.0.0.tgz.
Extract the package:
tar -zxf oci8-3.0.0.tgz
cd oci8-3.0.0
Prepare the package:
phpize
Configure the package, either
using $ORACLE_HOME or Instant Client
./configure -with-oci8=shared,$ORACLE_HOME
or
./configure -with-oci8=shared,instantclient,/path/to/instant/client/lib
Install the package:
make install
If you get an error oci8_dtrace_gen.h: No such file or
directory, it means PHP was built
with DTrace Dynamic Tracing enabled.
Re-run the configure and make
commands after setting this environment variable:
$ export PHP_DTRACE=yes
Edit your file and add the line:
extension=oci8.so
Make sure the
directive extension_dir is
set to the directory that oci8.so was installed
in.
Extract the package:
tar -zxf oci8-3.0.0.tgz
cd oci8-3.0.0
Prepare the package:
phpize
Configure the package, either
using $ORACLE_HOME or Instant Client
./configure -with-oci8=shared,$ORACLE_HOME
or
./configure -with-oci8=shared,instantclient,/path/to/instant/client/lib
Install the package:
make install
If you get an error oci8_dtrace_gen.h: No such file or
directory, it means PHP was built
with DTrace Dynamic Tracing enabled.
Re-run the configure and make
commands after setting this environment variable:
$ export PHP_DTRACE=yes
Edit your file and add the line:
extension=oci8.so
Make sure the
directive extension_dir is
set to the directory that oci8.so was installed
in.
Installing OCI8 as a Shared Extension when Building PHP
If you are building PHP from source code, the
configuration shared option can be used to build OCI8 as a shared library
that can be dynamically loaded into PHP. Building a shared extension allows
OCI8 to be upgraded easily without impacting the rest of PHP.
Configure OCI8 using one of the following configure options.
If using the free Oracle Instant
Client libraries, then do:
./configure --with-oci8=shared,instantclient,/path/to/instant/client/lib
If Instant Client 12.2 (or earlier) is installed from ZIP files, make sure to create
the library symbolic link first, for example ln -s
libclntsh.so.12.1 libclntsh.so.
If using an RPM-based installation of Oracle Instant Client, the
configure line will look like this:
./configure --with-oci8=shared,instantclient,/usr/lib/oracle/<version>/client/lib
For example, --with-oci8=shared,instantclient,/usr/lib/oracle/19.9/client/lib
If using an Oracle database or full Oracle Client installation then do:
./configure --with-oci8=shared,$ORACLE_HOME
Make sure the web server user
(nobody, www) has access to
the libraries, initialization files
and tnsnames.ora (if used) under
the $ORACLE_HOME directory. With Oracle
10gR2, you may need to run
the $ORACLE_HOME/install/changePerm.sh
utility to give directory access.
If using the free Oracle Instant
Client libraries, then do:
./configure --with-oci8=shared,instantclient,/path/to/instant/client/lib
If Instant Client 12.2 (or earlier) is installed from ZIP files, make sure to create
the library symbolic link first, for example ln -s
libclntsh.so.12.1 libclntsh.so.
If using an RPM-based installation of Oracle Instant Client, the
configure line will look like this:
./configure --with-oci8=shared,instantclient,/usr/lib/oracle/<version>/client/lib
For example, --with-oci8=shared,instantclient,/usr/lib/oracle/19.9/client/lib
If using an Oracle database or full Oracle Client installation then do:
./configure --with-oci8=shared,$ORACLE_HOME
Make sure the web server user
(nobody, www) has access to
the libraries, initialization files
and tnsnames.ora (if used) under
the $ORACLE_HOME directory. With Oracle
10gR2, you may need to run
the $ORACLE_HOME/install/changePerm.sh
utility to give directory access.
After configuration, follow the usual PHP building procedure,
e.g. make install. The OCI8 shared extension
oci8.so library will be created. It may need
to be manually moved to the PHP extension directory, specified by
the extension_dir option in
your file.
To complete installation of OCI8, edit and add the line:
extension=oci8.so
Installing OCI8 as a Statically Compiled Extension when Building PHP
If you are building PHP from source code, you can configure PHP to include
OCI8 as a static extension using one of the following configure options.
If using Oracle Instant Client, then do:
./configure --with-oci8=instantclient,/path/to/instant/client/lib
If using an Oracle database or full Oracle Client installation then do:
./configure --with-oci8=$ORACLE_HOME
If using Oracle Instant Client, then do:
./configure --with-oci8=instantclient,/path/to/instant/client/lib
If using an Oracle database or full Oracle Client installation then do:
./configure --with-oci8=$ORACLE_HOME
After configuration, follow the usual PHP building procedure,
e.g. make install. After successful
compilation, you do not need to add oci8.so to
. No additional build steps are required.
Installing OCI8 on Windows
The OCI8 extension can be added to an existing PHP installation by using the
DLLs from PECL repository or
the libraries in your PHP installation's ext directory.
With Oracle 12c (or later) libraries, uncomment one of
the lines extension=php_oci8_12c.dll
or extension=php_oci8_11g.dll
or extension=php_oci8.dll. Only one of these DLLs may be
enabled at a time. DLLs with higher versions may contain more
functionality. Not all DLLs may be available for all versions of PHP. Make
sure extension_dir is set to the
directory containing the PHP extension DLLs.
If using Instant Client, set the system PATH
environment variable to the Oracle library directory.
Setting the Oracle Environment
Before using this extension, make sure that the Oracle environment
variables are properly set for the web daemon user. If your web
server is automatically started at boot time then make sure that the
boot-time environment is also configured correctly.
Do not set Oracle environment variables
using putenv in a PHP script because Oracle
libraries may be loaded and initialized before your script
runs. Variables set with putenv may then cause
conflicts, crashes, or unpredictable behavior. Some functions may
work but others might give subtle errors. The variables should be
set up before the web server is started.
On Red Hat Linux and variants, export variables at the end of
/etc/sysconfig/httpd. Other systems with
Apache 2 may use an envvars script in the
Apache bin directory. A third option, the
Apache SetEnv directive
in httpd.conf, may work in some systems but is
known to be insufficient in others.
To check that environment variables are set correctly,
use phpinfo and check
the Environment (not the Apache
Environment) section contains the expected variables.
The variables that might be needed are included in the following
table. Refer to the Oracle documentation for more information on
all the available variables.
Common Oracle Environment Variables
Name
Purpose
ORACLE_HOME
Contains the directory of the full Oracle Database
software. Do not set this when using Oracle Instant Client as
it is unnecessary and may cause installation problems.
ORACLE_SID
Contains the name of the database on the local machine to
be connected to. There is no need to set this if you using
Oracle Instant Client, or always pass the connection parameter
to oci_connect.
LD_LIBRARY_PATH
Set this (or its platform equivalent, such
as LIBPATH, or SHLIB_PATH) to the
location of the Oracle libraries, for
example $ORACLE_HOME/lib
or /usr/lib/oracle/18.5/client/lib. Note with Instant
Client ZIP files on Linux it is more reliable to
use ldconfig instead, see the Instant Client
installation instructions. With Instant Client 19 (or later) RPM
files, ldconfig is automatically run for you. Some
users use
LD_PRELOAD instead
of LD_LIBRARY_PATH.
NLS_LANG
This is the primary variable for setting the character
set and globalization information used by the Oracle
libraries.
ORA_SDTZ
Sets the Oracle session timezone.
TNS_ADMIN
Contains the directory where the Oracle Net Services configuration
files such as tnsnames.ora
and sqlnet.ora are kept. Not needed if
the oci_connect connection string uses the Easy
Connect naming syntax such as localhost/XE. Not needed
if the network configuration files are in one of the default locations
such
as /usr/lib/oracle/VERSION/client/lib/network/admin, $ORACLE_HOME/network/admin
or /etc.
Less frequently used Oracle environment variables include
TWO_TASK, ORA_TZFILE, and the
various Oracle globalization settings
like NLS* and the ORA_NLS_*
variables.
Common Oracle Environment Variables
Troubleshooting
The most common problem with installing OCI8 is not having the
Oracle environment correctly set. This typically appears as a
problem using oci_connect
or oci_pconnect. The error may be a PHP error
such as Call to undefined function
oci_connect(), an Oracle error such as ORA-12705, or even
an Apache crash. Check the Apache log files for startup errors and
see the sections above to resolve this problem.
While network errors like ORA-12154 or ORA-12514 indicate an Oracle
network naming or configuration issue, the root cause may be because
the PHP environment is incorrectly set up and Oracle libraries are
unable to locate the tnsnames.ora configuration
file.
On Windows, having multiple versions of Oracle on the one machine
can easily cause library clashes unless care is taken to make sure
PHP only uses the correct version of Oracle.
A utility to examine what libraries are being looked for and loaded
can help resolve missing or clashing library issues, particularly on
Windows.
If the web server doesn't start or crashes at
startup
Check that Apache is linked with the pthread library:
# ldd /www/apache/bin/httpd
libpthread.so.0 => /lib/libpthread.so.0 (0x4001c000)
libm.so.6 => /lib/libm.so.6 (0x4002f000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x4004c000)
libdl.so.2 => /lib/libdl.so.2 (0x4007a000)
libc.so.6 => /lib/libc.so.6 (0x4007e000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
If the libpthread is not listed, then reinstall Apache:
# cd /usr/src/apache_1.3.xx
# make clean
# LIBS=-lpthread ./config.status
# make
# make install
Please note that on some systems like UnixWare, it is libthread
instead of libpthread. PHP and Apache have to be configured with
EXTRA_LIBS=-lthread.
Aliases and deprecated Mysqli
Many examples in this reference require an XML file. We will use
book.xml that contains the following:
book.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
]>
<book id="listing">
<title>My lists</title>
<chapter id="books">
<title>My books</title>
<para>
<informaltable>
<tgroup cols="4">
<thead>
<row>
<entry>Title</entry>
<entry>Author</entry>
<entry>Language</entry>
<entry>ISBN</entry>
</row>
</thead>
<tbody>
<row>
<entry>The Grapes of Wrath</entry>
<entry>John Steinbeck</entry>
<entry>en</entry>
<entry>0140186409</entry>
</row>
<row>
<entry>The Pearl</entry>
<entry>John Steinbeck</entry>
<entry>en</entry>
<entry>014017737X</entry>
</row>
<row>
<entry>Samarcande</entry>
<entry>Amine Maalouf</entry>
<entry>fr</entry>
<entry>2253051209</entry>
</row>
<!-- TODO: I have a lot of remaining books to add.. -->
</tbody>
</tgroup>
</informaltable>
</para>
</chapter>
</book>
book.xml
PCRE Patterns
Examples of valid patterns
/\/\w+/
|(\d{3})-\d+|Sm
/^(?i)php[34]/
{^\s+(\s+)?$}
Examples of valid patterns
/\/\w+/
|(\d{3})-\d+|Sm
/^(?i)php[34]/
{^\s+(\s+)?$}
Examples of invalid patterns
/href='(.*)' - missing ending delimiter
/\w+\s*\w+/J - unknown modifier 'J'
1-\d3-\d3-\d4| - missing starting delimiter
Examples of invalid patterns
/href='(.*)' - missing ending delimiter
/\w+\s*\w+/J - unknown modifier 'J'
1-\d3-\d3-\d4| - missing starting delimiter
In this example, we first define a base class and an extension
of the class. The base class describes a general vegetable,
whether it is edible, and what is its color. The subclass
Spinach adds a method to cook it and another to
find out if it is cooked.
Class Definitions
Vegetable
<?php
class Vegetable {
public $edible;
public $color;
public function __construct($edible, $color = "green")
{
$this->edible = $edible;
$this->color = $color;
}
public function isEdible()
{
return $this->edible;
}
public function getColor()
{
return $this->color;
}
}
?>
Spinach
<?php
class Spinach extends Vegetable {
public $cooked = false;
public function __construct()
{
parent::__construct(true, "green");
}
public function cook()
{
$this->cooked = true;
}
public function isCooked()
{
return $this->cooked;
}
}
?>
Class Definitions
Vegetable
Spinach
We then instantiate 2 objects from these classes and print out
information about them, including their class parentage.
We also define some utility functions, mainly to have a nice printout
of the variables.
test_script.php
<?php
// register autoloader to load classes
spl_autoload_register();
function printProperties($obj)
{
foreach (get_object_vars($obj) as $prop => $val) {
echo "\t$prop = $val\n";
}
}
function printMethods($obj)
{
$arr = get_class_methods(get_class($obj));
foreach ($arr as $method) {
echo "\tfunction $method()\n";
}
}
function objectBelongsTo($obj, $class)
{
if (is_subclass_of($obj, $class)) {
echo "Object belongs to class " . get_class($obj);
echo ", a subclass of $class\n";
} else {
echo "Object does not belong to a subclass of $class\n";
}
}
// instantiate 2 objects
$veggie = new Vegetable(true, "blue");
$leafy = new Spinach();
// print out information about objects
echo "veggie: CLASS " . get_class($veggie) . "\n";
echo "leafy: CLASS " . get_class($leafy);
echo ", PARENT " . get_parent_class($leafy) . "\n";
// show veggie properties
echo "\nveggie: Properties\n";
printProperties($veggie);
// and leafy methods
echo "\nleafy: Methods\n";
printMethods($leafy);
echo "\nParentage:\n";
objectBelongsTo($leafy, Spinach::class);
objectBelongsTo($leafy, Vegetable::class);
?>
veggie: CLASS Vegetable
leafy: CLASS Spinach, PARENT Vegetable
veggie: Properties
edible = 1
color = blue
leafy: Methods
function __construct()
function cook()
function isCooked()
function isEdible()
function getColor()
Parentage:
Object does not belong to a subclass of Spinach
Object belongs to class Spinach, a subclass of Vegetable
One important thing to note in the example above is that
the object $leafy is an instance of the class
Spinach which is a subclass of
Vegetable.
test_script.php
One important thing to note in the example above is that
the object $leafy is an instance of the class
Spinach which is a subclass of
Vegetable.
mqseries
Supported Character Encodings
Currently the following character encodings are supported by the
mbstring module. Any of those Character encodings
can be specified in the encoding parameter of
mbstring functions.
The following character encodings are supported in this PHP
extension:
UCS-4*
UCS-4BE
UCS-4LE*
UCS-2
UCS-2BE
UCS-2LE
UTF-32*
UTF-32BE*
UTF-32LE*
UTF-16*
UTF-16BE*
UTF-16LE*
UTF-7
UTF7-IMAP
UTF-8*
ASCII*
EUC-JP*
SJIS*
eucJP-win*
SJIS-win*
ISO-2022-JP
ISO-2022-JP-MS
CP932
CP51932
SJIS-mac (alias: MacJapanese)
SJIS-Mobile#DOCOMO (alias: SJIS-DOCOMO)
SJIS-Mobile#KDDI (alias: SJIS-KDDI)
SJIS-Mobile#SOFTBANK (alias: SJIS-SOFTBANK)
UTF-8-Mobile#DOCOMO (alias: UTF-8-DOCOMO)
UTF-8-Mobile#KDDI-A
UTF-8-Mobile#KDDI-B (alias: UTF-8-KDDI)
UTF-8-Mobile#SOFTBANK (alias: UTF-8-SOFTBANK)
ISO-2022-JP-MOBILE#KDDI (alias: ISO-2022-JP-KDDI)
JIS
JIS-ms
CP50220
CP50220raw
CP50221
CP50222
ISO-8859-1*
ISO-8859-2*
ISO-8859-3*
ISO-8859-4*
ISO-8859-5*
ISO-8859-6*
ISO-8859-7*
ISO-8859-8*
ISO-8859-9*
ISO-8859-10*
ISO-8859-13*
ISO-8859-14*
ISO-8859-15*
ISO-8859-16*
byte2be
byte2le
byte4be
byte4le
BASE64
HTML-ENTITIES (alias: HTML)
7bit
8bit
EUC-CN*
CP936
GB18030
HZ
EUC-TW*
CP950
BIG-5*
EUC-KR*
UHC (alias: CP949)
ISO-2022-KR
Windows-1251 (alias: CP1251)
Windows-1252 (alias: CP1252)
CP866 (alias: IBM866)
KOI8-R*
KOI8-U*
ArmSCII-8 (alias: ArmSCII8)
* denotes encodings usable also in regular expressions.
Any entry which accepts an encoding name
can also use the values auto and
pass.
mbstring functions which accept an encoding
name can also use the value auto.
If pass is set, no character
encoding conversion is performed.
If auto is set, it is expanded to
the list of encodings defined per the NLS.
For instance, if the NLS is set to Japanese,
the value is assumed to be
ASCII,JIS,UTF-8,EUC-JP,SJIS.
See also mb_detect_order