Изменения, внесенные в PHP 7 в оператор foreach PHP


Оглавление (нажмите, чтобы открыть):

Работаем с массивами в PHP7

Массив представляет собой составной тип данных, который представляет собой связь между ключами и значениями. В PHP это один из самых популярных и мощных типов данных. Существует около 80 функций для работы с массивами. Эта особенность страдает от той же причудливости, приписываемой языку в целом.

  • несовместимое соглашение об именах — asort — это не тот же шаблон, что и array_walk. Более интуитивное имя — array_sort.
  • непоследовательный порядок аргументов — array_filter($array, $callback) и array_map($callback, $array). strpos($haystack, $needle) и array_search($needle, $haytsack).

Тем не менее, массивы никуда не денутся, и их сила не уменьшается. В последних версиях языка были усовершенствованы функции. Давайте кратко рассмотрим две из них.

Константы в PHP

Начиная с PHP 5.3 существует два способа определения констант:

  • с помощью ключевого слова: const
  • и с использование функции: define().

Например, const TOTAL_ITEMS = 5; и define(‘FUNNY_MAN’, ‘Mr Bean’);

Основное отличие заключается в том, что const принимает только статическое скалярное значение (число или строку, а также другие константы, такие как TRUE, FALSE, NULL, __FILE__ и т.д.), в то время как в define вы можете передать любое выражение, например. define(‘DURATION’, 24 * 60 * 60);

Затем в PHP 5.6 добавили возможность для const также принимать выражения: const DURATION = 24 * 60 * 60;. Однако в PHP7 возможности const расширили:

Функции в PHP7 для работы с массивами

Функция array_column, введенная в PHP 5.5, является еще одним примером прогрессивного улучшения функций в PHP 7. Например, учитывая приведенный ниже массив:

До версии PHP 5.5, чтобы получить массив всех столбцов, нужно сделать что-то вроде:

И для индексации столбца другим столбцом, например:

Новая функция также делает это:

Все лучше и лучше. А что относительно PHP7? Теперь array_column принимает массив объектов, из которых вытягивается массив общедоступных свойств:

Мы получаем те же результаты, что и раньше, с

Обратите внимание, что array_column не работает рекурсивно, т. е. он не работает с вложенными массивами.

foreach

(PHP 4, PHP 5, PHP 7)

Конструкция foreach предоставляет простой способ перебора массивов. Foreach работает только с массивами и объектами, и будет генерировать ошибку при попытке использования с переменными других типов или неинициализированными переменными. Существует два вида синтаксиса:

Первый цикл перебирает массив, задаваемый с помощью array_expression. На каждой итерации значение текущего элемента присваивается переменной $value и внутренний указатель массива увеличивается на единицу (таким образом, на следующей итерации цикла работа будет происходить со следующим элементом).

Второй цикл будет дополнительно соотносить ключ текущего элемента с переменной $key на каждой итерации.

Когда оператор foreach начинает исполнение, внутренний указатель массива автоматически устанавливается на первый его элемент Это означает, что нет необходимости вызывать функцию reset() перед использованием цикла foreach.

Так как оператор foreach опирается на внутренний указатель массива, его изменение внутри цикла может привести к непредсказуемому поведению.

Для того, чтобы напрямую изменять элементы массива внутри цикла, переменной $value должен предшествовать знак &. В этом случае значение будет присвоено по ссылке.

Указатель на $value возможен, только если на перебираемый массив можно ссылаться (т.е. если он является переменной). Следующий код не будет работать:

Ссылка $value на последний элемент массива остается даже после того, как оператор foreach завершил работу. Рекомендуется уничтожить ее с помощью функции unset() .

Оператор foreach не поддерживает возможность подавления сообщений об ошибках с помощью префикса ‘@’.

Вы могли заметить, что следующие конструкции функционально идентичны:

= array( «one» , «two» , «three» );
reset ( $arr );
while (list(, $value ) = each ( $arr )) <
echo «Значение: $value
\n» ;
>

foreach ( $arr as $value ) <
echo «Значение: $value
\n» ;
>
?>

Следующие конструкции также функционально идентичны:

= array( «one» , «two» , «three» );
reset ( $arr );
while (list( $key , $value ) = each ( $arr )) <
echo «Ключ: $key ; Значение: $value
\n» ;
>

foreach ( $arr as $key => $value ) <
echo «Ключ: $key ; Значение: $value
\n» ;
>
?>

Вот еще несколько примеров, демонстрирующие использование оператора:

/* Пример 1: только значение */

$a = array( 1 , 2 , 3 , 17 );

foreach ( $a as $v ) <
echo «Текущее значение переменной \$a: $v .\n» ;
>

/* Пример 2: значение (для иллюстрации массив выводится в виде значения с ключом) */

$a = array( 1 , 2 , 3 , 17 );

$i = 0 ; /* только для пояснения */

foreach ( $a as $v ) <
echo «\$a[ $i ] => $v .\n» ;
$i ++;
>

/* Пример 3: ключ и значение */

$a = array(
«one» => 1 ,
«two» => 2 ,
«three» => 3 ,
«seventeen» => 17
);

foreach ( $a as $k => $v ) <
echo «\$a[ $k ] => $v .\n» ;
>

/* Пример 4: многомерные массивы */
$a = array();
$a [ 0 ][ 0 ] = «a» ;
$a [ 0 ][ 1 ] = «b» ;
$a [ 1 ][ 0 ] = «y» ;
$a [ 1 ][ 1 ] = «z» ;

foreach ( $a as $v1 ) <
foreach ( $v1 as $v2 ) <
echo » $v2 \n» ;
>
>

/* Пример 5: динамические массивы */

foreach (array( 1 , 2 , 3 , 4 , 5 ) as $v ) <
echo » $v \n» ;
>
?>

Распаковка вложенных массивов с помощью list()

(PHP 5 >= 5.5.0, PHP 7)

В PHP 5.5 была добавлена возможность обхода массива массивов с распаковкой вложенного массива в переменные цикла, передав list() в качестве значения.

foreach ( $array as list( $a , $b )) <
// $a содержит первый элемент вложенного массива,
// а $b содержит второй элемент.
echo «A: $a ; B: $b \n» ;
>
?>

Результат выполнения данного примера:

Можно передавать меньшее количество элементов в list() , чем находится во вложенном массиве, в этом случае оставшиеся значения массива будут проигнорированы:

foreach ( $array as list( $a )) <
// Обратите внимание на отсутствие $b.
echo » $a \n» ;
>
?>

Результат выполнения данного примера:

Если массив содержит недостаточно элементов для заполнения всех переменных из list() , то будет сгенерировано замечание об ошибке:

foreach ( $array as list( $a , $b , $c )) <
echo «A: $a ; B: $b ; C: $c \n» ;
>
?>

php — foreach изменения в PHP7

foreach в PHP7 по умолчанию при итерации по значению работает на копии массива в соответствии с: https://php.net/manual/en/migration70.incompatible.php

Ленько создает копию только в том случае, если в массив или значение внесены изменения или он всегда будет делать копию и, по сути, зацикливать ссылки на оптимизацию производительности?

Также, массивы объектов все еще петляют/дают вам ссылки на объекты? Или они на самом деле также создают копии для foreach и возвращают объекты по значению?

    2 1
  • 18 май 2020 2020-05-18 14:00:06
  • inquam

1 ответ

В PHP 7, если вы перебираете массив по значению, копия будет выполняться лениво, только когда и если массив действительно будет изменен.

Если вместо этого вы перебираете массив по ссылке, разделение будет выполняться в начале цикла. Если массив используется в более чем одном месте, это разделение приведет к копированию.

Кроме того, итерация по ссылке означает, что a) массив должен быть завернут в ссылку, и b) каждый элемент также должен быть обернут ссылкой. Создание ссылочной обертки — дорогостоящая операция, потому что она требует выделения.

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

Итак, нет, повторение по ссылке — это, конечно, не оптимизация, это де-оптимизация. Обычно используются ссылки.

Что будет нового в PHP 7.4

PHP 7.4 — последняя версия перед PHP 8, содержит множество дополнений и исправлений синтаксиса, будет выпущен 28 ноября 2020 года. Пост создан для помощи в подготовки к предстоящим изменениям.

PHP 7.4 будет содержать немало новых возможностей, начнем с новых функций, а затем рассмотрим изменения и устаревание функционала.

Короткие замыкания RFC

Короткие замыкания допускают менее подробный синтаксис анонимной функции. Вместо многословного:

можно использовать более лаконичное выражение:

Согласитесь, выглядит здорово?!

  • Короткие замыкания могут получить доступ к родительской области, ключевое слово use — не нужно.
  • $this доступен так же, как и у обычных замыканий.
  • Такие замыкания могут содержать в теле только одну строку, которая также является оператором возврата.

Предварительная загрузка (Preloading) RFC

Предварительная загрузка — удивительное дополнение к ядру PHP, которое может привести к значительному улучшению производительности.


Итак, если вы в своей работе используете какой-либо фреймворк, его файлы должны быть загружены и перекомпилированы при каждом запросе. Предварительная загрузка позволяет серверу загружать PHP-файлы в память при запуске и иметь их постоянно доступными для всех последующих запросов.

Предварительная загрузка управляется директивой opcache.preload в файле php.ini . Эта директива указывает PHP-скрипт, который будет скомпилирован и выполнен при запуске сервера. Данный файл может использоваться для предварительной загрузки дополнительных файлов или через функцию opcache_compile_file() (подробнее см. Документацию PHP).

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

Типизированные свойства RFC

Переменные класса могут быть подсказаны типом:

Это очень долгожданное со времён PHP 7 изменение в направлении более строгой типизации языка. Теперь у нас есть все основные возможности для строгой типизации.Для типизации доступны все типы, за исключением void и callable.

Улучшена разница типов RFC

Разница типов — это тема, достойная отдельного сообщения в блоге ; короче говоря: вы сможете использовать противоречивые типы возврата

. и противоречивые аргументы.

RFC в настоящее время находится на этапе голосования, но, похоже, пройдет без проблем

Интерфейс внешней функции RFC

Интерфейс внешней функции, FFI, позволяет вызывать код C из пользовательского пространства. Это означает, что расширения PHP могут быть написаны на чистом PHP.

Следует отметить, что это сложная тема. Вам все еще нужны знания C, чтобы правильно использовать эту функцию.

Оператор присваивания значения NULL RFC

Появится возможность использовать синтаксис «если левый параметр не существует или равен null, присвоить ему значение правого параметра».

Т.е. вместо этого:

Вы можете сделать это:

Оператор распаковки (. ) в массивах RFC

Теперь можно использовать оператор распаковки в массивах:

Это работает только с массивами с числовыми ключами, с ассоциативными массивами распаковка работать не будет, ошибка будет выдана при обнаружении строкового ключа. Оператор спреда должен иметь лучшую производительность, чем array_merge. Это объясняется не только тем, что оператор распаковки является языковой структурой, в то время как array_merge является функцией, но и оптимизация времени компиляции может быть выполнена для констант массива. Плюс array_merge поддерживает операции только над массивами, а оператор спреда поддерживает реализацию объектов Traversable.

Пользовательская сериализация объектов RFC

В настоящее время PHP предоставляет два механизма для настраиваемой сериализации объектов: методы __sleep()/__wakeup() и Serializable интерфейс. К сожалению, по словам Никиты, оба подхода имеют проблемы., которые приводят к сложному и ненадежному коду Этот RFC добавляет два новых магических метода: __serialize и __unserialize, которые позволяют избежать этих проблем

Использование очень похоже на Serializable интерфейс. С практической точки зрения главное отличие состоит в том, что вместо вызова serialize() внутри Serializable::serialize() вы напрямую возвращаете данные, которые должны быть сериализованы в виде массива. В следующем примере показано, как __serialize()/__unserialize() используются и как они составляются при наследовании:

Разделитель числовых литералов RFC

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

Рефлексия для ссылок RFC

Такие библиотеки как var dumper Symfony, в значительной степени полагаются на API Рефлексии для надежного вывода переменной. Раньше не было должной поддержки рефлексии для ссылок, в результате чего эти библиотеки полагались на «хаки» для обнаружения ссылок.

PHP 7.4 добавляет класс ReflectionReference, который решает эту проблему.

Обновление 02-14: RFC пройден, и изменения подтверждены для PHP 7.4.

Слабые ссылки

Слабые ссылки — это ссылки на объекты, которые не мешают их уничтожению. PHP 7.4 вводит класс WeakReference , который позволяет программистам сохранять ссылку на объект, который не препятствует уничтожению самого объекта. В настоящее время PHP поддерживает Weak References, используя расширение вроде pecl-weakref . В любом случае, новый API отличается от документированного WeakRefкласса.

Вот пример от автора этого предложения, Никиты Попова:

Сначала var_dump выведет object(std >NULL , так как указанный объект был уничтожен.

Добавлена функция mb_str_split RFC

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

Реестр хэширования паролей RFC

Внутренние изменения в библиотеке хеширования, чтобы пользователям было проще использовать хэширование. Добавлена новая функция password_algos, которая возвращает список всех зарегистрированных алгоритмов хеширования паролей

Изменения и устаревание

Помимо новых функций, есть также много изменений в языке. Большинство этих изменений не нарушают работу программиста, хотя некоторые из них могут повлиять на уже написанный вами код.

Обратите внимание, что предупреждения об устаревании не являются критическими, а просто уведомляют разработчика о том, что функциональность будет удалена или изменена в будущем. Было бы хорошо не игнорировать предупреждения об устаревании и сразу же их исправлять; поскольку это сделает путь обновления для PHP 8.0 более простым.

Если бы вы написали что-то вроде этого:

PHP ранее интерпретировал бы это так:

PHP 8 сделает так, чтобы он интерпретировался так:

В PHP 7.4 при обнаружении выражения без скобок, добавлено предупреждение об устаревании синтаксиса, содержащего «.» перед «+» или «-».

Разрешены исключения в __toString RFC

Ранее исключения не могли быть добавлены в магический метод__toString. Они были запрещены из-за некоторых старых механизмов обработки ошибок, правда Никита Попов отметил, что это «решение» на самом деле не решило проблему, которую он пытался решить.

RFC все еще находится на стадии голосования, но с 32 голосами за и 0 против, можно с уверенностью сказать, что это пройдет.

Мастер Йода рекомендует:  Виртуальная реализация SQL Server 2005

ext-hash всегда включен RFC

Как видно из заголовка, это расширение теперь постоянно доступно во всех установках PHP.

PEAR по умолчанию больше не включен ВНЕШНЕЕ

Поскольку PEAR больше не поддерживается, основная команда решила удалить установку по умолчанию с PHP 7.4.

Этот формат обмена данными никогда не был стандартизирован, и теперь его расширение устарело.

Короткие теги PHP устарели RFC

Короткий открытый тег array_merge и array_merge_recursive без аргументов

Поскольку добавлен оператор распаковки (. ), теперь имеет смысл использовать array_merge так:

Теперь array_merge и array_merge_recursive позволяют передавать пустой список параметров. Пустой массив будет возвращен, если не было передано ни одного массива.

strip_tags принимает массивы

Ранее несколько тегов можно было бы удалить только перечислением тегов в строке:

PHP 7.4 позволяет использовать массив:

Лево-ассоциативный тернарный оператор устареет RFC

Тернарный оператор имеет некоторые странные особенности в PHP. Этот RFC добавляет статус деприкейт для вложенных троичных операторов. В PHP 8 это устаревание будет преобразовано в ошибку времени при компиляции.

Устарели фигурные скобки для доступа к массивам и строкам

Раньше можно было получить доступ к массивам и смещениям строк, используя фигурные скобки:

Теперь лучше от этого отказаться.

Улучшение в proc_open улучшения

Были внесены изменения, чтобы proc_open мог выполнять программы, не проходя через shell. Это делается путем передачи массива вместо строки для команды .

Список некоторых устаревших вещей

  • Тип real
  • Magic quotes legacy
  • array_key_exists() с объектами
  • FILTER_SANITIZE_MAGIC_QUOTES фильтр
  • Метод Reflection export()
  • mb_strrpos() с указанием кодировки 3 аргументом
  • implode() параметр порядка смешивания
  • Открепление $this от нестатических замыканий ($closure->bindTo(null))
  • функция hebrevc()
  • функция convert_cyr_string()
  • функция money_format()
  • функция ezmlm_hash()
  • функция restore_include_path()
  • директива ini allow_url_include

Обратно несовместимые изменения

Так же не забываем смотреть на полный документ обновлений версий PHP.

Можно выделить следующие несовместимых назад изменений:

  • Вызов parent:: в классе без родителя вызовет ошибку.
  • Использование var_dump для DateTime или DateTimeImmutable больше не будет выводить доступные свойства объекта.
  • openssl_random_pseudo_bytes сгенерирует исключение в случае ошибки. Раньше она возвращала false, что могло привести к генерации пустой строки.
  • Попытка сериализации экземпляров PDO или PDOStatement сгенерирует Exception вместо PDOException.
  • Вызов get_object_vars() для ArrayObject экземпляре будет возвращать свойства самого ArrayObject, а не значения обернутого массива или объекта. Чтобы как раньше получить значения обернутого массива — приведите ArrayObject к типу array


Изменились правила голосования RFC RFC

Технически это не обновление, связанное с PHP 7.4, хотя это, безусловно, стоит упомянуть. Правила голосования для RFC были изменены: для принятия RFC требуется 2/3 голосов, все RFC должны быть открыты не менее 2 недель, чтобы пройти одобрение.

Веб-разработчик со стажем программирования более 6 лет, постоянно учусь, люблю делать новые проекты.

Блог Александра Денисюка

Два месяца назад я перешёл на PHP7 и в этом посте хочу поделиться нововведениями, которые пришлись по нраву мне больше всего. Во первых, переход на новую ветку PHP обусловлен приростом производительности и уменьшением потребляемых ресурсов, т. е. крупные сайты с PHP7 могут в два раза снизить расходы на хостинг и быстрее генерировать конечному пользователю. Здесь выигрывают сразу и владельцы сайтов, и их посетители.

Это сравнение скорости между версиями 5.6 и 7.0 на различных платформах. Zend Framework даёт прирост скорости на 133%, а WordPress — 129%. Такое улучшение PHP имеет позитивные последствия для бизнеса.

В прошлом году Badoo, WordPress.com, Tumblr и многие другие гиганты перешли на PHP7. Так, например, компании Badoo за счёт снижения CPU в два раза и уменьшения потребления памяти в 8 раз удалось сэкономить 1 млн долларов. Сайт WordPress.com также полностью переведён на PHP7, где прирост производительности действительно заметен:

https://t.co/VrQffeOtG0 has been 100% switched over to PHP7, bringing significant performance improvements. #wcus pic.twitter.com/MChiS9QBJh

Быстродействие в новых версиях стало самым крутым и обсуждаемым нововведением. Теперь не нужно заморачиваться по оптимизации каких-то участков кода, а сразу писать понятный и поддерживаемый код. Во вторых, в PHP 7.0 и 7.1 введено большое количество улучшений на уровне синтаксиса и функциональности. Далее на примерах я покажу, что мне понравилось в новых версиях и как эти нововведения поменяют язык PHP в будущем на уровне кода.

Замена тернарного оператора

На замену тернарного оператора пришёл «оператор объединения с null» или «null-коалесцентный оператор». Через два знака вопроса (??) можно указать цепочку значений в одну строку и будет выбрано первое значение, которое не равно null. Раньше этот подход применялся вместе с функцией isset(). Сейчас можно указать даже не существующие переменные и не мучатся c большой вложенностью как с тернарным оператором.

Групповое объявление классов, констант и функций

Начиная с версии 7.0 появилась возможность группировать объявления импорта классов, функций и констант, находящиеся в одном пространстве имён, в одной строке с помощью оператора use. Это нововведение на уровне синтаксического сахара, которое может наделить объявление имён компонентов определённой логикой.

Декларация типов и возвращаемых значений

Это самое мощное нововведение для ООП. Теперь при объявлении метода для каждой переменной можно указать свой тип, а также тип данных, который вернёт этот метод. В PHP 7.0 доступны следующие типы: array, callable, bool, float, int, string, имя класса или интерфейса. В версии 7.1 добавили ещё vo >iterable. Тип vo >iterable используется в качестве значения массива или объекта, реализующего интерфейс Traversable.

В примере выше отработала принуждающая декларация типов, т. е. PHP динамически привёл значения к нужному типу, когда в переменную с объявленным типом int мы передали string, например. Вместо того, чтобы сгенерировать ошибку, все значения переменных и результат функции был преобразован к указанному типу на лету. Это поведение установлено по умолчанию.

Строгую типизацию можно включить, если в начале скрипта прописать declare(strict_types=1) . Все значения должны полностью соответствовать указанным типам. В противном случае будет сгенерирована ошибка TypeError. Строгая типизация не затрагивает весь остальной код и её нужно прописывать для каждого скрипта отдельно.

В версии 7.1 появилась возможность обнулить возвращаемые типы. Это расширяет список возвращаеммых типов до null. Теперь функция может вернуть какой-то явно указанный тип или null. Достигается такое поведение путём добавления префикса в виде знака вопроса к указанному типу:

Декларация типов и возвращаемых значений выводит PHP на новый уровень и эти нововведения мне нравятся больше всего, т. к. со стороны разработчика повышается читабельность кода; чёткая согласованность входных и выходных данных; программист может быстрее понять, чего ожидать от функции; легче документировать код; появляется возможность изменять типы данных на лету. Это основополагающая функциональность PHP7, которой не знать уже сейчас недопустимо.

Обработка ошибок и исключений

В PHP 7.0 появился новый класс для внутренних ошибок Error и интерфейс исключений Throwable. Теперь Error и старый класс Excetion реализуют Throwable (пользовательские классы не могут реализовывать данный интерфейс). Exception можно использовать для отлова исключений, которые будут обработаны и выполнение программы продолжится. Класс Error служит для необратимых исключений и выбрасывается в случае ошибки PHP или на уровне ошибок разработчиков.

Большинство ошибок уровня E_ERROR или E_RECOVERABLE_ERROR будут выбрасывать Error, но некоторые будут выбрасывать объекты подклассов: ArithmeticError, AssertionError, ParseError, DivisionByZeroError, TypeError и ArgumentCountError (с версии 7.1). Эти подклассы ошибок не могут быть брошены самостоятельно, а только лишь словлены. Иерархию всех исключений можно представить в виде дерева:

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

На место фатальных ошибок пришли исключения, которые могут быть обработаны и позволяют корректно завершить программу в случае каких-то косяков. Это добавляет гибкости PHP-приложению.

Остальные нововведения одним списком

Нововведения в PHP7+ это лишь начало большого перехода на новый уровень языка. С каждым релизом приложения будут становиться быстрее и безопаснее. На версии 7.0 и 7.1 нужно отреагировать уже сегодня и будь в курсе новых тенденций PHP, дабы не выпадать из сферы. Ниже привожу одним списком остальные нововведения:

7.0 Оператор spaceship (космический корабль) ↩
7.0 Задание констант массивов с помощью define() ↩
7.0 Появились анонимные классы ↩
7.0 Синтаксис кодирования Unicode ↩
7.0 Добавлен метод в замыкания Closure::call() ↩
7.0 unserialize() с фильтрацией ↩
7.0 Новый класс IntlChar ↩
7.0 Улучшена старая функция assert() ↩
7.0 Выражение return в генераторах ↩
7.0 Делегация генератора с помощью конструкции yield from ↩
7.0 Новая функция intdiv() для целочисленного деления ↩
7.0 session_start() принимает массив опций ↩
7.0 Новая функция preg_replace_callback_array() ↩
7.0 Новые функции random_bytes() и random_int() ↩
7.0 list() может раскрывать объекты реализующие ArrayAccess ↩
7.0 Обращение к методам и свойствам класса при клонировании (clone $foo)->bar() ↩
7.1 Короткий синтаксис для list() ↩
7.1 Публичные и приватные константы классов ↩
7.1 Поддержка ключей в list() ↩
7.1 Поддержка отрицательных смещений для строк ↩
7.1 Расширены функции openssl_encrypt() и openssl_decrypt() ↩
7.1 Преобразование callable в Closure с помощью Closure::fromCallable() ↩
7.1 Новая функция pcntl_async_signals() ↩
7.1 Поддержка Server Push в CURL 7.46 ↩

PHP7 Что нового?

сейчас выбросит ошибку strict standards вне зависимости от скобок (ранее во втором вызове ее не было).

4. Элементы массива или свойства объекта, которые были автоматически созданы во время присвоений по ссылке сейчас будут иметь другой порядок. Код:

сейчас сгенерирует массив [«a» => 1, «b» => 1], тогда как ранее был [«b» => 1, «a» => 1].

Изменения в обработке list()
1. list() теперь присваивает переменные в прямом порядке (ранее — в обратном), например:

сейчас выдаст $array == [1, 2, 3] вместо [3, 2, 1]. Изменился только порядок присвоения, т.е. нормальное использование list() не затронуто.

2. Присвоения с пустым списком list() стали запрещены, следующие выражения ошибочны:

проитерирует и добавленный элемент. Вывод будет «int(0) int(1)», ранее было только «int(0)».

4. Итерирование обычных (не Traversable) объектов по значению или по ссылке будет вести себя как итерирование по ссылке для массивов. Ранее — аналогично, за исключением более точного позиционирования из предыдущего пункта.

5. Итерирование Traversable объектов не изменилось.

Изменения в обработке аргументов функций
1. Больше нельзя использовать одинаковые имена для аргументов (будет ошибка компиляции):

теперь выдаст:
Stack trace: #0 file.php(4): foo(42) #1

Ранее было бы так:
Stack trace: #0 file.php(4): foo(‘string’) #1

Хоть это и не влияет на исполнение, но следует иметь это в виду при отладке. То же ограничение теперь и в debug_backtrace() и прочих функциях, исследующих аргументы.

Изменения в обработке integer
1. Некорректные восьмеричные числа будут выдавать ошибку компиляции:

Из других изменений документ отмечает теперь отсутствие $this для нестатических методов, вызванных статически (ранее метод использовал $this вызывающего контекста).

Пополнился, что логично, список недоступных для классов, трейтов и интерфейсов имен — добавлены bool, int, float, string, null, false, true, а также для будущего использования: resource, object, mixed, numeric.

Конструкт yield не требует больше скобок при использовании в выражениях. Он теперь право-ассоциативный оператор с приоритетом между «print» и «=>». Поэтому поведение может измениться:

Эти случаи рекомендуется принудительно уточнять скобками.

Из заметных изменений в стандартной библиотеке функций отмечу только удаление call_user_method() и call_user_method_array(), остальное не столь значительно (выкинули dl() в php-fpm, переименовали и оптимизировали zend_qsort -> zend_sort, добавили zend_insert_sort, немного поменяли поведение setcookie при пустом имени cookie и убрали фатальную ошибку ob_start внутри буферизации).

Самой большой причиной для перехода на PHP7 является его производительность, которая своими характеристиками в первую очередь обязана phpng. Увеличение производительности может стать решающим фактором для быстрого перехода на 7ю версию маленькими хостерами, ведь им удастся разместить больше клиентов на том же оборудовании.

На текущий момент дела обстоят следующим образом: PHP7 находится на одном уровне с HHVM, написанным фейсбуком, который работает в качестве Just In Time (JIT) компилятора, переводящего PHP-код в машинные инструкции.

PHP7 не имеет JIT-компилятора, хотя было много дискуссий о нем. Непонятно какой прирост производительности даст этот шаг, но уверен, будет интересно посмотреть, если кто-то все же решится его сделать!

В дополнение к производительности, приятным побочным эффектом оптимизации внутренней структуры данных будет и значительная экономия памяти.

05.12.2015, 15:46

Проблемы с PHP7
Здравствуйте. Работаю на Ubuntu и установил LAMP > (тоже самое что и WAMP). Эта зараза установила.

Mysql_real_escape_string в PHP7
Всем доброго ) У меня вот такая проблема. Особо что у PHP7 нового не интересовался, но вот.

Php5 -> php7
Здравствуйте. решил перевести свой сайт на php7 но проблема в том, что он на myslq и само ядро.

странности php7?
Привет всем! Заметил странность $n1 = 1000000000; $n2 = 9999999999; $n3 = 1111111111; .

Call_user_func_array php7
При переходе на php7 возникла ошибка Function name must be a string $result =.

PHP 7 changes to foreach: Can I still delete items in they array on which I’m iterating?

When used in the default by-value mode, foreach 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.

I’m trying to understand what this means, and my main question is whether this code will work the same in PHP 7 as it does in PHP 5.6?

My two questions are:

Will this code still work?

If so, can you explain (maybe by example) what this new change in PHP 7 means?

Edit

I’ve been re-reading the doc statement. I’m thinking that what it means is that, if you change values of items lower down in the array, those changes won’t be there when you get to those items in the iteration. Example:

However, when I run this example it doesn’t seem to show any difference in PHP versions (although I’ve never used this tool before, so I’m not sure how it works).

I realize that if I do it by reference, I’ll get an a in new. Otherwise I won’t. But this seems to be the case in both versions.

What I really need to know is what is the incompatibility (by example)?

Edit 2

The answer link suggested by @NikiC provides the rest of the story I was looking for:

In most cases this change is transparent and has no other effect than better performance. However there is one occasion where it results in different behavior, namely the case where the array was a reference beforehand:

Previously by-value iteration of reference-arrays was special cases. In this case no duplication occurred, so all modifications of the array during iteration would be reflected by the loop. In PHP 7 this special case is gone: A by-value iteration of an array will always keep working on the original elements, disregarding any modifications during the loop.

This answer explains the rare «special case» where things work different between versions in regarding foreach operating on a copy of the array.

PHP 7.4: Изменения

Прошло совсем немного времени с релиза текущей актуальной версии PHP 7.3, а комьюнити и команда разработчиков языка уже вовсю работает над списком изменений для следующей версии — PHP 7.4.

Мастер Йода рекомендует:  Кросс-доменный Ajax в jQuery Javascript

По аналогии с чейнжлогом PHP 7.3 данный пост будет дополняться до тех пор, пока не состоится официальный релиз стабильной версии PHP 7.4. С учетом цикла разработки это произойдет в ноябре-декабре 2020 года. Стоит также напомнить, что уже 30 ноября 2020 года будет окончательно прекращен выпуск обновлений (кроме обновлений безопасности) для PHP 7.1 поэтому для всех, кто использует эту или, что еще хуже, более ранние версии языка в своих проектах настало время апгрейда.

UPD: График выхода PHP 7.4:

  • 13 июня — Alpha 1
  • 27 июня — Alpha 2
  • 11 июля — Alpha 3
  • 22 июля — Прекращение добавления нового функционала
  • 25 июля — Beta 1
  • 8 августа — Beta 2
  • 22 августа — Beta 3
  • 5 сентября — RC 1
  • 19 сентября — RC 2
  • 3 октября — RC 3
  • 17 октября — RC 4
  • 31 октября — RC 5
  • 14 ноября — RC 6
  • 28 ноября 2020 — Стабильная версия

Навигация

Список изменений

Предварительная загрузка

Данное нововведение базируется на технологии «Class Data Sharing» от Java HotSpot VM. Оно предоставляет пользователю возможность использовать гибкость кэширования, предоставляемого PHP (APC, Turck MMCache, Zend OpCache) для увеличения производительности собственных приложений. При запуске сервера, перед запуском любого приложения появится возможность скомпилировать и сохранить в памяти определенный набор файлов PHP, сделав их доступными сразу при последующих запросах. Все функции и классы из этих файлов будут доступны для использования прямо из коробки абсолютно так же, как и внутренние объекты ( \Exception или strlen() , например).

Таким образом появится возможность предзагрузки целых фреймворков, библиотек. Это также позволит добавлять “встроеннные” функции, написанные на PHP (по аналогии с HHVM sytemlib).

Предварительная загрузка будет контролироваться новой директивой php.ini — opcache.preload . В ней будет указан путь к файлу PHP, который будет загружен в память. Этот файл может загружать другие файлы, используя их или функцию opcache_compile_file() .

Например, этот файл добавляет новую функцию и использует ее для загрузки всего Zend Framework.

Предварительно загруженный файл остается в кэше навсегда и для его обновления потребуется перезагрузка сервера. opcache_reset() не сможет и не будет перезагружать предварительно загруженные файлы, а opcache_get_status() будет дополнен для предоставления информации о предварительно загруженных функция, классах и скриптах в индексе preload_statistics .


Кроме того, во избежание недоразумений не будет изменяться поведение статических данных классов. В предварительной загрузке смогут участвовать только классы с доступным родителем и интерфейсом, без динамических переменных, — иначе будет вызвано поведение как для класса без предварительной загрузки.

В Windows невозможно будет предварительно загрузить классы, унаследованные от внутренних.

Хэш-расширение всегда доступно

Расширение хэша ext/hash будет всегда доступно подобно date , spl и pcre .

Аргумент –enable-hash , используемый в конфигурации сборки удален.

Реестр хэш-расширений

Будет добавлен механизм реестра хэш-расширений password_algos() .

Типизированные свойства

7 версия языка добавила возможность указывать скалярный или структурированный тип для аргументов функций и методов, а также скалярный тип для возвращаемых ими значений. PHP 7.4 дополнит это изменение возможностью указывать типы свойств классов.

Изменения openssl_random_pseudo_bytes()

В случае ошибки генерации строки в openssl_random_pseudo_bytes() будет вызван \Exception с описанием проблемы. Присваемое второму аргументу $crypto_strong значение гарантированно будет true в случае, если не сработал механизм вызова ошибки.

FFI — Интерфейс для внешних функций на C

FFI — полезная фича из Python и LuaJIT, позволяющая работать с функциями и данными C из скриптового языка. Для PHP FFI открывает способ написания расширений и привязок PHP к библиотекам C на чистом PHP.

Для минимизации рисков использование данного интерфейса будет определяться директивой php.ini ffi.enable — false отключить, true включить везде и preload (по-умолчанию) разрешить использование только в файле предварительной загрузки.

У класса FFI доступны следующие методы:

  • FFI::cdef([string $cdef = «» [, string $lib = null]]): FFI
  • FFI::new(mixed $type [, bool $own = true [, bool $persistent = false]]): FFI\CData
  • FFI::free(FFI\CData $cdata): void
  • FFI::cast(mixed $type, FFI\CData $cdata): FFI\CData
  • FFI::addr(FFI\CData $cdata): FFI\CData
  • FFI::type(string $type): FFI\CType
  • FFI::arrayType(FFI\CType $type, array $dims): FFI\CType
  • FFI::typeof(FFI\CData $data): FFI\CType
  • FFI::sizeof(mixed $cdata_or_ctype): int
  • FFI::alignof(mixed $cdata_or_ctype): int
  • FFI::memcpy(FFI\CData $dst, mixed $src, int $size): void
  • FFI::memcmp(mixed $src1, mixed $src2, int $size): int
  • FFI::memset(FFI\CData $dst, int $c, int $size): void
  • FFI::string(FFI\CData $src [, int $size]): string
  • FFI::load(string $file_name): FFI
  • FFI::scope(string $scope_name): FFI

Более подробно о доступных методах можно прочитать в RFC.

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

NATIVE FFI
Python 0.212 0.343
PyPy 0.010 0.081
LuaJit -joff 0.037 0.412
LuaJit -jon 0.003 0.002
PHP 0.040 0.093
PHP + jit 0.016 0.087

Комбинированный оператор слияния с null

В PHP 7 добавилась возможность указывать значение в виде $foo ?? ‘baz’ , что звучит как «если $foo существует и не равен null присваивается $foo , иначе ‘baz’ «. Теперь отсутствует необходимость дублировать переменную при проверке через isset($foo) ? $foo : ‘baz’ , что немного облегчило процесс чтения кода.

В PHP 7.4 появится возможность использовать синтаксис «если левый параметр не существует или равен null , присвоить ему значение правого параметра». В коде это выглядит так:

Включение mb_str_split() в mbstring

mb_str_split() — новая функция, разбивающая многобайтовую строку на чанки по n символов каждый в PHP 7.4 станет частью расширения mbstring .

Рефлексия для ссылок

Появится новый глобальный класс, часть Reflection API — ReflectionReference . По сути он будет работать как spl_object_hash() , но отвечать за работу с ссылками а не объектами.

Доступный изначально статический метод fromArrayElement(array $array, int|string $key) вернет экземпляр ReflectionReference если $array[$key] является ссылкой, иначе null .

Если $array не является массивом или $key не строка или число, вызовется TypeError . В сценарии, когда $array[$key] не существует будет вызвано исключение ReflectionException .

Новый механизм сериализации объектов

Сегодня PHP предлагает два механизма для настраиваемой сериализации объекта — магические методы __sleep() / __wakeup() и интерфейс Serializable . PHP 7.4 добавится новый механизм, пытающийся совместить в себе универсальность Serializable и подход к реализации __sleep() / __wakeup() .

Работа будет происходить через 2 новых метода:

Они очень похожи на Serializable . Отличие от интерфейса состоит в том, что вместо сериализованных строк работа происходит с исходными массивами.

Стрелочные функции

Появится новый вид функций, аналог анонимных — «стрелочные». Грубо говоря, это однострочная анонимная функция с облегченным синтаксисом.

Синтаксис выглядит как fn(arguments) => expression , где fn — ключевое триггер-слово (обратите внимание, что для обратной совместимости необходимо будет избавиться от функций с аналогичным названием), arguments — список передаваемых аргументов, expression — «тело» функции. use (arguments) объявлять не требуется.

Стрелочные функции поддерживают типизацию.

В теле функции можно использовать классовый $this . В случае необходимости ограничения можно запретить поведение указанием static перед функцией.

Левоассоциативный тернарный оператор объявлен устаревшим и удален

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

В качестве исключения скобки не требуются при объединении двух коротких тернарных операторов а также при вложении в средний операнд.

Оператор переменного количества в массивах

Известный ранее по аргументам функций синтаксис foo(..$args) теперь доступен для использования в массивах.

Остается невозможным использование конструкции в пустом массиве.

ext/interbase удален и доступен в PECL

Данное расширение, предназначенное для работы с БД InterBase и Firebird довольно давно «заброшено» и без поддержки комьюнити исправления и нововведения, которые могли бы появиться добавлялись бы «вслепую». В связи с этим принято удалить расширение из PHP 7.4 и опубликовать его в PECL.

Слабые ссылки

Слабые ссылки позволяют программисту сохранять ссылку на объект, которая не препятствует его уничтожению. Они полезны для реализации кеш-подобных структур. В настоящее время они поддерживаются в PHP расширением.

В новой версии PHP их поддержка будет доступна «из коробки» через добавленный класс.

Удаление ext/wddx

WDDX был создан как независимый от ЯП формат обмена данный для Web 1.0. Формально он не был стандартизирован и в текущих реалиях вполне может быть заменен другими форматами, такими как JSON.

В PHP 7.4 будет удален весь функционал, связанный с данным форматом.

Изменение приоритета оператора конкатенации

Сейчас приоритет операторов . , + и — равен. Любая их комбинация просто отрабатывает слева-направо.

В PHP 8.0 оператору . будет дан более низкий приоритет, из-за чего первыми будут обработаны операции сложения/вычитания.

В версии 7.4 при обнаружении строк, где комбинируется строковой оператор . c + или — без скобок будет вызвано Deprecated уведомление.

Визуальный числовой разделитель

Появится новый визуальный разделитель _ , используемых в числовых литералах.

Он предназначен лишь для улучшения читабельности числовых значений и никакого эффекта на функциональность оказывать не будет.

Разрешение вызова Exception в __toString

В настоящее время вызов Exception в магическом методе __toString запрещен и вызовет фатальную ошибку. В PHP 7.4 данное ограничение уберут.

Развитие синтаксиса PHP — новинки версий 5.3-7.1

В этой статье я рассмотрю интересные моменты в развитии синтаксиса PHP — получится своего рода список изменений PHP. Что появилось в версиях PHP 5.3 и выше. Основная цель этой статьи создать некую карту изменений синтаксиса, что можно было быстро освежить в памяти «фишки» синтаксиса PHP, которые упрощают коддинг. У меня в последнее время частенько возникает необходимость убедиться, что можно в PHP 5.3, а чего нельзя.

При написании плагинов или тем WordPress можно использовать только возможности PHP 5.3, выше пожалуй не стоит. Все что можно в PHP 5.4 и выше, нужно решать через создание вспомогательных переменных. Впрочем, даже 5.3 не всегда работает, есть еще серверы с PHP 5.2, но хорошо что это редкость. К слову, сам WordPress еще поддерживает PHP 5.2.

Итак, к новинкам.

$str1 <0>— синтаксис получения символа строки

Новый синтаксис обращения к символам строки:

$str2[0] не рекомендуется, хотя и работает точно также. Рекомендация использовать фигурные скобки <> связана с тем, чтобы при прочтении кода было сразу понятно, что обрабатывается строка, а не элемент массива. Как мы знаем квадратными скобками в PHP принято обозначать массивы, а не строки.

В PHP 5.3, как и во всей пятой ветке PHP, включена новая машина-интерпретатор скриптов Zend Engine 2.0. Благодаря этому PHP стал работать быстрее примерно на 15-20%.

Новые возможности в PHP 5.3 (ссылка на офф. сайт):

?: — сокращение тернарного оператора

С PHP 5.3 стало возможным не писать среднюю часть тернарного оператора. Выражение expr1 ?: expr3 возвращает expr1 если expr1 не пустой, и expr3 в противном случае.

Тернарный — состоящий из трёх частей, компонентов.

Пример тернарного оператора:

В короткой записи есть еще момент производительности, например:

В полной записи функция get_post_meta() вызывается 2 раза. В короткой один раз, и если она что-то вернула, второму аргументу сразу передается полученное значение: не нужны дополнительные переменные.

$func = function()<>; — анонимные (лямбда) функции

Лямбда-функции еще называют «анонимными функциями», потому что для них не указывается название.

Лямбда-функции представляют собой замыкание (англ. closure) — это особый вид функции, которая определена в теле другой функции и создаётся каждый раз во время её выполнения. Синтаксически это выглядит как функция, находящаяся целиком в теле другой функции. Насколько я понял, любая функция — это замыкание текущего контекста, т.е. контекст не будет очищен пока работает функция. Но если в функции есть лямбда-функция, то она становится замыканием, и если в неё передаются переменные из «верхней» функции, то они не будут очищены, до тех пор пока работает вложенная-функция, даже если «верхняя» функция работу закончила.

В ранних версиях, анонимные функции создавались с помощью функции create_function() .

Пример создания анонимной функции для сортировки usort():

Еще одна фишка лямбда-функций — это использование переменных из текущей области видимости, с помощью оператора use :

Переменные передаются как значение, но можно передать и ссылку на переменную, указав & :

method()->var — получение объекта из метода/функции

В PHP ниже 5.3 писали как-то так:

В php 5.3 можно использовать аналог HEREDOC, который называется NOWDOC. Особенность его в том, что внутри него переменные остаются простым текстом, как если бы мы указали её в строке с одинарными кавычками: ‘текст $foo’ :

namespace — поддержка пространств имен


Пространства имен нужны, чтобы избежать конфликтов при совпадении названий функций/классов/переменных/констант. Если коротко: одинаковые называния в разных пространствах — это разные названия.

Пример ниже должен объяснить почти все, что возможно в пространствах имен. За подробностями идем в официальную документацию.

__DIR__ — новая магическая константа

__DIR__ содержит директорию текущего файла — файла в котором она используется. Возвращает полный путь до текущего файла без закрывающего слэша, за исключением корневой директории.

__DIR__ можно заменить:

$class::$foo — динамичное указание класса

Это дает динамичный доступ к статическим методам/свойствам класса:

const — ключевое слово для создания констант вне классов

Сразу пример, где все понятно:

В отличие define() , такие константы, должны быть объявлены в самой верхней области видимости, потому что они определяются при компилировании скрипта. Это значит, что их нельзя объявлять внутри функций/циклов/выражений if или try/ catch блоков.

static::method() — статическое связывание

Статическое объявление метода/свойства связывает его с классом из которого оно вызывается, а не с тем в котором оно зарегистрировано. Посмотрим на примере:

Подробнее про статическое связывание читайте в документации.

goto hell; — оператор goto

Используется для перехода в другую часть программы. Место, куда необходимо перейти указывается с помощью метки, за которой ставится двоеточие, после оператора goto указывается желаемая метка для перехода.

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

Также нельзя перейти внутрь любой циклической структуры или оператора switch. Но можно выйти из любой циклической структуры, поэтому «goto» удобен как замена многоуровневых break.

Пример использования goto:

Пример использования goto в цикле:

__callStatic() , __invoke() — магические методы

__callStatic() — срабатывает, когда вызывается несуществующий метод из статического контекста: Foo::bar() :

__invoke() — срабатывает, когда объект выполняется как функция: $obj() :

Возможности, добавленные в версии PHP 5.4. Ссылка на офф. сайт.

— короткая запись вывода на экран работает всегда

Короткая запись о которой идет речь это: вместо .

Для работы такой короткой записи вывода на экран в версиях ниже 5.4 нужно было, чтобы опция short_open_tag в php.ini была включена.

Пример длинной и короткой записи:

[1,2] — запись массива, без слова array

trait Class <> — примеси (трейты)

Трейт — это аналог класса, который содержит в себе методы. Нужен он для «подмешивания» его в имеющийся класс, чтобы методы трейта стали методами класса в который он добавлен.

Несколько примесей можно задавать через запятую:

Приоритеты трейтов

При совпадении названий свойств/методов приоритеты расставляются так: текущий класс имеет наивысший приоритет, затем трейт, а затем расширяемый класс. Другими словами: элементы из текущего класса переопределяют элементы в трейте, которые в свою очередь переопределяют унаследованные элементы.

Статический доступ к методу примеси из класса

Когда в класс подмешивается trait, то его методы становятся методами класса, включая статические и статический доступ:

foo()[0] — быстрое получение элемента массива

Теперь не нужно сохранять массив, который вернула функция/метод в переменную и получать элемент массива из этой переменной. Можно сразу получать элемент из функции/метода:

(new Foo)->method() — доступ к элементу объекта при его создании

Class::<'foo'>() — динамичное указание метода

Чтобы вызвать статический метод/свойство класса, не нужно запоминать его в отдельную переменную:

callable — новый тип для аргументов функции/метода

Авто-проверка передаваемых данных в функции/методы, известная как «контроль типа» (typehint), продолжает развиваться и теперь понимает слово callable .

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

Теперь, можно указать еще: callable — значит, что передаваемый аргумент должен быть вызываемым, т.е. удовлетворяет условию is_callable( $arg, false ) .

Оператор @ нужен для подавления вывода ошибок любого уровня. Вообще его использовать не рекомендуется, но иногда с ним короче:

Использовать @ нужно как можно реже и очень осторожно, потому что часто заметки и предупреждения дают понять, что логика кода работает неправильно. Например, у меня бывало что лезу поправить казалось бы безобидный NOTICE, но при анализе выясняется что ошибка появилась из-за неправильной логики кода, которая изменилась в процессе расширения кода.

Новые возможности в PHP 5.5 (ссылка на офф.сайт):

[1,3,4][2] , «foobar» <2>— разыменования только-созданных массивов и строк

empty() — можно применять к результатам функций и выражений

Раньше empty() мог принимать только переменные, теперь можно передавать сами выражения без необходимости сохранять результат в отдельную переменную:

В foreach стало возможным использовать list():

finally — в конструкции try/catch

Выбрасывать и ловить исключения можно с PHP 5. Такой подход позволяет контролировать выполнение кода, если есть подозрение, что в нем что-то может пойти не так.

А с версии 5.5. в эту конструкцию добавили третий блок finally . Блок finally выполняется всегда после завершается конструкции try/catch. Он выполняется даже когда код try вызвал фатальную ошибку:

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

Пару домонстрационных примеров:

Меньше кода

Допустим, нам нужно выполнить функцию close() в любому случае, было выброшено исключение или нет:

Больше возможностей

Допустим мы открыли соединение с БД до выполнения кода и есть вероятность что код вызовет ошибку и открытое соединение не закроется, а нам нужно его закрыть в любом случае. finally как раз кстати:

Подробнее про finally читайте статью на хабре.

Class::class — для получение имени класса в пространствах

Появилось ключевое слово class для классов, которое выводит название класса. В обычном режиме нам это не нужно, а вот при работе с пространствами (namespace) — это удобно:

yield — создание генераторов

Если говорить простым языком: yield похожа на return, она также возвращает значение, но она не обрывает работу функции, а приостанавливает её до тех пор пока не будет запрошено следующее значение. Благодаря этому создавать генераторы стало удобнее.

Как это работает на самом деле?

yield возвращает специальный объект — Generator. Когда функция generator() вызывается в цикле, например foreach, PHP выполнит код функции до первой встречи слова yield , на котором PHP прервет работу функции, запомнит позицию и выбросит значение (объект Generator). Затем, foreach обработает значение и вызовет метод next() у полученного объекта Generator. PHP снова выполнит код функции generator() , только начнет его не с начала, а с прошлой позиции, и опять, до слова yield, которое опять выбросит объект Generator. Работа цикла прервется тогда, когда функция generator() дойдет до конца (не вернет yield), или если она будет прервана с помощью return; .

Пример генератора который возвращает пару: ключ/значение:

Кратко о генераторах

— Не добавляют нового функционала в язык
— Быстрее
— Возобновление работы генератора происходит с последнего «выброса» yield
— В генератор можно отправлять значения и исключения (через метод throw())
— Генераторы однонаправлены, т.е. нельзя вернуться назад
— Меньше кода в большинстве случаев, более простые для понимания конструкции

Чтобы лучше понять генераторы прочитайте эту статью на Хабре.

API для хэширования паролей

Теперь PHP из коробки предлагает правильный способ хэшировать пароли. Новый API хэширования паролей предоставляет четыре функции:

password_hash() — используется для хэширования пароля. В WP для этого есть своя функция wp_hash_password().

password_verify() — используется для проверки пароля на соответствие хэшу. В WP для этого есть своя функция wp_check_password().

password_needs_rehash() — используется для проверки необходимости создать новый хэш.

  • password_get_info() — возвращает имя алгоритма хеширования и различные параметры, используемые при хэшировании.
  • Новые возможности PHP 5.6. Ссылка на офф.сайт.

    const PLUS = 1 + 2; — скалярные выражения в константах/свойствах/аргументах функции

    Теперь стало возможным указывать в значения констант примитивные PHP выражения (выражения из скаляров).

    Точнее, новинка касается не только констант, а всего где раньше PHP ожидал статическое значение. Теперь вместо статики можно указать выражение из чисел/строк/констант. Если точнее, то PHP выражение можно указывать: в константах/свойствах класса и в значении аргумента функции по умолчанию.

    const ARR = [‘a’, ‘b’]; — константа может хранить массив

    Стало возможным держать в константе массивы:

    func( . $args ) или func( . [2, 3] ) — неизвестное число аргументов функции или распаковка массива с помощью ‘. ‘ (splat оператор)


    Когда мы не знали заранее, сколько параметров может получить функция, нам приходилось внутри функции обрабатывать переданные параметры с помощью специальных функций: func_num_args(), func_get_arg(), func_get_args().

    Теперь они не нужны и мы можем получить все параметры в одной переменной, для этого перед этой переменной нужно указать оператор . :

    Оператор . еще называют «Splat Оператор», например в языке Ruby

    Быстрая распаковка передаваемых параметров функции

    Теперь с помощью splat оператора . , можно указать параметры функции сразу из значений массива:

    Замена медленной функции call_user_func_array()

    Теперь call_user_func_array( $callback, $param_arr ) , которая обычно не самая быстрая, можно заменить так:

    ** — оператор возведения в степень

    До php 5.6, чтобы возвести число в степень нужно было использовать функцию pow(2,2); , а теперь есть оператор ** :

    use function и use const — импорт функций и констант в пространство

    Теперь стало возможным при помощью ключевого слова use подключать функции или константы другого пространства в наше:

    Остальные новинки PHP 5.6 не связанные с синтаксисом, смотрите в статье на Хабре.

    Куда делся PHP 6?

    Умер не родившись. В ядро PHP 6 планировали внедрить полную поддержку юникода, но затея оказалась слишком амбициозной, а объем работ слишком велик. К тому моменту, когда это стало понятно, о PHP 6 уже было написано не мало статей. Чтобы не было путаницы, из-за того что новая версия стала преследовать совсем другие цели (производительность) и сильно отличалась по концепции от PHP 6, было решено пропустить PHP 6. Еще одной причиной стало наличие весомого количества недоделанного кода в репозитории PHP, который решили не трогать, чтобы тот в ответ тоже никого не трогал.

    3 декабря 2015 года было объявлено о выходе PHP 7. Новая версия основывается на экспериментальной ветке PHP, которая изначально называлась phpng (PHPNextGeneration — следующее поколение), и разрабатывалась с упором на увеличение производительности и уменьшение потребления памяти.

    Самой важной новинкой стало изменение ядра интерпретатора: теперь он называется PHPNG (Next Generation). Благодаря PHPNG удалось увеличить скорость обработки скриптов почти в двое по сравнению с PHP 5.x. Так же появился более эффективный менеджер памяти.

    Прирост в скорости на практике хорошо виден на этой картинке. А для WordPress прирост в скорости выглядит так:

    Синтаксические новинки PHP 7:

    $a ?? » — одновременная проверка isset и получение значения

    Новый оператор слияния с NULL (NULL coalescing operator) ?? — это сокращение проверки isset и получения значения, если проверка пройдена.

    Такая проверка часто была нужна в тернарном операторе ?: :

    Так же, проверять можно по цепочке:

    $a $b — одновременное выполнение трех сравнений: больше, равно или меньше.

    Новый оператор сравнения — «spaceship operator» (космический корабль). Сравнивает 2 переменные и возвращает результат сравнения в виде числа:

    • -1 — если в сравнении подходит первый символ оператора
    • 0 — подходит второй символ =
    • 1 — подходит третий символ >

    Удобен для использования в колбэках для usort().

    define(‘FOO’, [1,2]); — передача массива константе через define()

    Константы могут содержать массивы еще с PHP 5.6. Но тогда их можно было передавать только через ключевое слово const. Теперь их можно указывать еще и через define().

    use name\space\; — группировка импорта при помощи use

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

    int, float, bool — новые типы для аргументов функции/метода

    Авто-проверка типа передаваемых данных в функции/методы, известная как «контроль типа» (typehint), продолжает развиваться и теперь понимает скаляры: int , float , bool , string . Раньше понимались только типы: array , имя класса или callable (с версии 5.4).

    Режим строгой типизации

    Если указан тип int и передать строку ‘123’ то проверка все равно будет пройдена, и php превратить строку в число.

    Но что, если нужно получать именно число 123? Для этого можно включить режим строгой типизации, поместив в самое начало файла такую строку:

    Это объявление должно быть первой строкой в файле, до выполнения какого-либо кода. Оно затрагивает только код файла и только вызовы и возвращаемые значения в этом файле.

    Заметка: если строгая типизация указана в файле X, но не указана в файле Y и в файле Y вызывается функция из файла X. То вызов такой функции не будет подвержен строгой типизации!

    int, float, bool, array — указание возвращаемых типов для функции/метода

    Указывать принимаемый тип, можно еще с версии PHP 5.3. А вот указать какой тип функция/метод должна вернуть доступно только с версии PHP 7. Тут понимаются все типы: string , int , float , bool , array , callable , self (в методах), parent (в методах) , Closure , имя класса , имя интерфейса .

    Возвращаемые типы при наследовании методов класса

    При наследовании в классах, дочерние методы должны иметь такие же возвращаемые типы как и в родительском классе/интерфейсе:

    Навороченный пример того, как можно писать в PHP 7

    Тут сразу несколько новинок:

    1. принимаемый и возвращаемый тип;
    2. объединение и распаковка параметров с помощью . ;
    3. пример создания анонимной функции с указанием возвращаемого типа данных.

    foo()(), $a::$b::$c, $$foo->bar — единый синтаксис переменных: СЛЕВА НАПРАВО

    Очень важная новинка! Теперь обращения к сложносочиненным переменным разбираются последовательно СЛЕВА НАПРАВО.

    Примеры новых возможностей:

    Примеры разницы старого и нового распознавания:

    Старый код написанный с использованием <> для обработки переменных возможно не будет работать в новой версии PHP7.

    foreach — изменена логика работы

    Теперь foreach не переключает автоматически внутренний указатель перебираемого массива, т.е. next() не работает автоматически.

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

    Переключение указателей и влияние на работу цикла в PHP 7:

    Анонимные классы позволяют делать тоже самое что и обычные классы: передавать данные в конструктор, наследовать другие классы, использовать трейты и т.п.

    Расширение классов работает как и ожидается:

    Подробнее про анонимные классы читайте в документации и на wiki.php.net.

    yield . return 99; — возврат (return) выражений в генераторах

    Функции-генераторы появились в PHP 5.5. Но там можно было использовать return, только чтобы прервать работу генератора. Теперь return может возвращать выражение (значение/массив/другой генератор), а не только NULL. Но сделать это можно только в конце работы генератора.

    Получить возвращенное значение можно методом getReturn() , но только по завершении работы генератора.

    Возможность явно вернуть последнее значение упрощает работу с генераторами:
    теперь не нужно проверять является ли значение последним, а просто вызываем getReturn().

    yield from gen() — делегирование генераторов

    Позволяет разбить сложный генератор на несколько простых.

    Для этого используется новый синтаксис: yield from , где может быть значением (скаляром), массивом или другим генератором.

    будет работать до тех пор, пока возвращает данные, затем выполнение продолжится в генераторе откуда был вызван. Смотрите пример:

    Пример с массивом:

    Пример с return из дочернего генератора:

    Еще новинки PHP 7.0

    Синтаксис конструкторов в стиле PHP 4 (имя метода конструктора совпадает с именем класса) теперь считается устаревшим.

    Статичные вызовы :: нестатичных методов теперь считаются устаревшими.

    list() — изменение поведения. В PHP 5, list() устанавливал значения начиная с правого крайнего значения указанного массива, в PHP 7 параметры устанавливаются начиная с левого крайнего значения массива. Так же в PHP 5 list() умела разбивать строки на символы, в PHP 7 не работает со строками вообще.

    Поддержка юникод управляющих (escape-) последовательностей. Т.е. в строках «» и heredoc можно использовать конструкцию \uXXXX для создания юникод символа. Вот так:

    Класс IntlChar. Cодержит методы и константы для работы с юникодом.

    Функция intdiv() — делит 2 числа и возвращает только целую часть от деления:

    session_start() умеет получать параметры (стандартные настройки сессий из php.ini):

    Функция preg_replace_callback_array() — альтернатива preg_replace_callback(). Позволяет передать в качестве обратной функции — массив [‘/regex’/ => callback, . ] :

  • Можно использовать глобальные ключевые слова в названиях методов. Т.е. раньше нельзя было назвать метод словами: with/new/for/foreach/. — это приводило к ошибке. Теперь можно:
  • Подробнее о новинках PHP 7 читайте в этой статье и вторая часть.

    void — возвращаемый тип

    Теперь функции и методы, которые не должны ничего возвращать, можно помечать возвращаемым типом void . Оператор return при этом должен отсутствовать или должен быть пустым — return; . Вызов return null; вызовет ошибку.

    iterable — новый псевдо-тип

    Введен новый тип iterable для передаваемых/возвращаемых значений. Может использоваться при передаче массивов или объектов, которые соответствуют интерфейсу Traversable.

    null — тип передаваемых/возвращаемых значений

    В PHP 7.0 стало возможным указать тип возвращаемых/передаваемых значений, но типизация не допускала использование null в качестве значения параметра.

    В PHP 7.1 для разрешения null-значений перед типом параметра указывается «?»:

    <-1>— отрицательное значение смещения в строках

    Добавлена возможность использовать отрицательное значение для смещения в строках

    [‘key’=>$a] = [‘key’=>’Значение’] — поддержка ключей и новый синтаксис list()

    Теперь, можно использовать новый синтаксис — аналог list(), в котором разрешено использовать строковые ключи:

    Область видимости констант в классах

    Конец публичным константам, теперь для констант можно указать видимость:

    Заметки по PHP 7.1

    PHP движется в сторону строгой типизации данных и при переходе на 7.1 я столкнулся с ФАТАЛЬНОЙ ошибкой. И мне это показалось очень странным. Приведу пример:

    При Warning PHP еще работает, а дальше уже нет! А еще в 7.0 код просто работал, даже без предупреждений и нотисов. Похоже на недоработку в PHP 7.1.

    К примеру, ошибка такого типа есть в популярном плагине WP Super Cache (отписал авторам, надеюсь скоро поправят).

    SLUSAR.SU

    Логово Программиста

    Изучаем PHP 7.№9. Циклы. For.

    Цикл for очень прост. Так что вам не составит труда его освоить.
    Вся его логика заключена примерно в следующих действиях:

    for(данные; условие; операция над данными) <
    код
    >

    На практике все еще проще. Давайте создадим файл for.php в котором и будем все пробовать.

    Добавить комментарий Отменить ответ

    Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.

    Мастер Йода рекомендует:  Minecraft на Unity3D — всё по этой теме для программистов
    Добавить комментарий