Переход от php 2 к php 3


PHP: break, continue и goto

break

Часто бывает удобно при возникновении некоторых условий иметь возможность досрочно завершить цикл. Такую возможность предоставляет оператор break . Он работает с такими конструкциями как: while, do while, for, foreach или switch .

Оператор break может принимать необязательный числовой аргумент, который сообщает ему, выполнение какого количества вложенных структур необходимо завершить. Значением числового аргумента по умолчанию является 1, при котором завершается выполнение текущего цикла. Если в цикле используется оператор switch , то break/break 1 выходит только из конструкции switch .

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

continue

Для остановки обработки текущего блока кода в теле цикла и перехода к следующей итерации можно использовать оператор continue . От оператора break он отличается тем, что не прекращает работу цикла, а просто выполняет переход к следующей итерации.

Оператор continue также как и break может принимать необязательный числовой аргумент, который указывает на скольких уровнях вложенных циклов будет пропущена оставшаяся часть итерации. Значением числового аргумента по умолчанию является 1, при которой пропускается только оставшаяся часть текущего цикла.

Обратите внимание: в процессе работы цикла было пропущено нулевое значение переменной $counter , но цикл продолжил работу со следующего значения.

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

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

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

Переход от php 2 к php 3

На втором месте по частоте использования, после конструкций условий (условных операторов), находятся .

Циклы позволяют повторять определенное (и даже неопределенное — когда работа цикла зависит от условия) колличество раз различные операторы. Данные операторы называются . Проход цикла называется .

PHP поддерживает три вида циклов:

  • Цикл с предусловием (while);
  • Цикл с постусловием (do-while);
  • Цикл со счетчиком (for);
  • Специальный цикл перебора массивов (foreach).

При использовании циклов есть возможность использования операторов break и continue. Первый из них прерывает работу всего цикла, а второй — только текущей итерации.

Рассмотрим циклы PHP:

Цикл с предусловием while

Цикл с предусловием while работает по следующим принципам:

  1. Вычисляется значение логического выражения.
  2. Если значение истинно, выполняется тело цикла, в противном случае — переходим на следующий за циклом оператор.

Синтаксис цикла с предусловием:

while (логическое_выражение)
инструкция;

В данном случае телом цикла является . Обычно тело цикла состоит из большого числа операторов. Приведем пример цикла с предусловием while:

php
$ x = 0 ;
while ($ x ++ 10 ) echo $ x ;
// Выводит 12345678910
?>

Обратите внимание на последовательность выполнения операций условия $x++ php
$ x = 0 ;
while ($ x 10 )
<
$ x ++; // Увеличение счетчика
echo $ x ;
>
// Выводит 12345678910
?>

Если мы увеличим счетчик после выполнения оператора echo, мы получим строку 0123456789. В любом случае, мы имеем 10 итераций. Итерация — это выполение операторов внутри тела цикла.

Подобно конструкции условного оператора if, можно группировать операторы внутри тела цикла while, используя следующий альтернативный синтаксис:

while ( логическое_выражение ):
инструкция;
.
endwhile;

= 1 ;
while ( $x 10 ):
echo $x ;
$x ++;
endwhile;
?>

Цикл с постусловием do while

В отличие от цикла while, этот цикл проверяет значение выражения не , а каждого прохода (итерации). Таким образом, тело цикла выполняется хотя бы один раз. Синтаксис цикла с постусловием такой:

do
<
тело_цикла;
>
while (логическое_выражение);

После очередной итерации проверяется, истинно ли логическое_выражение, и, если это так, управление передается вновь на начало цикла, в противном случае цикл обрывается.
Альтернативного синтаксиса для do-while разработчики PHP не предусмотрели (видимо, из-за того, что, в отличие от прикладного программирования, этот цикл довольно редко используется при программировании web-приложений).

Пример скрипта, показывающего работу цикла с постусловием do-while:

Рассмотренный сценарий выводит: 12345678910

Цикл со счетчиком for

Цикл со счетчиком используется для выполнения тела цикла определенное число раз. С помощью цикла for можно (и нужно) создавать конструкции, которые будут выполнять действия совсем не такие тривиальные, как простая переборка значения счетчика.

Синтаксис цикла for такой:

for (инициализирующие_команды; условие_цикла; команды_после_итерации)

Цикл for начинает свою работу с выполнения инициализирующих_команд. Данные команды выполняются только один раз. После этого проверяется условие_цикла, если оно истинно (true), то выполняется тело_цикла. После того, как будет выполнен последний оператор тела, выполняются команды_после_итерации. Затем снова проверяется условие_цикла. Если оно истинно (true), выполняется тело_цикла и команды_после_итерации, и.т.д.

php
for ($ x = 0 ; $ x 10 ; $ x ++) echo $ x ;
?>

Данный сценарий выводит: 0123456789

Есть вариант вывода строки 12345678910 :

php
for ($ x = 0 ; $ x ++ 10 ;) echo $ x ;
// Выводит 12345678910
?>

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

Если необходимо указать несколько команд, их можно разделить запятыми, пример:

php
for ($ x = 0 , $ y = 0 ; $ x 10 ; $ x ++, $ y ++) echo $ x ;
// Выводит 0123456789
?>

Приведем еще один, более практичный пример использования нескольких команд в цикле for:

php
for($ i = 0 ,$ j = 0 ,$ k = «Точки» ; $ i 10 ; $ j ++,$ i +=$ j ) < $ k =$ k . "." ; echo $ k ; >
// Выводит Точки.Точки..Точки. Точки.
?>

Рассмотренный пример (да и вообще любой цикл for) можно реализовать и через while, только это будет выглядеть не так изящно и лаконично.

Для цикла for имеется и альтернативный синтаксис:

for(инициализирующие_команды; условие_цикла; команды_после_итерации):
операторы;
endfor;

Цикл перебора массивов foreach

В PHP4 появился еще один специальный тип цикла — foreach. Данный цикл предназначен специально для .

Синтаксис цикла foreach выглядит следующим образом:

foreach (массив as $ключ=>$значение)
команды;

Здесь команды циклически выполняются для каждого элемента массива, при этом очередная пара ключ=>значение оказывается в переменных $ключ и $значение. Приведем пример работы цикла foreach:

php
$ names [ «Иванов» ] = «Андрей» ;
$ names [ «Петров» ] = «Борис» ;
$ names [ «Волков» ] = «Сергей» ;
$ names [ «Макаров» ] = «Федор» ;
foreach ($ names as $ key => $ value ) <
echo «$value $key
» ;
>
?>

Рассмотренный сценарий выводит:

Андрей Иванов
Борис Петров
Сергей Волков
Федор Макаров

У цикла foreach имеется и другая форма записи, которую следует применять, когда нас не интересует значение ключа очередного элемента. Выглядит она так:

foreach (массив as $значение)
команды;

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

php
$ names [] = «Андрей» ;
$ names [] = «Борис» ;
$ names [] = «Сергей» ;
$ names [] = «Федор» ;
foreach ($ names as $ value ) <
echo «$value
» ;
>
?>

Внимание: Цикл foreach оперирует не исходным массивом, а его копией. Это означает, что любые изменения, которые вносятся в массив, не могут быть «видны» из тела цикла. Что позволяет, например, в качестве массива использовать не только переменную, но и результат работы какой-нибудь функции, возвращающей массив (в этом случае функция будет вызвана всего один раз — до начала цикла, а затем работа будет производиться с копией возвращенного значения).

Конструкция break

Очень часто для того, чтобы упростить логику какого-нибудь сложного цикла, удобно иметь возможность его прервать в ходе очередной итерации (к примеру, при выполнении какого-нибудь особенного условия). Для этого и существует конструкция break, которая осуществляет немедленный выход из цикла. Она может задаваться с одним необязательным параметром — числом, которое указывает, из какого вложенного цикла должен быть произведен выход. По умолчанию используется 1, т. е. выход из текущего цикла, но иногда применяются и другие значения. Синтаксис конструкции break:

break; // По умолчанию
break(номер_цикла); // Для вложенных циклов (указывается номер прерываемого цикла)

php
$ x = 0 ;
while ($ x ++ 10 ) <
if ($ x == 3 ) break;
echo «Итерация $x
» ;
>
// Когда $x равен 3, цикл прерывается
?>

Рассмотренный сценарий выводит:

Если нам нужно прервать работу определенного (вложенного) цикла, то нужно передать конструкции break параметр — номер_цикла, например, break(1). Нумерация циклов выглядит следующим образом:

for (. ) // Третий цикл
<
for (. ) // Второй цикл
<
for (. ) // Первый цикл
<
>
>
>

Конструкция continue

Конструкция continue так же, как и break, работает только «в паре» с циклическими конструкциями. Она немедленно завершает текущую итерацию цикла и переходит к новой (конечно, если выполняется условие цикла для цикла с предусловием). Точно так же, как и для break, для continue можно указать уровень вложенности цикла, который будет продолжен по возврату управления.
В основном continue позволяет вам сэкономить количество фигурных скобок в коде и увеличить его удобочитаемость. Это чаще всего бывает нужно в циклах-фильтрах, когда требуется перебрать некоторое количество объектов и выбрать из них только те, которые удовлетворяют определенным условиям. Приведем пример использования конструкции continue:

php
$ x = 0 ;
while ($ x ++ 5 ) <
if ($ x == 3 ) continue;
echo «Итерация $x
» ;
>
// Цикл прервется только на третьей итерации
?>

Рассмотренный скрипт выводит:

Итерация 1
Итерация 2
Итерация 4
Итерация 5

Грамотное использование break и continue позволяет заметно улучшить «читабельность» кода и количество блоков else.

Ошибки при переходе при переходе с PHP 5.2.x на PHP 5.3.x (Deprecated: function. глобальные переменные, работа с сессиями)

При переходе с PHP 5.2.x на PHP 5.3.x перестают работать некоторые функции, так php изживает и развивает себя. Но для разработчика начинается головная боль, особенно если используются CMS, написанные на PHP (например MODx), которые вдруг выдают ошибки.

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

1) Итак счастливым обладателям php 5.3.x стоит заменить:

ereg() — впредь используйте preg_match()

ereg_replace() — пользуйтесь preg_replace()
eregi() — пользуйтесь preg_match() с модификатором ‘i’
eregi_replace() — пользуйтесь preg_replace() с модификатором ‘i’
split() — пользуйтесь preg_split()
spliti() — пользуйтесь preg_split() с модификатором ‘i’
set_magic_quotes_runtime() и ее синоним magic_quotes_runtime()
session_register() — пользуйтесь суперглобальный массив $_SESSION
session_unregister() — пользуйтесь суперглобальный массив $_SESSION
session_is_registered() — пользуйтесь суперглобальный массив $_SESSION
set_socket_blocking() — пользуйтесь е stream_set_blocking()
mysql_db_query() — пользуйтесь mysql_select_db() и mysql_query()
mysql_escape_string() — пользуйтесь mysql_real_escape_string()

2) Переменные Depecated в PHP 5.3.x надо заменить соответственно:

HTTP_SERVER_VARS -> _SERVER
HTTP_POST_VARS -> _POST
HTTP_ENV_VARS -> _ENV
HTTP_GET_VARS -> _GET
HTTP_COOKIE_VARS -> _COOKIES
HTTP_SESSION_VARS -> _SESSION
HTTP_POST_FILES -> _FILES

3) Теперь для разрушения сессии обязательно надо сделать unset всех переменных сессии ($_SESSION = array()):

Ошибка №1 (встретилась в MODx 0.9.6.3): Function split() is deprecated

Сначала небольшие изменения внесём в файл manager/includes/config.inc.php , чтобы нам показывались ошибки, заменим строку

Теперь в manager/includes/document.parser.class.php , заменим строку 2502

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

Если не хотим игнорировать, то решением проблемы может быть замена split на explode

almix
Разработчик Loco, автор статей по веб-разработке на Yii, CodeIgniter, MODx и прочих инструментах. Создатель Team Sense.

Переход с php 5.2 на 5.3

Видел подобную тему, но никто товарищу не ответил. А проблема такая:
Проект работает на основе «1С-Битрикс: Управление сайтом 8.6.4».
Версия PHP 5.2.
Через неделю хостер отключает поддержку 5.2, надо перевести на 5.3.
В ПУ сайтом (у хостера) переключаю в настройках с 5.2 на 5.3 и возникают ошибки:
1) перестает отображаться корзина ( вижу сообщение: DB query error. Please try later.)
2) не могу войти в ПУ сайтом (mysite.ru/bitrix/admin/index.php) — попытка авторизации заканчивается сообщением- 502 Bad Gateway nginx/1.6.3
Возможно есть еще какие-то ошибки, но пока не тестировал.
Возврат настроек в исходное (5.2) — устраняет ошибки.

Насколько я понимаю, ошибки возникают вследствие использования в модулях устаревших функций и процедур, и исправление их в соответствующих php файлах должно привести к устранению сбоев. Следовательно вопрос: в каких файлах и какие функции следует изменить? какие файлы используются при работе ПУ битрикс?

Правильный метод лечения — платное обновление Битрикса (ну вот не стоит искать все устаревшие функции в over 20.000 файлов, да и возможности в новой версии другие, хотя бы те же обновления поддерживаемых платежных систем).
Не правильный путь — поменять хостера (взять VDS и установить на него необходимое обеспечение).
А так то, кончено, можно и заменять все функции во всех файлах.

Ps. если уж решили иметь дело с Битриксом, то вы приняли правила игры — для новых требований бизнеса нужен актуальный Битрикс. ДА и не поверю я, что у бизнеса не найдется 20 т.р. раз в 4 года на обновление системы, которая зарабатывает деньги или это не бизнес, а надувание щек.

Смотрите логи php, mysql, apache2, логи ошибок для домена сначала надо поглядеть, если будут ошибки, исправлять последовательно, я бы лучше это сделал на Open Server

на нем можно переключать модули php, apache2, mysql и смотреть ошибки в интерфейсе программы,

только его надо настроить для Битрикс, поможет вот эта статья Перенос сайта Битрикс на другой хостинг

2) Панель управления: по какой-то причине перестаёт работать эмуляция включённого register_globals. Решение — включить настоящий register_globals в php.ini
1) Проблемы с корзиной (с модулем sale) связаны с тем, что в PHP 5.3 изменилась схема работы php-функции call_user_func_array в части обработки параметров, передаваемых по ссылке. Конкретно в модуле sale в объявлении всех функций, имена которых заканчиваются на 4Where , необходимо убрать & из параметров (они реально не нужны и это не влияет на функциональность).
Например
Было
function PrepareCurrency4Where($val, $key, $operation, $negative, $field, &$arField, &$arFilter )
стало
function PrepareCurrency4Where($val, $key, $operation, $negative, $field, $arField, $arFilter )

Но подлянка заключается в том, что функций, вызываемых через call_user_func_array, в Битриксе может быть сколько угодно, и найти их можно только разбором каждой конкретной ситуации через debug_backtrace.
Так что смена сервера, хостера или схемы хостинга (на VPS собственной конфигурации) может быть лучшим решением.
Удачи!

Развитие синтаксиса 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 (отписал авторам, надеюсь скоро поправят).

    Проблема перехода от PHP 5.2 к PHP 5.3

    Моя компания имеет некоторый старый PHP код, который был запущен на PHP 5.2 довольно долго, но наш веб-хостинг избавляется от PHP 5.2. Скрипт использует domxml-php4-к-php5.php запустить domxml. По какой-то причине, когда я перейти на PHP 5.3 скрипт не будет тянуть в файле XML. Он просто возвращает «Вы не выбрали файл для редактирования!». Мне просто нужно, чтобы получить эту работу на PHP 5.3 на некоторое время, пока я обновить код для PHP 5.

    Как «безболезненно» перейти с php 5.4 на php 5.6?

    Сейчас у меня сайт с версией PHP 5.4, но время то идёт, уже убрали поддержку PHP 5.2 (не удивительно) и перекинули всех на PHP 5.3 поэтому начинаю задумываться — ведь наступит день, когда и «пять точка четыре» станет недоступен. Тем более что 7 версия не за горами.

    На хостинге в панели управления очень легко перейти с PHP 5.4 на PHP 5.6 — достаточно всего лишь выбрать версию и нажать кнопку подтвердить, но ведь 5.4 это не тоже самое, что 5.6. Я пробовал «глянуть» будет ли мой сайт работать, но, естественно, меня ждал белый экран. Пришлось вернуться к PHP 5.4.
    Я понимаю что не всё так просто, но как будет правильно организовать переход с PHP 5.4 на PHP 5.6? Не буду же я включать вывод ошибок и переписывать код.
    Или по-другому никак?

    • Вопрос задан более трёх лет назад
    • 4802 просмотра

    php.net/migration56
    php.net/migration55
    Изменений, на самом деле, не так уж и много, все наши проекты спокойно мигрировали с 5.3 на 5.6 (через все промежуточные версии).

    Не буду же я включать вывод ошибок и переписывать код.

    Версия 5.2 вышла где-то в июле 2006 года, а провайдеры убирать её стали только в 2013-2014 годах. Даже когда выйдет 7 версия, её еще очень долго будут тестировать, переделывать, прежде чем провайдеры начнут устанавливать её. Этот день, о котором ты говоришь наступит скорее всего лет через 5.

    Что касается переходов по версиям, ведь не факт, что они используют один и тот же `php.ini` файл (а следовательно настройки, в частности отображения ошибок там всяких). Каждая версия лежит в отдельной папке и использует свою сборку в 99.9% случаях. Есть вещи, которые были в 5.4 и они вызывали (E_NOTICE, E_DEPRECATED), но их полностью убрали с 5.6. Отсюда и белый экран. Быть может там одна ошибка? Легче всего включить отображение ошибок `(error_reporting(-1))` и не гадать.

    Да и вообще, если работает на 5.4 зачем вообще менять и трогать что-то? Работает — ну и пусть себе дальше работает.

    Переход от php 2 к php 3

    (PHP 4, PHP 5, PHP 7)

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

    Замечание: В PHP оператор switch считается циклическим и внутри него может использоваться continue. Если continue не передано аргументов, то он ведет себя аналогично break. Если switch расположен внутри цикла, continue 2 продолжит выполнение внешнего цикла со следующей итерации.

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

    foreach ( $arr as $key => $value ) <
    if (!( $key % 2 )) < // пропуск четных чисел
    continue;
    >
    do_something_odd ( $value );
    >

    $i = 0 ;
    while ( $i ++ 5 ) <
    echo «Снаружи
    \n» ;
    while ( 1 ) <
    echo «В середине
    \n» ;
    while ( 1 ) <
    echo «Внутри
    \n» ;
    continue 3 ;
    >
    echo «Это никогда не будет выведено.
    \n» ;
    >
    echo «Это тоже.
    \n» ;
    >
    ?>

    Пропуск точки запятой после continue может привести к путанице. Пример как не надо делать.

    Ожидается, что результат будет такой:

    Но в версиях PHP ниже 5.4.0 этот скрипт выведет следующее:

    Потому что выражение continue print «$i\n»; воспринимается как единое выражение, поэтому print вызывается только тогда, когда выражение $i == 2 истинно. (Возвращаемое значение от print передается к continue как числовой аргумент.)

    Начиная с PHP 5.4.0, вышеприведенный пример вызовет ошибку E_COMPILE_ERROR .

    Изменения, касающиеся оператора continue

    Версия Описание
    7.0.0 Операторы break и continue вне цикла или управляющей структуры switch теперь обрабатываются во время компиляции, а не во время выполнения, как это было ранее, поэтому выдают ошибки уровня E_COMPILE_ERROR .
    5.4.0 continue 0; больше не допускается. В предыдущих версиях это воспринималось точно также как и continue 1;.
    5.4.0 Убрана возможность задавать переменную (например, $num = 2; continue $num;) в качестве числового аргумента.

    User Contributed Notes 18 notes

    The remark «in PHP the switch statement is considered a looping structure for the purposes of continue» near the top of this page threw me off, so I experimented a little using the following code to figure out what the exact semantics of continue inside a switch is:

    for( $i = 0 ; $i 3 ; ++ $i )
    <
    echo ‘ [‘ , $i , ‘] ‘ ;
    switch( $i )
    <
    case 0 : echo ‘zero’ ; break;
    case 1 : echo ‘one’ ; XXXX ;
    case 2 : echo ‘two’ ; break;
    >
    echo ‘ , $i , ‘> ‘ ;
    >

    ?>

    For XXXX I filled in

    — continue 1
    — continue 2
    — break 1
    — break 2

    and observed the different results. This made me come up with the following one-liner that describes the difference between break and continue:

    continue resumes execution just before the closing curly bracket ( > ), and break resumes execution just after the closing curly bracket.

    Corollary: since a switch is not (really) a looping structure, resuming execution just before a switch’s closing curly bracket has the same effect as using a break statement. In the case of (for, while, do-while) loops, resuming execution just prior their closing curly brackets means that a new iteration is started —which is of course very unlike the behavior of a break statement.

    In the one-liner above I ignored the existence of parameters to break/continue, but the one-liner is also valid when parameters are supplied.

    Переход от php 2 к php 3

    PHP 3.0 переписан полностью. В нём имеется соответствующий разборщик/parser, который намного надёжнее и быстрее, чем в 2.0. 3.0, а также значительно меньше расходует память. Однако некоторые из этих улучшений невозможны без изменения совместимости, как в синтаксисе, так и в функциональности.

    Кроме того, PHP-разработчики попытались прочистить синтаксис и семантику PHP в версии 3.0, и это также вызвало появление некоторой несовместимости. Мы считаем, что в долговременном плане это изменения к лучшему.

    В этой главе будет сделана попытка помочь вам преодолеть несовместимости, возникающие при переходе от PHP/FI 2.0 к PHP 3.0. Новые возможности здесь не упоминаются без необходимости.

    Программа конвертации, которая может автоматически конвертировать ваши старые PHP/FI 2.0-скрипты, существует. Её можно найти в поддиректории convertor дистрибутива PHP 3.0. Эта программа отлавливает только синтаксические изменения, поэтому вы в любом случае должны внимательно прочитать эту главу.

    Атомная энергетика. Ядерные реакторы АЭС. Атомный флот. Ядерное оружие

    Высшая математика

    PHP имеет уже долгую историю развития: легендарный PHP 1.0, PHP/FI, PHP 3.0 и PHP 4.0.

    1. Переход от PHP 2 к PHP 3.

    PHP/FI 2.0 больше не поддерживается. См. соответствующий раздел учебника о переходе от PHP/FI 2.0.

    Если вы всё ещё работаете в PHP 2, мы настоятельно рекомендуем перейти сразу к PHP 4.

    Илон Маск рекомендует:  Изменение формы курсора на произвольный
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL
    Учебник РНР
    Назад Вперёд