Skip to content

Instantly share code, notes, and snippets.

@romanitalian
Last active September 13, 2015 11:05
Show Gist options
  • Save romanitalian/04ee341128f14fb1148b to your computer and use it in GitHub Desktop.
Save romanitalian/04ee341128f14fb1148b to your computer and use it in GitHub Desktop.
php_features_by_versions
Main changes (short):
5.1 PDO enabled by default
5.2 Added data: stream support.
5.3 namespaces, closures, __callStatic() и __invoke()
5.4 traits, short array syntax
5.5 finally, generators (yield, range)
5.6 variadic functions, argument unpacking
7 return types, scalar type hints
------------------------------------------------------------------------------------------
PHP 7 некоторые новые ключевые возможности:
PHP 7 has been slated for release [in November of this year](https://wiki.php.net/rfc/php7timeline)
(2015). It comes with a number of new features, changes, and backwards
compatibility breakages that are outlined below.
Performance
Unarguably the greatest part about PHP 7 is the incredible performance boosts
it provides to applications. This is a result of refactoring the Zend Engine to
use more compact data structures and less heap allocations/deallocations.
The performance gains on real world applications will vary, though many
applications seem to receive a ~100% performance boost - with lower memory
consumption too!
The refactored codebase provides further opportunities for future optimisations
as well (such as JIT compilation). So it looks like future PHP versions will
continue to see performance enhancements too.
PHP 7 performance chart comparisons:
- [Turbocharging the Web with PHP 7](https://www.zend.com/en/resources/php7_infographic)
- [Benchmarks from Rasmus's Sydney Talk](http://talks.php.net/oz15#/drupalbench)
Features
Combined Comparison Operator
The combined comparison operator (or spaceship operator) is a shorthand
notation for performing three-way comparisons from two operands. It has an
integer return value that can be either:
* a positive integer (if the left-hand operand is greater than the right-hand operand)
* 0 (if both operands are equal)
* a negative integer (if the right-hand operand is greater than the left-hand operand)
The operator has the same precedence as the equality operators ('==', '!=',
'===', '!==') and has the exact same behaviour as the other loose comparison
operators ('<', '>=', etc). It is also non-associative like them too, so
chaining of the operands (like '1 <=> 2 <=> 3') is not allowed.
<?php
// compares strings lexically
var_dump('PHP' <=> 'Node'); // int(1)
// compares numbers by size
var_dump(123 <=> 456); // int(-1)
// compares corresponding array elements with one-another
var_dump(['a', 'b'] <=> ['a', 'b']); // int(0)
?>
Objects are not comparable, and so using them as operands with this operator
will result in undefined behaviour.
RFC: [Combined Comparison Operator](https://wiki.php.net/rfc/combined-comparison-operator)
Null Coalesce Operator
The null coalesce operator (or isset ternary operator) is a shorthand notation
for performing 'isset()' checks in the ternary operator. This is a common thing
to do in applications, and so a new syntax has been introduced for this exact
purpose.
<?php
// Pre PHP 7 code
$route = isset($_GET['route']) ? $_GET['route'] : 'index';
// PHP 7+ code
$route = $_GET['route'] ?? 'index';
?>
RFC: [Null Coalesce Operator](https://wiki.php.net/rfc/isset_ternary)
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 the PHP 5.x versions: class names, interfaces, 'array' and
'callable'.
<?php
// Coercive mode
function sumOfInts(int ...$ints)
{
return array_sum($ints);
}
var_dump(sumOfInts(2, '3', 4.1)); // int(9)
?>
To enable strict mode, a single 'declare()' 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](#return-type-declarations)), built-in PHP functions, and
functions from loaded extensions.
If the type-check fails, then a 'TypeError' exception (see [Exceptions in the
Engine](#exceptions-in-the-engine)) is thrown. The only leniency present in
strict typing is the automatic conversion of integers to floats (but not
vice-versa) when an integer is provided in a float context.
<?php
declare(strict_types=1);
function multiply(float $x, float $y)
{
return $x * $y;
}
function add(int $x, int $y)
{
return $x + $y;
}
var_dump(multiply(2, 3.5)); // float(7)
var_dump(add('2', 3)); // Fatal error: Uncaught TypeError: Argument 1 passed to add() must be of the type integer, string given...
?>
Note that only the *invocation context* applies when the type-checking is
performed. This means that the strict typing applies only to function/method
calls, and not to the function/method definitions. In the above example, the
two functions could have been declared in either a strict or coercive file, but
so long as they're being called in a strict file, then the strict typing rules
will apply.
BC Breaks
- Classes with names 'int', 'string', 'float', and 'bool' are now forbidden.
RFC: [Scalar Type Declarations](https://wiki.php.net/rfc/scalar_type_hints_v5)
Return Type Declarations
Return type declarations enable for the return type of a function, method, or
closure to be specified. The following return types are supported: 'string',
'int', 'float', 'bool', 'array', 'callable', 'self' (methods only), 'parent'
(methods only), 'Closure', the name of a class, and the name of an interface.
<?php
function arraysSum(array ...$arrays): array
{
return array_map(function(array $array): int {
return array_sum($array);
}, $arrays);
}
print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));
/* Output
Array
(
[0] => 6
[1] => 15
[2] => 24
)
*/
?>
With respect to subtyping, invariance has been chosen for return types.
This simply means that when a method is either overridden in a subtyped class
or implemented as defined in a contract, its return type must match exactly the
method it is (re)implementing.
<?php
class A {}
class B extends A {}
class C
{
public function test() : A
{
return new A;
}
}
class D extends C
{
// overriding method C::test() : A
public function test() : B // Fatal error due to variance mismatch
{
return new B;
}
}
?>
The overriding method 'D::test() : B' causes an 'E_COMPILE_ERROR' because
covariance is not allowed. In order for this to work, 'D::test()' method must
have a return type of 'A'.
<?php
class A {}
interface SomeInterface
{
public function test() : A;
}
class B implements SomeInterface
{
public function test() : A // all good!
{
return null; // Fatal error: Uncaught TypeError: Return value of B::test() must be an instance of A, null returned...
}
}
?>
This time, the implemented method causes a 'TypeError' exception (see
[Exceptions in the Engine](#exceptions-in-the-engine)) to be thrown when
executed. This is because 'null' is not a valid return type - only an instance of the
class 'A' can be returned.
RFC: [Return Type Declarations](https://wiki.php.net/rfc/return_types)
Anonymous Classes
Anonymous classes are useful when simple, one-off objects need to be created.
<?php
// Pre PHP 7 code
class Logger
{
public function log($msg)
{
echo $msg;
}
}
$util->setLogger(new Logger());
// PHP 7+ code
$util->setLogger(new class {
public function log($msg)
{
echo $msg;
}
});
?>
They can pass arguments through to their constructors, extend other classes,
implement interfaces, and use traits just like a normal class can:
<?php
class SomeClass {}
interface SomeInterface {}
trait SomeTrait {}
var_dump(new class(10) extends SomeClass implements SomeInterface {
private $num;
public function __construct($num)
{
$this->num = $num;
}
use SomeTrait;
});
/ Output:
object(class@anonymous)#1 (1) {
["Command line code0x104c5b612":"class@anonymous":private]=>
int(10)
}
*/
?>
Nesting an anonymous class within another class does not give it access to any
private or protected methods or properties of that outer class. In order to use
the outer class' protected properties or methods, the anonymous class can
extend the outer class. To use the private or protected properties of the outer
class in the anonymous class, they must be passed through its constructor:
<?php
class Outer
{
private $prop = 1;
protected $prop2 = 2;
protected function func1()
{
return 3;
}
public function func2()
{
return new class($this->prop) extends Outer {
private $prop3;
public function __construct($prop)
{
$this->prop3 = $prop;
}
public function func3()
{
return $this->prop2 + $this->prop3 + $this->func1();
}
};
}
}
echo (new Outer)->func2()->func3(); // 6
?>
RFC: [Anonymous Classes](https://wiki.php.net/rfc/anonymous_classes)
Unicode Codepoint Escape Syntax
This enables a UTF-8 encoded unicode codepoint to be output in either a
double-quoted string or a heredoc. Any valid codepoint is accepted, with
leading "0"'s being optional.
<?php
echo "\u{aa}"; // ª
echo "\u{0000aa}"; // ª (same as before but with optional leading 0's)
echo "\u{9999}"; // 香
?>
RFC: [Unicode Codepoint Escape Syntax](https://wiki.php.net/rfc/unicode_escape)
Closure call() Method
The new 'call()' method for closures is used as a shorthand way of invoking a
closure whilst binding an object scope to it. This creates more perfomant and
compact code by removing the need to create an intermediate closure before
invoking it.
<?php
class A {private $x = 1;}
?>
<?php
// Pre PHP 7 code
$getXCB = function() {return $this->x;};
$getX = $getXCB->bindTo(new A, 'A'); // intermediate closure
echo $getX(); // 1
?>
<?php
// PHP 7+ code
$getX = function() {return $this->x;};
echo $getX->call(new A); // 1
?>
RFC: [Closure::call](https://wiki.php.net/rfc/closure_apply)
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.
<?php
// converts all objects into __PHP_Incomplete_Class object
$data = unserialize($foo, ["allowed_classes" => false]);
// converts all objects into __PHP_Incomplete_Class object except those of MyClass and MyClass2
$data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]]);
// default behaviour (same as omitting the second argument) that accepts all classes
// $data = unserialize($foo, ["allowed_classes" => true]);
?>
RFC: [Filtered unserialize()](https://wiki.php.net/rfc/secure_unserialize)
IntlChar Class
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.
<?php
printf('%x', IntlChar::CODEPOINT_MAX); // 10ffff
echo IntlChar::charName('@'); // COMMERCIAL AT
var_dump(IntlChar::ispunct('!')); // bool(true)
?>
In order to use this class, the 'Intl' extension must be installed.
BC Breaks
- Classes in the global namespace must not be called 'IntlChar'.
RFC: [IntlChar class](https://wiki.php.net/rfc/intl.char)
Expectations
Expectations are backwards compatible enhancement to the older 'assert()'
function. They enable for zero-cost assertions in production code, and provide
the ability to throw custom exceptions on error.
The 'assert()' function's prototype is as follows:
void assert (mixed $expression [, mixed $message]);
As with the old API, if '$expression' is a string, then it will be evaluated.
If the first argument is falsy, then the assertion fails. The second argument
can either be a plain string (causing an AssertionException to be triggered),
or a custom exception object containing an error message.
<?php
ini_set('assert.exception', 1);
class CustomError extends AssertionError {}
assert(false, new CustomError('Some error message'));
?>
With this feature comes two PHP.ini settings (along with their default values):
- zend.assertions = 1
- assert.exception = 0
zend.assertions has three values:
- 1 = generate and execute code (development mode)
- 0 = generate code and jump around at it at runtime
- -1 = don't generate any code (zero-cost, production mode)
assert.exception means that an exception is thrown when an assertion fails.
This is switched off by default to remain compatible with the old 'assert()'
function.
RFC: [Expectations](https://wiki.php.net/rfc/expectations)
Group 'use' Declarations
This gives the ability to group multiple 'use' declarations according to the
parent namespace. This seeks to remove code verbosity when importing multiple
classes, functions, or constants that come under the same namespace.
<?php
// Pre PHP 7 code
use some\namespace\ClassA;
use some\namespace\ClassB;
use some\namespace\ClassC as C;
use function some\namespace\fn_a;
use function some\namespace\fn_b;
use function some\namespace\fn_c;
use const some\namespace\ConstA;
use const some\namespace\ConstB;
use const some\namespace\ConstC;
// PHP 7+ code
use some\namespace\{ClassA, ClassB, ClassC as C};
use function some\namespace\{fn_a, fn_b, fn_c};
use const some\namespace\{ConstA, ConstB, ConstC};
?>
RFC: [Group use Declarations](https://wiki.php.net/rfc/group_use_declarations)
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 finishing yielding values.
<?php
// IIFE syntax now possible - see the Uniform Variable Syntax subsection in the Changes section
$gen = (function() {
yield 1;
yield 2;
return 3;
})();
foreach ($gen as $val) {
echo $val, PHP_EOL;
}
echo $gen->getReturn(), PHP_EOL;
// output:
// 1
// 2
// 3
?>
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.
RFC: [Generator Return Expressions](https://wiki.php.net/rfc/generator-return-expressions)
Generator Delegation
Generator delegation builds upon the ability of being able to return
expressions from generators. It does this by using an new syntax of 'yield from
<expr>', where <expr> can be any 'Traversable' object or array. This <expr>
will be advanced until no longer valid, and then execution will continue in the
calling generator. This feature enables 'yield' statements to be broken down
into smaller operations, thereby promoting cleaner code that has greater
reusability.
<?php
function gen()
{
yield 1;
yield 2;
return yield from gen2();
}
function gen2()
{
yield 3;
return 4;
}
$gen = gen();
foreach ($gen as $val)
{
echo $val, PHP_EOL;
}
echo $gen->getReturn();
// output
// 1
// 2
// 3
// 4
?>
RFC: [Generator Delegation](https://wiki.php.net/rfc/generator-delegation)
Integer Division with 'intdiv()'
The 'intdiv()' function has been introduced to handle division where an integer is to be returned.
<?php
var_dump(intdiv(10, 3)); // int(3)
?>
BC Breaks
- Functions in the global namespace must not be called 'intdiv'.
RFC: [intdiv()](https://wiki.php.net/rfc/intdiv)
'session_start()' Options
This feature gives the ability to pass in an array of options to the
'session_start()' function. This is used to set session-based php.ini options:
<?php
session_start(['cache_limiter' => 'private']); // sets the session.cache_limiter option to private
?>
This feature also introduces a new php.ini setting ('session.lazy_write') that
is, by default, set to true and means that session data is only rewritten if it
changes.
RFC: [Introduce session_start() Options](https://wiki.php.net/rfc/session-lock-ini)
'preg_replace_callback_array()' Function
This new 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 (second
parameter of 'preg_replace_callback()') to be polluted with lots of branching
(a hacky method at best).
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.
Function Signature:
string preg_replace_callback_array(array $regexesAndCallbacks, string $input);
<?php
$tokenStream = []; // [tokenName, lexeme] pairs
$input = <<<'end'
$a = 3; // variable initialisation
end;
// Pre PHP 7 code
preg_replace_callback(
[
'~\$[a-z_][a-z\d_]*~i',
'~=~',
'~[\d]+~',
'~;~',
'~//.*~'
],
function ($match) use (&$tokenStream) {
if (strpos($match[0], '$') === 0) {
$tokenStream[] = ['T_VARIABLE', $match[0]];
} elseif (strpos($match[0], '=') === 0) {
$tokenStream[] = ['T_ASSIGN', $match[0]];
} elseif (ctype_digit($match[0])) {
$tokenStream[] = ['T_NUM', $match[0]];
} elseif (strpos($match[0], ';') === 0) {
$tokenStream[] = ['T_TERMINATE_STMT', $match[0]];
} elseif (strpos($match[0], '//') === 0) {
$tokenStream[] = ['T_COMMENT', $match[0]];
}
},
$input
);
// PHP 7+ code
preg_replace_callback_array(
[
'~\$[a-z_][a-z\d_]*~i' => function ($match) use (&$tokenStream) {
$tokenStream[] = ['T_VARIABLE', $match[0]];
},
'~=~' => function ($match) use (&$tokenStream) {
$tokenStream[] = ['T_ASSIGN', $match[0]];
},
'~[\d]+~' => function ($match) use (&$tokenStream) {
$tokenStream[] = ['T_NUM', $match[0]];
},
'~;~' => function ($match) use (&$tokenStream) {
$tokenStream[] = ['T_TERMINATE_STMT', $match[0]];
},
'~//.*~' => function ($match) use (&$tokenStream) {
$tokenStream[] = ['T_COMMENT', $match[0]];
}
],
$input
);
?>
BC Breaks
- Functions in the global namespace must not be called 'preg_replace_callback_array'.
RFC: [Add preg_replace_callback_array Function](https://wiki.php.net/rfc/preg_replace_callback_array)
CSPRNG Functions
This feature introduces two new functions for generating cryptographically
secure integers and strings. They expose simple APIs and are
platform-independent.
Function signatures:
string random_bytes(int length);
int random_int(int min, int max);
Both functions will emit an 'E_WARNING' and return 'false' if a source of
sufficient randomness cannot be found.
BC Breaks
- Functions in the global namespace must not be called 'random_int' or 'random_bytes'.
RFC: [Easy User-land CSPRNG](https://wiki.php.net/rfc/easy_userland_csprng)
Support for Array Constants in 'define()'
The ability to define array constants was introduced in PHP 5.6 using the
'const' keyword. This ability has now been applied to the 'define()' function
too:
<?php
define('ALLOWED_IMAGE_EXTENSIONS', ['jpg', 'jpeg', 'gif', 'png']);
?>
RFC: no RFC available
Reflection Additions
Two new reflection classes have been introduced in PHP 7. The first is
'ReflectionGenerator', which is used for introspection on generators:
<?php
class ReflectionGenerator
{
public ReflectionGenerator::__construct(Generator $gen)
public array ReflectionGenerator::getTrace($options = DEBUG_BACKTRACE_PROVIDE_OBJECT)
public int ReflectionGenerator::getExecutingLine(void)
public string ReflectionGenerator::getExecutingFile(void)
public ReflectionFunctionAbstract ReflectionGenerator::getFunction(void)
public Object ReflectionGenerator::getThis(void)
public Generator ReflectionGenerator::getExecutingGenerator(void)
}
?>
The second is 'ReflectionType' to better support the scalar and return type
declaration features:
<?php
class ReflectionType
{
public bool ReflectionType::allowsNull(void)
public bool ReflectionType::isBuiltin(void)
public string ReflectionType::__toString(void)
}
?>
Also, two new methods have been introduced into 'ReflectionParameter':
<?php
class ReflectionParameter
{
// ...
public bool ReflectionParameter::hasType(void)
public ReflectionType ReflectionParameter::getType(void)
}
?>
As well as two new methods in 'ReflectionFunctionAbstract':
<?php
class ReflectionFunctionAbstract
{
// ...
public bool ReflectionFunctionAbstract::hasReturnType(void)
public ReflectionType ReflectionFunctionAbstract::getReturnType(void)
}
?>
BC Breaks
- Classes in the global namespace must not be called 'ReflectionGenerator' or
'ReflectionType'.
RFC: no RFC available
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:
<?php
// 'new', 'private', and 'for' were previously unusable
Project::new('Project Name')->private()->for('purpose here')->with('username here');
?>
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').
RFC: [Context Sensitive Lexer](https://wiki.php.net/rfc/context_sensitive_lexer)
Uniform Variable Syntax
This change brings far greater orthogonality to the variable operators in PHP.
It enables for a number of new combinations of operators that were previously
disallowed, and so introduces new ways to achieve old operations in terser
code.
<?php
// nesting ::
$foo::$bar::$baz // access the property $baz of the $foo::$bar property
// nesting ()
foo()() // invoke the return of foo()
// operators on expressions enclosed in ()
(function () {})() // IIFE syntax from JS
?>
The ability to arbitrarily combine variable operators came from reversing the
evaluation semantics of indirect variable, property, and method references. The
new behaviour is more intuitive and always follows a left-to-right evaluation
order:
<?php
// old meaning // new meaning
$$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']()
?>
BC Breaks
- Code that relied upon the old evaluation order must be rewritten to
explicitly use that evaluation order with curly braces (see middle column of
the above). This will make the code both forwards compatible with PHP 7.x and
backwards compatible with PHP 5.x
RFC: [Uniform Variable Syntax](https://wiki.php.net/rfc/uniform_variable_syntax)
Exceptions in the Engine
Exceptions in the engine converts many fatal and recoverable fatal errors into
exceptions. This enables for graceful degradation of applications through
custom error handling procedures. It also means that cleanup-driven features
such as the 'finally' clause and object destructors will now be executed.
Furthermore, by using exceptions for application errors, stack traces will be
produced for additional debugging information.
<?php
function sum(float ...$numbers) : float
{
return array_sum($numbers);
}
try {
$total = sum(3, 4, null);
} catch (TypeError $typeErr) {
// handle type error here
}
?>
The new exception hierarchy is as follows:
interface Throwable
|- Exception implements Throwable
|- ...
|- Error implements Throwable
|- TypeError extends Error
|- ParseError extends Error
|- AssertionError extends Error
|- ArithmeticError extends Error
|- DivisionByZeroError extends ArithmeticError
See the [Throwable Interface](#throwable-interface) subsection in the Changes
section for more information on this new exception hierarchy.
BC Breaks
- Custom error handlers used for handling (and typically ignoring) recoverable
fatal errors will not longer work since exceptions will now be thrown
- Parse errors occurring in 'eval()'ed code will now become exceptions,
requiring them to be wrapped in a 'try...catch' block
RFC: [Exceptions in the Engine](https://wiki.php.net/rfc/engine_exceptions_for_php7)
Throwable Interface
This change affects PHP's exception hierarchy due to the introduction of
[exceptions in the engine](#exceptions-in-the-engine). Rather than placing
fatal and recoverable fatal errors under the pre-existing 'Exception' class
hierarchy, [it was
decided](https://wiki.php.net/rfc/engine_exceptions_for_php7#doodle__form__introduce_and_use_baseexception)
to implement a new hierarchy of exceptions to prevent PHP 5.x code from
catching these new exceptions with catch-all ('catch (Exception $e)') clauses.
The new exception hierarchy is as follows:
interface Throwable
|- Exception implements Throwable
|- ...
|- Error implements Throwable
|- TypeError extends Error
|- ParseError extends Error
|- AssertionError extends Error
|- ArithmeticError extends Error
|- DivisionByZeroError extends ArithmeticError
The 'Throwable' interface is implemented by both 'Exception' and 'Error' base
class hierarchies and defines the following contract:
<?php
interface Throwable
{
final public string getMessage ( void )
final public mixed getCode ( void )
final public string getFile ( void )
final public int getLine ( void )
final public array getTrace ( void )
final public string getTraceAsString ( void )
public string __toString ( void )
}
?>
'Throwable' cannot be implemented by user-defined classes - instead, a custom
exception class should extend one of the pre-existing exceptions classes in
PHP.
RFC: [Throwable Interface](https://wiki.php.net/rfc/throwable-interface)
Integer Semantics
The semantics for some integer-based behaviour has changed in an effort to make
them more intuitive and platform-independent. Here is a list of those changes:
- Casting 'NAN' and 'INF' to an integer will always result in 0
- Bitwise shifting by a negative number of bits is now disallowed (causes a
bool(false) return an emits an E_WARNING)
- Left bitwise shifts by a number of bits beyond the bit width of an integer will always result in 0
- Right bitwise shifts by a number of bits beyond the bit width of an integer
will always result in 0 or -1 (sign dependent)
BC Breaks
- Any reliance on the old semantics for the above will no longer work
RFC: [Integer Semantics](https://wiki.php.net/rfc/integer_semantics)
JSON Extension Replaced with JSOND
The licensing of the old JSON extension was regarded as non-free, causing
issues for many Linux-based distributions. The extension has since been
replaced with JSOND and comes with some [performance
gains](https://github.com/bukka/php-jsond-bench/blob/master/reports/0001/summary.md)
and backward compatibility breakages.
BC Breaks
- A number *must not* end in a decimal point (i.e. '34.' must be changed to either '34.0' or just '34')
- The 'e' exponent *must not* immediately follow the decimal point (i.e.
'3.e3' must be changed to either '3.0e3' or just '3e3')
RFC: [Replace current json extension with jsond](https://wiki.php.net/rfc/jsond)
ZPP Failure on Overflow
Coercion between floats to integers can occur when a float is passed to an
internal function expecting an integer. If the float is too large to represent
as an integer, then the value will be silently truncated (which may result in a
loss of magnitude and sign). This can introduce hard-to-find bugs. This change
therefore seeks to notify the developer when an implicit conversion from a
float to an integer has occurred and failed by returning 'null' and emitting an
E_WARNING.
BC Breaks
- Code that once silently worked will now emit an E_WARNING and may fail if
the result of the function invocation is directly passed to another function
(since 'null' will now be passed in).
RFC: [ZPP Failure on Overflow](https://wiki.php.net/rfc/zpp_fail_on_overflow)
Fixes to 'foreach()' 's Behaviour
PHP's 'foreach()' loop had a number of strange edge-cases to it. These were all
implementation-driven and caused a lot of undefined and inconsistent behaviour
when iterating between copies and references of an array, when using iterator
manipulators like 'current()' and 'reset()', when modifying the array currently
being iterated, and so on.
This change eliminates the undefined behaviour of these edge-cases and makes
the semantics more predictable and intuitive.
'foreach()' by value on arrays
<?php
$array = [1,2,3];
$array2 = &$array;
foreach($array as $val) {
unset($array[1]); // modify array being iterated over
echo "{$val} - ", current($array), PHP_EOL;
}
// Pre PHP 7 result
1 - 3
3 -
// PHP 7+ result
1 - 1
2 - 1
3 - 1
?>
When by-value semantics are used, the array being iterated over is now not
modified in-place. 'current()' also now has defined behaviour, where it will
always begin at the start of the array.
'foreach()' by reference on arrays and objects and by value on objects
<?php
$array = [1,2,3];
foreach($array as &$val) {
echo "{$val} - ", current($array), PHP_EOL;
}
// Pre PHP 7 result
1 - 2
2 - 3
3 -
// PHP 7+ result
1 - 1
2 - 1
3 - 1
?>
The 'current()' function is no longer affected by 'foreach()' 's iteration on
the array. Also, nested 'foreach()''s using by-reference semantics work
independently from each other now:
<?php
$array = [1,2,3];
foreach($array as &$val) {
echo $val, PHP_EOL;
foreach ($array as &$val2) {
unset($array[1]);
echo $val, PHP_EOL;
}
}
// Pre PHP 7 result
1
1
1
// PHP 7+ result
1
1
1
3
3
3
?>
BC Breaks
- Any reliance on the old (quirky and undocumented) semantics will no longer work.
RFC: [Fix "foreach" behavior](https://wiki.php.net/rfc/php7_foreach)
Changes to 'list()''s Behaviour
The 'list()' function was documented as not supporting strings, however in few cases strings could have been used:
<?php
// array dereferencing
$str[0] = 'ab';
list($a, $b) = $str[0];
echo $a; // a
echo $b; // b
// object dereferencing
$obj = new StdClass();
$obj->prop = 'ab';
list($a, $b) = $obj->prop;
echo $a; // a
echo $b; // b
// function return
function func()
{
return 'ab';
}
list($a, $b) = func();
var_dump($a, $b);
echo $a; // a
echo $b; // b
?>
This has now been changed making string usage with 'list()' forbidden in all cases.
Also, empty 'list()' 's are now a fatal error, and the order of assigning variables has been changed to left-to-right:
<?php
$a = [1, 2];
list($a, $b) = $a;
// OLD: $a = 1, $b = 2
// NEW: $a = 1, $b = null + "Undefined index 1"
$b = [1, 2];
list($a, $b) = $b;
// OLD: $a = null + "Undefined index 0", $b = 2
// NEW: $a = 1, $b = 2
?>
BC Breaks
- Making 'list()' equal to any non-direct string value is no longer possible.
'null' will now be the value for the variable '$a' and '$b' in the above
examples
- Invoking 'list()' without any variables will cause a fatal error
- Reliance upon the old right-to-left assignment order will no longer work
RFC: [Fix list() behavior inconsistency](https://wiki.php.net/rfc/fix_list_behavior_inconsistency)
RFC: [Abstract syntax tree](https://wiki.php.net/rfc/abstract_syntax_tree)
Changes to Division by Zero Semantics
Prior to PHP 7, when a divisor was 0 for either the divide (/) or modulus (%) operators,
an E_WARNING would be emitted and 'false' would be returned. This was nonsensical for
an arithmetic operation to return a boolean in some cases, and so the behaviour has been
rectified in PHP 7.
The new behaviour causes the divide operator to return a float as either +INF, -INF, or
NAN. The modulus operator E_WARNING has been removed and (alongside the new 'intdiv()'
function) will throw a 'DivisionByZeroError' exception. In addition, the 'intdiv()'
function may also throw an 'ArithmeticError' when valid integer arguments are supplied
that cause an incorrect result (due to integer overflow).
<?php
var_dump(3/0); // float(INF) + E_WARNING
var_dump(0/0); // float(NAN) + E_WARNING
var_dump(0%0); // DivisionByZeroError
intdiv(PHP_INT_MIN, -1); // ArithmeticError
?>
BC Breaks
- The divide operator will no longer return 'false' (which could have been silently coerced
to 0 in an arithmetic operation)
- The modulus operator will now throw an exception with a 0 divisor instead of returning 'false'
RFC: No RFC available
Fixes to Custom Session Handler Return Values
When implementing custom session handlers, predicate functions from the
'SessionHandlerInterface' that expect a 'true' or 'false' return value did not
behave as expected. Due to an error in the previous implementation, only a '-1'
return value was considered false - meaning that any even if the boolean
'false' was used to denote a failure, it was taken as a success:
<?php
class FileSessionHandler implements SessionHandlerInterface
{
private $savePath;
function open($savePath, $sessionName)
{
return false; // always fail
}
function close(){return true;}
function read($id){}
function write($id, $data){}
function destroy($id){}
function gc($maxlifetime){}
}
session_set_save_handler(new FileSessionHandler());
session_start(); // doesn't cause an error in pre PHP 7 code
?>
Now, the above will fail with a fatal error. Having a '-1' return value will
also continue to fail, whilst '0' and 'true' will continue to mean success. Any
other value returned will now cause a failure and emit an E_WARNING.
BC Breaks
- If boolean 'false' is returned, it will actually fail now
- If anything other than a boolean, '0', or '-1' is returned, it will fail and cause a warning to be emitted
RFC: [Fix handling of custom session handler return values](https://wiki.php.net/rfc/session.user.return-value)
Deprecation of PHP 4-Style Constructors
PHP 4 constructors were preserved in PHP 5 alongside the new '__construct()'.
Now, PHP 4-style constructors are being deprecated in favour of having only a
single method ('__construct()') to be invoked on object creation. This is
because the conditions upon whether the PHP 4-style constructor was invoked
caused additional cognitive overhead to developers that could also be confusing
to the inexperienced.
For example, if the class is defined within a namespace or if an
'__construct()' method existed, then a PHP 4-style constructor was recognised
as a plain method. If it was defined above an '__construct()' method, then an
E_STRICT notice would be emitted, but still recognised as a plain method.
Now in PHP 7, if the class is not in a namespace and there is no
'__construct()' method present, the PHP 4-style constructor will be used as a
constructor but an E_DEPRECATED will be emitted. In PHP 8, the PHP 4-style
constructor will always be recognised as a plain method and the E_DEPRECATED
notice will disappear.
BC Breaks
- Custom error handlers may be affected by the raising of E_DEPRECATED
warnings. To fix this, simply update the class constructor name to
'__construct'.
RFC: [Remove PHP 4 Constructors](https://wiki.php.net/rfc/remove_php4_constructors)
Removal of date.timezone Warning
When any date- or time-based functions were invoked and a default timezone had
not been set, a warning was emitted. The fix was to simply set the
'date.timezone' INI setting to a valid timezone, but this forced users to have
a php.ini file and to configure it beforehand. Since this was the only setting
that had a warning attached to it, and it defaulted to UTC anyway, the warning
has now been removed.
RFC: [Remove the date.timezone warning](https://wiki.php.net/rfc/date.timezone_warning_removal)
Removal of Alternative PHP Tags
The alternative PHP tags '<%' (and '<%='), '%>', '<script language="php">', and
'</script>' have now been removed.
BC Breaks
- Code that relied upon these alternative tags needs to be updated to either
the normal or short opening and closing tags. This can either be done
manually or automated with [this porting script](https://gist.github.com/nikic/74769d74dad8b9ef221b).
RFC: [Remove alternative PHP tags](https://wiki.php.net/rfc/remove_alternative_php_tags)
Removal of Multiple Default Blocks in Switch Statements
Previously, it was possible to specify multiple 'default' block statements
within a switch statement (where the last 'default' block was only executed).
This (useless) ability has now been removed and causes a fatal error.
BC Breaks
- Any code written (or more likely generated) that created switch statements
with multiple 'default' blocks will now become a fatal error.
RFC: [Make defining multiple default cases in a switch a syntax error](https://wiki.php.net/rfc/switch.default.multiple)
Removal of Dead Server APIs
The following SAPIs have been removed from the core (most of which have been moved to PECL):
- sapi/aolserver
- sapi/apache
- sapi/apache_hooks
- sapi/apache2filter
- sapi/caudium
- sapi/continuity
- sapi/isapi
- sapi/milter
- sapi/nsapi
- sapi/phttpd
- sapi/pi3web
- sapi/roxen
- sapi/thttpd
- sapi/tux
- sapi/webjames
- ext/mssql
- ext/mysql
- ext/sybase_ct
- ext/ereg
RFC: [Removal of dead or not yet PHP7 ported SAPIs and extensions](https://wiki.php.net/rfc/removal_of_dead_sapis_and_exts)
Removal of Hex Support in Numerical Strings
A Stringy hexadecimal number is no longer recognised as numerical.
<?php
var_dump(is_numeric('0x123'));
var_dump('0x123' == '291');
echo '0x123' + '0x123';
// Pre PHP 7 result
bool(true)
bool(true)
582
// PHP 7+ result
bool(false)
bool(false)
0
?>
The reason for this change is to promote better consistency between the
handling of stringy hex numbers across the language. For example, explicit
casts do not recognise stringy hex numbers:
<?php
var_dump((int) '0x123'); // int(0)
?>
Instead, stringy hex numbers should be validated and converted using the 'filter_var()' function:
<?php
var_dump(filter_var('0x123', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX)); // int(291)
?>
BC Breaks
- This change affects the 'is_numeric()' function and various operators, including '==', '+', '-', '*', '/', '%', '', '++', and '--'
RFC: [Remove hex support in numeric strings](https://wiki.php.net/rfc/remove_hex_support_in_numeric_strings)
Removal of Deprecated Functionality
All Deprecated functionality has been removed, most notably:
- The original mysql extension (ext/mysql)
- The ereg extension (ext/ereg)
- Assigning 'new' by reference
- Scoped calls of non-static methods from an incompatible '$this' context
(such as 'Foo::bar()' from outside a class, where 'bar()' is not a static
method)
BC Breaks
- Any code that ran with deprecation warnings in PHP 5 will no longer work (you were warned!)
RFC: [Remove deprecated functionality in PHP 7](https://wiki.php.net/rfc/remove_deprecated_functionality_in_php7)
Reclassification and Removal of E_STRICT Notices
E_STRICT notices have always been a bit of a grey area in their meaning. This
changes removes this error category altogether and either: removes the E_STRICT
notice, changes it to an E_DEPRECATED if the functionality will be removed in
future, changes it to an E_NOTICE, or promotes it to an E_WARNING.
BC Breaks
- Because E_STRICT is in the lowest severity error category, any error
promotions to an E_WARNING may break custom error handlers
RFC: [Reclassify E_STRICT notices](https://wiki.php.net/rfc/reclassify_e_strict)
Deprecation of Salt Option for 'password_hash()'
With the introduction of the new password hashing API in PHP 5.5, many began
implementing it and generating their own salts. Unfortunately, many of these
salts were generated from cryptographically insecure functions like mt_rand(),
making the salt far weaker than what would have been generated by default.
(Yes, a salt is always used when hashing passwords with this new API!) The option to
generate salts have therefore been deprecated to prevent developers from
creating insecure salts.
RFC: no RFC available
Error on Invalid Octal Literals
Invalid octal literals will now cause a parse error rather than being
truncated and silently ignored.
<?php
echo 0678; // Parse error: Invalid numeric literal in...
?>
BC Breaks
- Any invalid octal literals in code will now cause parse errors
FAQ
What happened to PHP 6?
PHP 6 was the major PHP version that never came to light. It was supposed to
feature full support for Unicode in the core, but this effort was too ambitious
with too many complications arising. The predominant reasons why version 6 was
skipped for this new major version are as follows:
- To prevent confusion. Many resources were written about PHP 6 and much
of the community knew what was featured in it. PHP 7 is a completely
different beast with entirely different focusses (specifically on performance)
and entirely different feature sets. Thus, a version has been skipped to
prevent any confusion or misconceptions surrounding what PHP 7 is.
- To let sleeping dogs lie. PHP 6 was seen as a failure and a large amount
of PHP 6 code still remains in the PHP repository. It was therefore seen as
best to move past version 6 and start afresh on the next major version, version 7.
------------------------------------------------------------------------------------------
PHP 5.6.x
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.
<?php
const ONE = 1;
const TWO = ONE * 2;
class C {
const THREE = TWO + 1;
const ONE_THIRD = ONE / self::THREE;
const SENTENCE = 'The value of THREE is '.self::THREE;
public function f($a = ONE + self::THREE) {
return $a;
}
}
echo (new C)->f()."\n";
echo C::SENTENCE;
?>
Результат выполнения данного примера:
4
The value of THREE is 3
It is also now possible to define a constant array using the const keyword:
<?php
const ARR = ['a', 'b'];
echo ARR[0];
?>
Результат выполнения данного примера:
a
Variadic functions via ...
Variadic functions can now be implemented using the ... operator, instead of relying on func_get_args().
<?php
function f($req, $opt = null, ...$params) {
// $params is an array containing the remaining arguments.
printf('$req: %d; $opt: %d; number of params: %d'."\n",
$req, $opt, count($params));
}
f(1);
f(1, 2);
f(1, 2, 3);
f(1, 2, 3, 4);
f(1, 2, 3, 4, 5);
?>
Результат выполнения данного примера:
$req: 1; $opt: 0; number of params: 0
$req: 1; $opt: 2; number of params: 0
$req: 1; $opt: 2; number of params: 1
$req: 1; $opt: 2; number of params: 2
$req: 1; $opt: 2; number of params: 3
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.
<?php
function add($a, $b, $c) {
return $a + $b + $c;
}
$operators = [2, 3];
echo add(1, ...$operators);
?>
Результат выполнения данного примера:
6
Exponentiation via
A right associative operator has been added to support exponentiation, along with a = shorthand assignment operator.
<?php
printf("2 3 == %d\n", 2 3);
printf("2 3 2 == %d\n", 2 3 2);
$a = 2;
$a = 3;
printf("a == %d\n", $a);
?>
Результат выполнения данного примера:
2 3 == 8
2 3 2 == 512
a == 8
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.
<?php
namespace Name\Space {
const FOO = 42;
function f() { echo __FUNCTION__."\n"; }
}
namespace {
use const Name\Space\FOO;
use function Name\Space\f;
echo FOO."\n";
f();
}
?>
Результат выполнения данного примера:
42
Name\Space\f
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:
<?php
$a = gmp_init(42);
$b = gmp_init(17);
// Pre-5.6 code:
var_dump(gmp_add($a, $b));
var_dump(gmp_add($a, 17));
var_dump(gmp_add(42, $b));
// New code:
var_dump($a + $b);
var_dump($a + 17);
var_dump(42 + $b);
?>
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 are not susceptible to timing attacks).
<?php
$expected = crypt('12345', '$2a$07$usesomesillystringforsalt$');
$correct = crypt('12345', '$2a$07$usesomesillystringforsalt$');
$incorrect = crypt('1234', '$2a$07$usesomesillystringforsalt$');
var_dump(hash_equals($expected, $correct));
var_dump(hash_equals($expected, $incorrect));
?>
Результат выполнения данного примера:
bool(true)
bool(false)
__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().
<?php
class C {
private $prop;
public function __construct($val) {
$this->prop = $val;
}
public function __debugInfo() {
return [
'propSquared' => $this->prop 2,
];
}
}
var_dump(new C(42));
?>
Результат выполнения данного примера:
object(C)#1 (1) {
["propSquared"]=>int(1764)
}
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.
------------------------------------------------------------------------------------------
PHP 5.5.x
Support for generators has been added via the yield keyword. Generators provide an easy way to implement simple iterators without the overhead or complexity of implementing a class that implements the Iterator interface.
A simple example that reimplements the range() function as a generator (at least for positive step values):
<?php
function xrange($start, $limit, $step = 1) {
for ($i = $start; $i <= $limit; $i += $step) {
yield $i;
}
}
echo 'Single digit odd numbers: ';
/*
* Note that an array is never created or returned,
* which saves memory.
*/
foreach (xrange(1, 9, 2) as $number) {
echo "$number ";
}
echo "\n";
?>
Результат выполнения данного примера:
Single digit odd numbers: 1 3 5 7 9
finally keyword added
try-catch blocks now support a finally block for code that should be run regardless of whether an exception has been thrown or not.
New password hashing API
A new password hashing API that makes it easier to securely hash and manage passwords using the same underlying library as crypt() in PHP has been added. See the documentation for password_hash() for more detail.
foreach now supports list()
The foreach control structure now supports unpacking nested arrays into separate variables via the list() construct. For example:
<?php
$array = [
[1, 2],
[3, 4],
];
foreach ($array as list($a, $b)) {
echo "A: $a; B: $b\n";
}
?>
Результат выполнения данного примера:
A: 1; B: 2
A: 3; B: 4
Further documentation is available on the foreach manual page.
empty() supports arbitrary expressions
Passing an arbitrary expression instead of a variable to empty() is now supported. For example:
<?php
function always_false() {
return false;
}
if (empty(always_false())) {
echo "This will be printed.\n";
}
if (empty(true)) {
echo "This will not be printed.\n";
}
?>
Результат выполнения данного примера:
This will be printed.
array and string literal dereferencing
Array and string literals can now be dereferenced directly to access individual elements and characters:
<?php
echo 'Array dereferencing: ';
echo [1, 2, 3][0];
echo "\n";
echo 'String dereferencing: ';
echo 'PHP'[0];
echo "\n";
?>
Результат выполнения данного примера:
Array dereferencing: 1
String dereferencing: P
Class name resolution via ::class
It is possible to use ClassName::class to get a fully qualified name of class ClassName. For example:
<?php
namespace Name\Space;
class ClassName {}
echo ClassName::class;
echo "\n";
?>
Результат выполнения данного примера:
Name\Space\ClassName
OPcache extension added
The Zend Optimiser+ opcode cache has been added to PHP as the new OPcache extension. OPcache improves PHP performance by storing precompiled script bytecode in shared memory, thereby removing the need for PHP to load and parse scripts on each request. See the installation instructions for more detail on enabling and using OPcache.
foreach now supports non-scalar keys
foreach now supports keys of any type. While non-scalar keys cannot occur in native PHP arrays, it is possible for Iterator::key() to return a value of any type, and this will now be handled correctly.
Apache 2.4 handler supported on Windows
The Apache 2.4 handler SAPI is now supported on Windows.
Improvements to GD
Various improvements have been made to the GD extension, these include:
Flipping support using the new imageflip() function.
Advanced cropping support using the imagecrop() & imagecropauto() functions.
WebP read and write support using imagecreatefromwebp() & imagewebp() respectively.
------------------------------------------------------------------------------------------
PHP 5.4.0 предлагает широкий спектр новых возможностей:
Добавлена поддержка трейтов.
Добавлен короткий синтаксис объявления массивов. Например, $a = [1, 2, 3, 4]; или $a = ['one' => 1, 'two' => 2, 'three' => 3, 'four' => 4];.
Добавлена возможность разыменования массивов, возвращаемых функциями. Например: foo()[0].
Классы для создания анонимных функций (Closures) теперь поддерживают $this.
Оператор <?= теперь доступен всегда, несмотря на значение php.ini опции short_open_tag.
Добавлена возможность получения доступа к члену класса при создании экземпляра. Например: (new Foo)->bar().
Теперь поддерживается такой синтаксис: Class::{expr}().
Добавлен бинарный формат задания чисел, например: 0b001001101.
Улучшены сообщения об ошибках разбора и предупреждения о несовместимых аргументах.
Расширение по работе с сессиями теперь может отслеживать процесс загрузки файлов.
Встроенный веб-сервер в режиме командной строки для разработчиков.
------------------------------------------------------------------------------------------
PHP 5.3.0 предлагает широкий спектр новых возможностей:
Добавлена поддержка пространств имен.
Добавлена поддержка позднего статического связывания.
Добавлена поддержка меток перехода (ограниченный goto).
Добавлена поддержка нативных замыканий (closures) (Lambda/Anonymous функции).
Появились два магических метода: __callStatic() и __invoke().
Появилась поддержка синтаксиса Nowdoc, подобный Heredoc, но с одинарными кавычками.
Теперь возможно использовать Heredoc для инициализации статических переменных и свойств/констант классов.
Heredoc теперь может быть объявлен используя двойные кавычки, дополняющие синтаксис Nowdoc.
Константы теперь могут быть объявлены вне класса, используя ключевое слово const.
У тернарного оператора есть теперь сокращенный вид: ?:.
Обертка (wrapper) HTTP-потока стала воспринимать коды статуса от 200 до 399 как успешные.
Стал возможен динамический доступ к статическим методам:
<?php
class C {
public static $foo = 123;
}
$a = "C";
echo $a::$foo;
?>
Результат выполнения данного примера:
123
Исключения теперь могут быть вложенными:
<?php
class MyCustomException extends Exception {}
try {
throw new MyCustomException("Exceptional", 112);
} catch (Exception $e) {
/* Обратите внимание, что для передачи $e
* в RuntimeException используется третий параметр. */
throw new RuntimeException("Rethrowing", 911, $e);
}
?>
Добавлен сборщик мусора для циклических ссылок. Он включен по умолчанию.
Функция mail() теперь поддерживает журналирование отправки письма с помощью директивы mail.log. (Примечание: это применимо только для писем, отправленных этой функцией.)
------------------------------------------------------------------------------------------
PHP 5.2.x некоторые новые ключевые возможности:
Added data: stream support.
------------------------------------------------------------------------------------------
PHP 5.1.x некоторые новые ключевые возможности:
Полностью переписан код по работе с датами с расширенной поддержкой временных зон.
Значительное улучшение производительности по сравнению с PHP 5.0.X.
Расширение PDO сейчас включено по умолчанию.
Свыше 30 новых функций в различных расширениях и во встроенной функциональности.
Свыше 400 различных исправлений ошибок.
------------------------------------------------------------------------------------------
Main changes (short):
5.1 PDO enabled by default
5.2 Added data: stream support.
5.3 namespaces, closures, __callStatic() и __invoke()
5.4 traits, short array syntax
5.5 finally, generators (yield, range)
5.6 variadic functions, argument unpacking
7 return types, scalar type hints
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment