Ниже приведены основные изменения, привнесенные
PHP 7.1
. Для получения полного списка утвержденных и обсуждаемых на текущий момент изменений проверьте официальный PHP RFC.- Перехват нескольких типов исключений за раз
- Поддержка
Curl HTTP/2 server push
- Области видимости для констант классов
- Возвращаемый тип
void
- Единое поведение строковых функций
- Поддержка строковых параметров в функции
list()
и новый синтаксис c[]
- Выброс предупреждения при невалидных строках в арифметике
- Объявление устаревшим
mcrypt()
и его последующее удаление
Перехват нескольких типов исключений за раз
В некоторых случаях мы обрабатываем различные исключения одинаково и нет возможности унаследовать их от общего предка, что приводит к дублированию кода. Например:
try {
// to do something
} catch (MyException $e) {
// Handle this exception
} catch (AnotherException $e) {
// Handle this in the same way as MyException
} catch (Exception $e) {
// Handle this in a different way
}
В PHP 7.1, оба исключения, обрабатываемые в примере одинаково, можно поймать одновременно:
try {
// to do something
} catch (MyException | AnotherException $e) {
// Handle these exceptions
} catch (Exception $e) {
// Handle this in a different way
}
Обратите внимание на синтаксис — это не обычный
||
оператор, который мы ассоциируем с or
, это одинарный символ |
.Поддержка Curl HTTP/2 server push
Во-первых, что же такое
server push
? Лучшим способом, возможно, будет понять это через пример.Как вы знаете, когда пользователь делает запрос к domain.com (не берем в расчет DNS и т.д.), веб-сервер отдает ответ с кучей разметки, которую браузер затем интерпретирует и отображает. В рамках этой интерпретации, исполняемой браузером, ему необходимо понять, какие дополнительные ресурсы он должен запросить, чтобы полностью отобразить страницу. Это включает в себя CSS, файлы JavaScript и изображения.
Server push
стремится ускорить время загрузки и позволяет пропустить этот шаг, сразу направляя ресурсы клиенту напрямую.Эта функциональность доступна в
libcurl
с версии 7.44.0
, но пока нестабильна и не ушла в релиз (Подробнее: тут и тут). Для более подробной информации читайте официальный PHP RFC: ext/curl HTTP/2 Server Push Support.Области видимости для констант классов
Константы классов в настоящее время нельзя сделать
private
или protected
. Они всегда являются public
.Например:
class Panda
{
private $pandaId;
public $name;
// This is public, and there's
// nothing you can do about it.
const MAGIC_POWER = 20;
}
PHP 7.1 вводит модификаторы видимости для констант:
class Panda
{
// Constants default to public
const MAGIC_POWER = 20;
private const LIMIT_BREAK = 30;
protected const EXPERIENCE_POINTS = 0;
public const HEALTH_POINTS = 100;
}
Это ставит константы в один ряд с другими членами класса.
Возвращаемый тип void
Возвращаемые типы были добавлены в PHP 7.0. Напомню, что это позволяет разработчику явно объявить тип возвращаемого функцией значения.
Например:
function foo(): array {
return [];
}
Начиная с PHP 7.1, можно указать, что функция имеет тип
void
, т.е. она выполняет действие, но ничего не возвращает.function i_dont_return_anything(): void {
// Perform some action
// This is perfectly valid.
return;
// This would throw a Fatal error (A
// void function must not return a
// value).
// return true;
}
Конечно, вы можете возразить, что функция всегда должна что-то возвращать, хотя бы
boolean
, указывающий успешное выполнение, но это уже тема для другой статьи.Единое поведение строковых функций
Взгляните на встроеную в PHP функцию strrpos().
strrpos($needle, $haystack, $offset = 0);
Последний параметр поддерживает отрицательное смещение, которое вместо того, чтобы найти последнее вхождение
$needle
в $haystack
начиная от начала строки, находит последнее вхождение начиная с N позиций назад от конца $haystack.Многие связанные со строками функции PHP имеют этот необязательный параметр
$offset
, а некоторые — нет. Один из ярких примеров — strpos()
. Здесь, чтобы добиться отрицательного смещения, функцию необходимо объединить с substr()
, что снижает читабельность и производительность кода.Следующее обновление PHP устраняет данный пробел в языке, добавляя параметр
$offset
и его поведение с отрицательным значением во множество стандартных функций.Поддержка строковых параметров в функции list()
и новый синтаксис c []
В настоящее время в PHP есть возможность преобразовать массив в список переменных с помощью функции
list()
:Пример:
$myArray = ['monkey', 'tree', 'banana'];
list($monkey, $tree, $banana) = $myArray;
// $monkey is now equal to 'monkey'.
_list()
работает только с числовыми индексами массивов, начинающимися с нуля, например как в коде выше. Она не работает с ассоциативными массивами, такими как:$myNamedArray = [
'name' => 'Amo',
'age' => 32,
'location' => 'London'
];
PHP 7.1 решает это:
list('name' => $name, 'age' => $age, 'location' => $location) = $myNamedArray;
Другим значительным улучшением PHP 7.1. является введение квадратных скобок
[]
для обозначения массива переменных. Это обеспечивает альтернативу list()
для разбиения массива на переменные.[$a, $b, $c] = [1, 2, 3];
Обратите внимание, что используется тот же синтаксис, как и при создании массива:
$numbers = [1, 2, 3];
Полная информация по этому изменению доступна на странице RFC.
Выброс предупреждения при невалидных строках в арифметике
При выполнении арифметики в PHP, язык будет корректно (или нет, в зависимости от того, как вы на это смотрите) смешивает целочисленные значения со строковыми на основе содержащихся в них чисел.
Возьмем следующие примеры:
//Results in 10
$total = 5 + 5;
// Results in 10
$total = '5' + '5';
// Results in 10
$total = 5+ '5';
// Results in 10
$total = '3 bananas yesterday' + '7 bananas today';
// Results in 5
$total = 5 + 'I love bananas';
Четвертый пример содержит в себе числовые значения, а т.к. все остальное вырезается, то и сумма оставшихся символов, используемых для расчета, даст в общей сложности 10. Но все равно было бы приятно увидеть предупреждение о работе с непредназначенными для подобного поведения строками.
Последний пример также демонстрирует подобное поведение в работе. В строке
I love bananas
нет числовых значений и вся строка трактуется как 0.В PHP 7.1, примеры четыре и пять вернут:
Notice: A non well formed numeric string encountered in file.php on line x
Это вносит некоторые проблемы с обратной совместимостью в тех случаях, когда ожидается молчаливая обработка подобных строк. Можно заранее преобразовать заранее строки в целое число через
(int) "string"
, но лично я думаю, если вы выполняете арифметические операции на подобных строках, то стоит задуматься о качестве этого кода.Объявление устаревшим mcrypt()
и его последующее удаление
Библиотека
mcrypt
была заброшена в 2007м году и содержит многочисленные ошибки и несмердженные патчи. Таким образом, вопрос ее включения в PHP давно уже созрел для рассмотрения.В PHP 7.1 все
mcrypt_*
функции будут выдавать уведомление E_DEPRECATED
. В PHP 7.1+1, они будут полностью удалены.Помните, если вы используете
mcrypt
в вашем PHP коде, вы делаете это неправильно.На этом пока все, но если вы столкнетесь с какими-либо другими
core
-изменениями, которые я не упомянул, пожалуйста, дайте знать в комментариях ниже. Спасибо за прочтение.Комментарии (62)
alexkunin
01.06.2016 16:51+3Обратите внимание на синтаксис — это не обычный || оператор, который мы ассоциируем с or, это одинарный символ |.
Это отлично пересекается предложением добавить Union Types, т.е. хинт может указывать на несколько типов. В IDE, кстати, такое давно можно указывать в аннотациях (как минимум в Шторме).bolk
02.06.2016 08:46+1И «|» с «or» у меня он не ассоциируется, ассоциируется с бинарным «или», который тоже есть в PHP.
denis-n-ko
01.06.2016 20:10+3Спасибо за обзор!
Еще nullable types (https://wiki.php.net/rfc/nullable_types) добавили, которого многие ждалиFesor
01.06.2016 23:40+2а как же https://wiki.php.net/rfc/typed-properties? хотя его еще не в мерджили конечно, но это то чего я лично ждал уже пару лет.
TheDoctor
01.06.2016 20:10+4Сложилось впечатление, что началось движение в сторону более строгой типизации.
«Возвращаемый тип void»
«Выброс предупреждения при невалидных строках в арифметике»
Возможно, это поможет избежать некоторые неоднозначности связанные с автоматическим преобразованием типов.impwx
02.06.2016 11:09+1PHP — идеальный пример социокультурной инверсии в программировании. Сначала придумали одно, а потом началась бесконечная гонка за модными тенденциями из всех остальных языков программирования:
- Изначально — структурный язык, со второй попытки добавили ООП, потом лямбда-функции, где необходимо явно указывать замыкания
- Изначально — динамическая нестрогая типизация, потом четыре раза робко добавляли неполноценные ограничения, и это не считая изменений в 7.1
- Изначально — язык, встраемый в шаблон. Потом сделали опциональным закрывающий тег, а теперь и открывающий предлагают убрать.
- Опции register_globals и magic_quotes_gpc — сначала использовались во всех туториалах и самоучителях, потом объявлены опасными и удалены
Направление движения, безусловно, верное. Но с таким багажом неудачных дизайн-решений и легаси светлого будущего можно ждать бесконечно.lexxpavlov
02.06.2016 11:47+4>Но с таким багажом неудачных дизайн-решений и легаси светлого будущего можно ждать бесконечно.
Это были не неудачные решения, это был маленький язык, который и был нужен сообществу. Если бы в 90х php изначально был бы как php7 сейчас, то вряд ли кто-то он был бы нужен — его бы никто не понял. Но теперь язык развился, сообщество развилось. Когда-то register_globals и magic_quotes_gpc были нужны, а сейчас — язык стал взрослее. Это нормально.Fesor
02.06.2016 19:59+2Когда-то register_globals и magic_quotes_gpc были нужны
это как раз таки неудачное решение. Надеялись что будет хорошо но по итогу вышло плохо, хотя часть проблем это решало несомненно.
Athari
01.06.2016 20:20На lambda functions a.k.a. arrow functions, я так понимаю, забили?
Печалька.
Fesor
01.06.2016 23:38там большой холивар на пустом месте родился… так что решили для 7.1 не делать. Может в 7.2...
Есть реализация одного из предложений в yay (препроцессор для PHP) но мне не нравится...
LionAlex
01.06.2016 23:37+3// Results in 10 $total = 'I ate 3 bananas yesterday' + 'and I ate 7 bananas today';
Это неправда. Тут будет предсказуемый 0.
А вот
$total = '3 bananas yesterday' + '7 bananas today';
вернет 10.impwx
02.06.2016 16:07+2$total = '3 bananas yesterday' + '7 bananas today';
<sarcasm>
Ожидаемый результат — строка"10 bananas tomorrow"
!
</sarcasm>
POPSuL
02.06.2016 00:54+1[$a, $b, $c] = [1, 2, 3];
Господи! Я десять лет этого ждал!FlameStorm
08.06.2016 02:55Заранее прошу не кидаться помидорами, — но стоит ли таких оваций этот кусочек синтаксического сахара
относительноlist($a, $b, $c) = array(1, 2, 3)
ещё седого PHP 4,
или относительноlist($a, $b, $c) = [1, 2, 3]
PHP 5.4+?
Я бы так возликовал, если б в PHP реализовали вроде такой штуки:
public function foobar($a, $b) { __int64 $result; __asm { MOV EAX, $a ADD EAX, $b MOV $result, EAX } $result = parent::after_foobar($result); $log->write("foobar called with result $result"); return $result; }
Fesor
08.06.2016 03:32+2Я бы так возликовал, если б в PHP реализовали вроде такой штуки:
Ассемблерные вставки в динамическом языке программирования?) Нет уж спасибо.FlameStorm
08.06.2016 12:42+1Ну а почему нет? Раз уж такая пьянка пошла, что
void
появился, да и в статье доходчиво описывается, как замечательно эволюционирует PHP. И то, что это интерпретируемый язык (ну почти, скорее псевдо-некомпилируемый), ещё далеко не исключает ассемблерные вставки.
Никто не заставляет использовать эту возможность, конечно.
И даже не говорит, что куски асма отправлять прямо в проц как есть, реализовать решительно все команды и дать возможность писать байткодом, — нет. Речь об контролируемых PHP и компилируемых из псевдоасма в опкоды/асм вставках.
Помнится, даже реально чисто интерпретируемый Qbasic в 199х году поддерживал асмовые вставки, никакой фантастики в такой смеси. Это имело место быть потому, что многого «продвинутого» интерпретатор сам не умел, не мог предоставить любопытствующему программеру — взять CPUID, перейти в режим VESA аж 800х600 и 256 цветов, читать порты и т.д.
Так почему не дать самому PHP возможности для разработчика писать непосредственно в рамках языка эффективно по производительности некоторые алгоритмы, например, на SSE/SSE2, с использованием команд типа PUNPCKHQDQ, PMULUDQ и т.д.? Без необходимости привлечения Cи для написания кастомного php-экстеншна, который потом до кучи придётся поддерживать?Fedot
08.06.2016 13:14+1А разве ассемблерные вставки поддерживать легче чем расширение на C?
FlameStorm
08.06.2016 14:03Зачем их потребуется поддерживать и как-то изменять в коде, скажем, некой PHP-функции, если начиная с PHP X.X и выше всё это однозначным образом поддерживается из коробки? Один раз написал и оставь в покое.
В варианте с Си, кроме того, что это другой язык а также требуются дополнительные стыковочные компетенции написания расширений, нужно не только тот же кусок асма написать (не скрою, что на Си это делать роднее и приятнее), но и попадаешь в зависимость от этой самой «стыковки». Написал расширение для 7.0, работает. Но возьми сменись в 7.3 несовместимо что-то в работе расширений — лишний головняк, вообще с асмом и твоим алгоритмом не связанный.Fesor
08.06.2016 15:44+1кроме того, что это другой язык
А ассемблер не другой язык?
вообще с асмом и твоим алгоритмом не связанный.
сменил процессор с x86-64 на arm и появился свой головняк.FlameStorm
08.06.2016 21:08В случае сильно разных процессоров, естественно, нужен разный код.
Однако сервер с нужным железом из облака (или collocation) можно просто выбрать такой, какой тебе нужен. Как правило (уже много лет как, сейчас и в обозримом будущем) это окажется тот или иной Intel Xeon. Впрочем, можно AMD-шный взять — по части устоявшихся технологий со стажем они предоставляют единообразный набор команд. Да, x86-64 для очень многих целей достаточно.
Ассемблер конечно другой язык. Но в одном случае языков нужно два, а в другом три, плюс элементы космической стыковки.Fesor
08.06.2016 21:26+1Вообще-то нынче все в облаке и вы не знаете на каком железе крутится ваше ПО. Все за несколькими слоями абстракций. И это хорошо.
Повторюсь. Писать ассемблерные вставки в 2016-ом году нужно чувакам из области алготрейдинга, где счет идет на милисекунды. Но там как бы не используют языки со сборщиками мусора, если вы меня поняли.
В целом же intel для этих ребят уже предоставляет возможность мувнуть алгоритмы на уровень железа за счет использования FPGA что намного круче ассемблерных вставок.
FlameStorm
08.06.2016 21:57В облаке можно быть по разному, в том числе и заведомо выбирая тип и даже частоту проца. К тому же всегда можно выбрать вариант физически выделенного сервера / кластера, где ты точно знаешь свои ресурсы.
Алготрейдинг — читал про это, но не занимался, пока, такими вещами.
У всего свои плюсы и минусы, бесспорно.
Лично меня очень печалит тот факт, что за несколькими слоями абстракций, зависимостей разного степени качества, за обложенными подушками, костылями и железными конями современными разработчиками конечное железо производит полезную работу на уровне 1%, если не меньше, от того, что могло выдать в случае олдскул-гик подхода.
FPGA кстати, и вообще идея программирования в железе, действительно очень интересное направление.Fesor
08.06.2016 22:17+1Так, давайте вернемся с небес на землю. Мы говорим про PHP:
- умирающая модель выполнения.
- блокирующее API, то есть 100% утилизация CPU уже не светит.
- сборка мусора, машралинг.
Итого, мы не получаем ровным счетом никакого профита от возможностей писать на ассемблере. Намного проще нужный функционал написать на Си или еще лучше на Rust и использовать в крайнем случае в качестве расширения PHP. В Node.js есть целые готовые библиотеки для rust что бы упростить этот процесс. Для PHP в целом тоже не так все сложно.
Как результат стоимость поддержки таких решений будет на порядок ниже и у нас будет четкое разделение ответственности. Тестировать такие вещи так же намного проще.
FlameStorm
08.06.2016 22:56+1Давайте, на землю можно. Главное не проскочить под землю в ад. )
Боюсь спросить о профите синтаксического сахара[$a, $b, $c] = [1, 2, 3]
перед list, ну да не суть.
Да, модель выполнения с постоянной инициализацией-деинициализацией огромного слоя выполняемого кода в PHP на каждый запрос я тоже считаю злом, — тем, чего не должно быть в работе приложения-сервиса на сервере. И прочие минусы PHP сто раз подмечены.
Но всё же, статья о будущем, о PHP 7.1 и дальнейших планах. Тут комментарии в стиле «давайте уже закопаем и пойдём на ноду», или вроде того, имхо, не очень к месту, хотя понимаю.
И в общем случае, вы неправы насчёт отсутствия профита. Если у нас есть критическое место, которое в обычной реализации ест более 80%-90% всего времени обработки запроса PHP, а после оптимизации через продвинутые x86-64 инструкции станет занимать менее 10% времени, то резон может иметь место.
Тестирование, как я вижу, будет стоить ровно одинаково, а поддержка же не потребуется, поскольку наборы команд как были так и останутся, ровно как и предлагаемая нативная поддержка от языка.
А за дискуссию спасибо. На самом деле, я скорее на той стороне, которую вы занимаете. Но тем не менее, нововведение было бы любопытным и возможно полезным, а отсекающих причин не видно по большому счёту.
Пожалуй, я на этой ноте закруглюсь, с пожеланием разработчикам творческих побед.Fesor
09.06.2016 00:50+1Боюсь спросить о профите синтаксического сахара
Не бойтесь) Честно — это просто причесывание синтаксиса ради единообразия. Что бы синтаксис PHP больше походил на другие языки. Да, чуть потеряем самобытность, но все же это приятнее читается. И да, это мелочи.
Тут комментарии в стиле «давайте уже закопаем и пойдём на ноду», или вроде того, имхо, не очень к месту, хотя понимаю.
Я где-то к этому призывал? Если бы я так думал я бы уже давно писал на каком Go но нет, я все еще топчусь с PHP. Что до умирающей модели, есть уже кучи проектов вроде того же php-pm дабы невилировать эти издержки. Да и с асинхронщикой в PHP не все так плохо.
Если у нас есть критическое место, которое в обычной реализации ест более 80%-90% всего времени обработки запроса PHP, а после оптимизации через продвинутые x86-64 инструкции станет занимать менее 10% времени, то резон может иметь место.
Вы можете сделать расширение на Си, и там использовать ассемблерные вставки. Рядовому похапэшнику это всеравно не под силу и это значит что у нас рядом где-то есть сишник.
а отсекающих причин не видно по большому счёту.
На самом деле отсекающая причина простая. Вы сейчас можете это сделать без этой фичи? Можете. Это нужно 90% пользователей PHP? Нет. Это стоит того что бы инвестировать в это время вместо того что бы LLVM к opcache прикрутить или илнайнинг? Нет. И главное! Это дает разработчику возможность стрелять из гаубицы по своим ногам? Еще как.
Ну то есть это та же причина по которой в PHP нет из коробки потоков. Просто потому что в контексте WEB они ооочень редко нужны. И даже если брать экстенешн pthreads он сильно нас ограничивает в том как мы можем себя покалечить (в частности нет возможности шарить переменные между потоками неявно хоть оно все в одном адресном пространстве и крутится). Чем больше возможностей отстрелить ногу — тем больше их отстрелят.
А за дискуссию спасибо.
Вам так же!)
Fesor
08.06.2016 13:20+1Раз уж такая пьянка пошла, что void появился
void запрещает возвращение значения из функции. Приведу вам пример когда это может быть полезным: к примеру вы делаете критически важную часть системы — бизнес логику. В рамках этого вы делаете интерфейсы для инфраструктурных сервисов, которые будут реализовывать джуниоры. И что бы запретить им возвращение значений из методов мутирующих состояние я могу просто на уровне интерфейса это запретить, и это будет отрабатывать на этапе парсинга, так что CI-ка отловит это даже если мы не покрывали тестами этот кусок кода. Ну а джуниор потом прослушает лекцию на тему почему методы мутирующие состояния должны быть void.
ну почти, скорее псевдо-некомпилируемый
Это интерпритируемый и называется, не выдумывайте.
ещё далеко не исключает ассемблерные вставки.
Еще как исключает. В этом просто нет смысла.
Никто не заставляет использовать эту возможность, конечно.
в контексте PHP, используюегося в основном в контексте умирающей модели выполнения, который тратит немыслемое количество ресурсов на бутстраппинг приложения при каждом запросе… давать возможность делать ассемблерные вставки выглядит поменьше мере глупо.
Речь об контролируемых PHP и компилируемых из псевдоасма в опкоды/асм вставках.
А зачем? Я вот могу написать все нужные алгоритмы на C/Rust и просто использовать это добро в PHP в качестве доп модуля. В итоге я получаю и векторизацию вычислений, и все что захочу. И при этом портируемость, стоимость поддержки будет явно ниже чем в случае ассемблерных вставок, ну и т.д.
Помнится, даже реально чисто интерпретируемый Qbasic в 199х году поддерживал асмовые вставки
А сегодня у нас 2016-ый год, LLVM, умные компиляторы, оптимизирующие компиляторы… Они зачастую выдают код намного более оптимизированный нежели может написать большинство людей. В 9x еще небыло так хорошо потому еще находились извращенцы которым это было нужно. Сегодня — это пережиток прошлого.
Так почему не дать самому PHP возможности для разработчика писать непосредственно в рамках языка эффективно по производительности некоторые алгоритмы, например, на SSE/SSE2, с использованием команд типа PUNPCKHQDQ, PMULUDQ и т.д.?
Повторюсь, потому что рано или поздно это за нас будет делать интерпритатор. Сам будет запаковывать данные в вектора, сам будет заниматься векторизацией и т.д. К сожалению пока этому препятствует динамическая система тиепов. Даже в javascript векторизацию можно делать только в рамках simd API. Да даже в java с этим не так хорошо потому что есть такая штука как боксинг.
А сейчас поскольку PHP не умеет так, вы можете это делать на каком rust и использовать его в PHP.FlameStorm
08.06.2016 14:55Немножко занудного определения:
Интерпрета?ция — пооператорный (покомандный, построчный) анализ, обработка и тут же выполнение исходной программы или запроса (в отличие от компиляции, при которой программа транслируется без её выполнения)
Извините уж, и это давно не тайна, но современный PHP лишь условно интерпретатор. На самом деле он компилятор.
Да. А именно:
PHP читает PHP файл, транслирует, компилирует в opcode, и выполняет скомпилированное.
Керосину в эту нашу библиотеку может плеснуть разве чтоeval
, который is evil и который рекомендуется избегать по очевидной его мешаемости для статического анализа, трансляции и компилировании в опкод «интерпретатором» PHP.
В частности, этап сгенерённых опкодов можно кэшировать всякими Zend Opcode+ / php-apc и т.д., что позволяет PHP пропускать этап трансляции и сразу приступать к выполнению ранее скомпилированной опкодной версии сурса.
Еще как исключает. В этом просто нет смысла.
Кстати, в своём комментарии выше вы сами противоречите естественной логике. Как исключать может, почему, и тем более если привели конкретный пример где интерпретатор и асм прекрасно уживаются — видно мне не понять такого полёта мысли.
А сегодня у нас 2016-ый год, LLVM, умные компиляторы, оптимизирующие компиляторы… Они зачастую выдают код намного более оптимизированный нежели может написать большинство людей. В 9x еще небыло так хорошо потому еще находились извращенцы которым это было нужно. Сегодня — это пережиток прошлого.
О да. Теперь программированием, разработкой, сеньёр-девелопментом и т.п. занимаются, наконец-то, не какие-то там извращенцы, а настоящие профессионалы.
Вообще, глядя на современные тенденции, можно скоро не удивляться заявлениям, что «The Hello World», не требующий
— установки менее трёх сервисных сред,
— от двадцати пяти зависимостей,
— обязательное и широкополосное подключение к интернету для отправки персональных данных в корпорацию добра для заботы о вас,
— а также не менее чем четырёхядерный проц
— и полтара гигабайта доступной под этот «The Hello World» оперативки
— e.t.c
так вообще шляпа и пережиток каменного века. )
Верю, будущее индустрии будет иным.
POPSuL
09.06.2016 00:56+1Я хоть и не джуниор, но с радостью послушал бы лекцию о том, почему мутирующие состояние объекта методы должны возвращать void.
Fesor
09.06.2016 01:36+1Не должны а желательно что бы они ничего не возвращали.
Давайте для начала заменим термины: вызов метода — сообщения между объектами.
Сообщения могут быть трех типов:
- Запросы — сферический примером могут служить геттеры. Они возвращают нам значения но никогда не мутируют состояние. Только чтение.
- Команды — опять же сферический пример — сеттеры. Они не возвращают значений а только меняют состояние.
- Смешанные — классический пример — pop для стэка. Он одновременно возвращает вершину стэка и одновременно изменяет состояние стэка. Этот тип сообщений приходится использовать что бы добиться атомарности.
Собственно из этого мы можем сделать вывод. Если у нас нет необходимости делать атомарно чтение + запись (а на самом деле это крайне редкий кейс) то лучше разделить ответственность на чтение и запись на два отдельных метода. Сделав это мы получаем возможность по разному комбинировать это добро и нам становится намного проще тестировать поведение объектов.
POPSuL
09.06.2016 06:50Ну вот на счет сеттеров я не совсем согласен.
Я вот предпочитаю цепочки вызовов, и часто пишу что-то вроде:
$object = (new SomeClass()) ->setSomething1($a) ->setSomething2($b) ->setSomething3($c);
И получается что это сеттеры, которые меняют состояние объекта, и возвращают ссылку на этот же самый объект.
Fesor
09.06.2016 10:54+1текучий интерфейс это не совсем то же самое. Это не возвращение значений, это возвращение самого себя для удобства.
p.s. я так не делаю обычно, просто потому что редко пишу сеттеры.
alsii
08.06.2016 16:37+3Мне кажется, что если прикладном коде на PHP потребовались вставки на ассемблере, что явно "что-то пошло не так". А если это реюзабельный компонент, то вообще-говоря непонятно, на какой платформе его придется запускать. Ну и если уж совсем никак, то можно написать свое расширение PHP, собрать dll или so, подключить к PHP и использовать в свое удовольствие.
POPSuL
09.06.2016 00:52А почему нет?
[$b, $a] = [$a, $b]
- красивее чем
list($b, $a) = [$a, $b]
; - читабельнее чем
list($b, $a) = [$a, $b]
; - короче чем
list($b, $a) = [$a, $b]
.
- красивее чем
phpclub
02.06.2016 07:36Спасибо Илья — за развернутый ответ по PHP7.1
Можно повлиять на те или иные изменения — пообщавшись автором ветки на DevConf'16
Приглашаю тебя туда бесплатно — глядишь что-то и протолкнем под чаек.LionAlex
02.06.2016 09:11+3И вообще, всем рекомендую этот доклад Дмитрия: интересный рассказ, как удалось добиться такого прироста производительности, много сишного кода, хардкор, все как вы любите. Слушал его на CodeFest'е, это был самый технический доклад из всех, на которых я успел там побывать.
Fesor
02.06.2016 10:44+1Можно повлиять на те или иные изменения
нельзя) Только через процесс обсуждения в php-internals и RFC.
taliban
02.06.2016 11:18+1try {
// to do something
} catch (MyException | AnotherException $e) {
// Handle these exceptions
} catch (Exception $e) {
// Handle this in a different way
}
Всегда думал что эти вещи должны решать интерфейсыalexkunin
02.06.2016 14:46+2Если через интерфейсы, то все библиотеки должны определять исключения через интерфейсы. А если какие-нибудь разработчики супер-популярного компонента забили на это? Возвращаемся к нашим костылям с несколькими catch. А тут получилось компактно и наглядно.
А вообще можно смотреть на это так:
function toDoSomething() { /* ... */ } function handleTheseExceptions(MyException | AnotherException $e) { /* ... */ } function handleThisInADifferentWay(Exception $e) { /* ... */ }
Т.е. фактически это была сигнатура функции… пусть даже только в воображении. Зато повторно используются концепции вроде Union Types.alexkunin
02.06.2016 14:48+1О, да, кроме того: случай, когда несколько исключний, между собой не связанных (т.е. нельзя интерфейсом обобщить) должны быть обработаны одинаково, например закрыть файл и отдать сообщение в лог.
samizdam
02.06.2016 23:14Почему же нельзя? Я на оба повесил бы что-то вроде ClosingFileAndLoggableExceptionInterface
С одной стороны удобный сахар, а с другой Union Types по сути поощряет лень и расшатывает в некотором смысле ООП.
Имхо, неоднозначное улучшение.alexkunin
03.06.2016 00:33+2Обобщите мне, пожалуйста, эксепшны из доктрины и из твига. ;) Я именно об этом случае говорил: у того, кто ловит эксепшны, нет контроля над их классами.
Но вообще согласен, что тут решение довольно спорное — в том смысле, что весьма редкий юзкейз (ну, осмысленный).samizdam
03.06.2016 00:44Ну, чтобы держать свой код в чистоте, для такого случая пришлось бы адаптеры создавать на все используемые библиотечные классы, в адаптерах перехватывать и в своё приложение уже выбрасывать по своему типизированные, обобщённые. ООП головного мозга, короче =)
Fesor
03.06.2016 00:53+2И пришлось бы в каком-то адаптере делать такое:
// ... } catch (DoctrineException | TwigException $exception) { throw new MyUnifiedException('something went wrong', $exception); }
То есть мы просто наплодим сущностей и при этом останемся с тем что было. А если мы и так говорим про какой-то адаптер (инверсия зависимостей, все такое, мы напрямую в нашем коде не зависим от сторонних зависимостей), то к чему это все...
taliban
05.06.2016 20:42-1Я бы не совмещал эксепшены из рахных сфер, вообще в идеале должны быть у каждой библиотеки свои корневые ексепшены и все остальные наследуются от них, тогда можно будет нормально ловить все эксепшены от твитера отдельно, от фейсбука отдельно, от доктрины отдельно. А для того чтоб просто логировать, есть корневой ексепшн пхп
impwx
02.06.2016 15:40+2Структурная типизация — это хорошо, гораздо удобнее и гибче «классической». Представив интерфейс в виде множества требований к классу, можно делать некоторые удобные вещи, например объединять сторонние классы своим интерфейсом, или создавать объединения \ пересечения типов.
Проблема тут в том, что операции над типами — это фундаментальный функционал системы типизации как таковой. Если это добавлять, то сразу во всех местах, где используются типы. Реализовать только частный случай в блокеtry
, но не реализовать в типах аргумента функции — это раскладывание граблей. Будущие поколения разработчиков будут на них наступать и плеваться.
bloknot
06.06.2016 12:21А можете объяснить на конкретном примере, как это должно быть реализовано через интерфейсы? Сам использую конструкции вида try {} catch () {} catch () {}..., которые мне не очень нравятся
taliban
06.06.2016 14:17+1Обьединяйте нужне вам ексепшены в интерфейсы, если нужно что-то сделать общее при нескольких исключениях, если нет доступа к конкретному интерфейсу, всегда можно наслеваться от него и дальше см. пункт 1 — интерфейсы.
impwx
alexkunin
Похоже, в оригинальной статье ошибка, которая прокралась и в перевод. Вот из этого документа следует, что пример должен был быть таким:
impwx
О, так стало понятнее!
Интересно, а выражение в качестве имени поддерживается, или только константные строки?
alexkunin
По ссылке, которая есть внутри того документа, говорится, что можно. Смотрите тут: https://wiki.php.net/rfc/list_keys, раздел «Proposal». Более того, list() можно вкладывать в list() — там есть примеры, выглядят дико. А еще там чуть ниже есть интереснейший foreach вместе с list().
webmoder
ИМХО: статья не правильная была выбрана для перевода.
> Note the syntax isn’t the usual double pipe || operator that we associate with or, rather a single pipe | character.
> You might argue that every function should return something, if only a boolean to indicate successful execution, but that’s another discussion for another day.
Fesor
На самом деле крутата вот в чем:
называется это "деструктуризация", есть в куче языков и тд.
rafuck
Что-то я не увидел в спецификации, что будет, если запрашиваемый ключ в исходном массиве отсутствует: list('foo' => $bar) = array('bar' => 'foo');
alexkunin
Вот еще круче:
$points = [
___[«x» => 1, «y» => 2],
___[«x» => 2, «y» => 1]
];
foreach ($points as list(«x» => $x, «y» => $y)) {
___echo «Point at ($x, $y)», PHP_EOL;
}
Fesor
Да, крутое применение деструктуризации
servekon
Не проще ли использовать
? Аж с 4-й версии можно.
Fesor
А теперь попробуем с другими ключами:
Или еще интереснее: