PHP 5.3 (2009)

1. Замыкания или анонимные функции.

Объявление функций без имени.

<?php

$myFunction = function($arg1) { 
     echo "Hello: $arg1";        
}

$myFunction("PHP");

//Результат:
//Hello: PHP

Для классов:

<?php

class MyClass {

    /**
        __invoke - магическая функция вызывается, когда 
                   скрипт пытается выполнить объект как функцию.       
    */
    public funciont __invoke($arg1) { 
       echo "Hello: $arg1";
   }   
}

$myClass = new MyClass;
$myClass("PHP");

//Результат:
//Hello: PHP

2. Внешние переменные внутри функции.

<?php

$myName = "PHP 5.3";
function getName() use($myName) {
    echo "Hello: $myName";            
}

getName();

//Результат:
//Hello: PHP 5.3

3. Пространства имен.

Пространства имен позволяют создавать классы с одинаковым именем, но с разным пространством имен (аналог файлов с одинаковым именем в разных папках).

---------------- users/friens/Users.php
<?php

// Объявление пространства имен. Разделитель \. Объявляется в самом начале файла
namespace users\Friends;  
class Users {
  ....
} 

--------------- users/colleague/Users.php
// Если мы поставим разделитель вначале (\colleague\Colleague) это будет означать, что класс
// находится в глобальном пространстве имен. Если вообще не объявлять пространство имен, класс
// также будет находится в глобальном пространстве имен

namespace colleague\Colleague;  
class Users {
  ....
} 

-------------- run1.php
use users\Friends;     // Определяем пространство имен
$friends = new Users();

-------------- run2.php
$friends = new \users\Colleague\Users();  // Второй вариант определения пространства имен

4. Тернанный оператор.

<?php

$str = "Hello";
echo $str ? : "ERROR"; // если после ? ничего не указанно - выведется значение $str

//Результат:
//Hello

5. Сборщик мусора.

Работает без утечки памяти для больших приложений

6. SPL Функции

Описание будет в следующих статьях.

PHP 5.4 (2012)

1. Трейты (trait).

Структура, которая помогает реализовать множественное наследование

<?php 

class A {
    public function foo() {
       return "foo";   
    }
}

// Трейт. Для вызова используется use. Несколько трейтов разделяются запятыми.
trait T {
    public function hello() {
        // $this->name - переменная класса B, parent::foo() - функция класса A
        echo "Hello ".$this->name ." ".parent::foo(); 
    }
}

class B extends A {
    use T;
   private $name = "PHP 5.4";
}

$b = new B();
$b->hello();

//Результат:
//Hello: PHP 5.4 foo

2. Нативная поддержка юникода.

Больше не нужно использовать multibyte и подобные расширения.

3. Короткий синтаксис для объявления массивов.

<?php

$array = [1, 2, 3, 4]; // вместо array()

3. Поддержка разыменования массивов.

<?php

function getArray() {
    return [1, 2, 3, 4];
}

echo getArray()[0]; // 1

4. Встроенный веб-сервер.

Для разработки, чтобы не ставить Apache, Nginx ...

php -S localhost:8000

5. Прогресс для загрузки файлов.

При загрузке файлов, в сессии хранится значение upload_progress_myform. Можно дергать AJAX-ом и смотреть состояние загрузки.

6. Вызов метода или свойства класса выражением.

<?php

class A {
  public static function my_function() {
    return 'Hello';
  }
}

$oneVar = 'my';
$twoVar = 'function';

echo A::{$oneVar . '_' . $twoVar}(); // Hello

PHP 5.5 (2013)

1. Генераторы.

Можно создать функцию для использования в foreach.

<?php

function myGetter($start, $end, $step = 1) {
    for ($i = $start; $i <= $end; $i+= $step) {
        yield $i; // yield прерывает функцию до следующей итерации в foreach.
    }
}

foreach (myGetter(1, 100) as $num) {
     echo $num;  // на самом деле $num - это объект класса Generator      
}

2. Итераторы объектов.

Можно создать свой класс для обхода в foreach. Для этого, нужно реализовать интерфейс Iterator

<?php

class MyIterator implements Iterator {
    private $var = [];

    public function __construct($array) {
        if (is_array($array)) {
            $this->var = $array;
        }
    }

    public function current() {
        $var = current($this->var);
        echo "Текущий: $var\n";
        return $var;
    }

    public function next() {
        $var = next($this->var);
        echo "следующий: $var\n";
        return $var;
    }

    public function key() {
        $var = key($this->var);
        echo "Ключ: $var\n";
        return $var;
    }

    public function valid() {
        $key = key($this->var);
        $var = ($key !== null && $key !== false);
        echo "Верный: $var\n";
        return $var;
    }

    public function rewind() {
        echo "Перемотка в начало:\n";
        reset($this->var);
    }
}

$values = [1, 2, 3, 4];
$it = new MyIterator($values);

foreach ($it as $a=>$b) {
    print "$a: $b\n";
}

Хороший пример использования итераторов можно найти во фреймворке Yii2.

<?php

// получить 10 покупателей одновременно
foreach (Customer::find()->batch(10) as $customers) {
    // $customers - это массив, в котором находится 10 или меньше объектов класса Customer
}

// получить одновременно десять покупателей и перебрать их одного за другим
foreach (Customer::find()->each(10) as $customer) {
    // $customer - это объект класса Customer
}

Таким образом, итерация отлично подходит в тех случаях, когда нужно вывести большой объем данных не загружая все данные в память.

3. Password Hashing API.

Хеширование паролей из коробки. Подробнее в следующих статьях.

4. Ключевое слово ::class.

Используется для получение имени класса.

<?php

namespace myclass;

class MyClass {
}

echo MyName::class; // myclass\ClassName

5. Функция list() в foreach

<?php

$array = [
    [1, 2],
    [3, 4],
];

foreach ($array as list($a, $b)) {
    echo "A: $a; B: $b\n";
}

6. Функция empy().

В функцию empy() - можно указать результат функции или выражения (раньше, нужно было сохранять результат в переменную).

7. finally в исключениях.

Может вызываться вместо или после catch. Код в блоке finally всегда будет выполняться после кода в блоках try и catch, вне зависимости было ли брошено исключение или нет, перед тем как продолжится нормальное выполнение кода.

<?php

try {
    return 2;
} finally {
    echo "Этот текст мы увидим\n";
}

//Этот текст мы увидим
echo "Этот текст мы НЕ увидим";

PHP 5.6 (2014)

1. Скалярные выражения в константах.

<?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

2. Переменное число аргументов функции при помощи ...

<?php

function sum(...$numbers) {
  $sum = 0;
  foreach ($numbers as $n) {
    $sum += $n;
  }
  return $sum;
}

echo sum(1, 2, 3, 4); // - 10

3.Оператор возведения в степень **.

$a ** $b

4. Импорт функций и констант.

<?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

5. Поддержка загрузки файлов больше 2 Гб.

6. В ядро включен интерактивный отладчик phpdbg.

7. Разрешено повторное использование php://input

Разрешено повторное использование php://input, а $HTTP_RAW_POST_DATA объявлена устаревшей.

PHP 6 . Такой версии не существует

PHP 7 (2015)

1. Группировка объявления импорта классов в одном пространстве имен.

<?php

use Framework\Module\{Foo, Bar, Baz};

2. Значение по умолчанию для переменной.

<?php

// до php 7
if (isset($foo)) {
    $bar = $foo;
} else {
    $bar = 'default'; // присваиваем $bar значение 'default' если $foo равен NULL
}

// в php 7
$bar = $foo ?? 'default';
// или цепочкой
$bar = $foo ?? $baz ?? 'default';

3. <=> Трехуровневое сравнение двух значений.

<?php

// позволяя понимать не только их равенство 
// или неравенство, но и то, которое из них больше при неравенстве, возвращая 1,0 или -1.
switch ($bar <=> $foo) {
    case 0:
        echo '$bar и $foo равны';
    case -1:
        echo '$foo больше';
    case 1:
        echo '$bar больше';
}

4. Скалярные типы данных в аргументах функции и тип возвращаемого значения.

<?php

class MyClass {
    public function sum(int $a, int $b): int {
         return $a + $b;
    }    
}

5. Перехват ошибок уровня ядра.

Теперь, все фатальные ошибки можно перехватывать и перебрасывать (try catch)

6. Анонимные классы.

<?php

var_dump(new class { 
       public function log ($msg) {
             return $msg;                    
        } 
});

7. Функии генерации случайного числа и случайной строки (CSPRNG - функции).

<?php

random_bytes(int $len);         
// - случайная строка
random_int(int $min, int $max); // - случайное число

8. Генераторы могут вызывать другие генераторы и возвращать значения.

Это позволяет проверить, правильно ли выполнился генератор.

<?php

function a() {
   yield 1;
   yield 2;
}

function b() {
   yield 3;
   a();
   return 'ok';
}

foreach (b() as $val) {
    echo $val; // 123
}

$b->getReturn(); // ок если не было ошибок.