Comments 58
То есть?
$x = 5;
function foo(void $x) : int {
return $x;
}
Вернет 5? Или данный код некорректен?
Продолжаем потихонечку-потихонечнку двигаться вперёд.
В 8.1, наконец введут псевод-тип для объединения array и ArrayAccess
Насколько я помню (но могу и ошибаться), все кто реализует ArrayAccess так или иначе используют и Traversable интерфейс в конечном итоге. Например, тот же ArrayObject — он будет принят через «iterable» тип.
Другой вопрос самописные классы — но в них нет проблем добавить еще один дополнительный интерфейс Iterator или IteratorAggregate и все так же будет работать…
foreach для ArrayAccess никогда работал — https://3v4l.org/8H8vR
Есть два интерфейса — перебор элементов и доступ к конкретному элементу по ключу. Они не взаимозаменяемые.
Нативный array «реализует» их оба.
И для итерирования, наконец, его слили с объектами с нужным интерфейсом.
А для доступа по ключу, опять забыли.
Тогда в php 9.2 можно ожидать наконец введения типов, как в некоторых других языках? =)
type likeArray = array|ArrayAccess;
function a(likeArray $a) { ... }
ну вот зачем отдавать преимущество {} перед [] для доступа к строке? ничего оно путать не будет, в других языках ведь как-то не путаются. а вот разные скобки задолбаешься ставить.
UPD: А не, они еще не решили
On the opposite side, it was also suggested that array access and string offsets are so closely-related concepts that we should recommend using '[]' in both cases and disable the alternate '{}' syntax for string offsets !
So, as the subject is controversial and very tangential to the subject of this RFC, it will be left for a future RFC.
For reference, the way to fix any issues with this change is to make sure your __isset() or offsetExists() functions behave correctly. If this change causes issues with your code, it indicates that you already have a broken __isset/offsetExists implementation, but it's brokenness did not previously surface (one bug canceling another...)
А вообще согласен, даже patch версии нельзя бездумно или автоматически обновлять, хотя бы не почитав changelog. )
Кстати, это не значит что $x = someNethod(); не вернет ничего. Как и прежде в $x будет значение NULL
У авторов php шмаль явно лучше чем у меня.
Код, который имеет такое поведение уже написан и просто так ломать его не принесет успеха новой версии языка.
Хотя с другой стороны, было бы не плохо кидать какой-то warning для такого кода, чтобы фиксили активнее.
Если использовать библиотеку, которая обновится и функция станет возвращать void,то это как раз тот случай, когда лучше показать даже не ворнинг, а ошибку. Ведь если вызывающий код использовал значение, которое возвращала функция, то он никак не ожидает настолько кардинальной смены логики работы этой самой функции. Прикинуться валенком и продолжать работать — это худшее что может сделать интерпретатор в такой ситуации.
Именно так. Смысл void только в том, чтобы помечать методы (функции) у которых де-факто отсутствует возвращаемое значение. Можно было конечно не изобретать новый псевдотип, а использовать null:
function a(): null {}
Но с другой стороны такая конструкция позволяет писать:
function a(): ?int {
return random_int(0, 1) ?: null;
}
function b(): null {
return a();
}
Что говорит о том, что ошибка может возникнуть в 50% случаях. А на void можно ругаться ещё на этапе парсинга тела метода\функции (скорее всего так и будет, я пока не пробовал войд на практике, не в курсе). Там не должно быть ничего кроме return;
или же он (ретурн) просто должен отсутствовать, что избавляет от подобных проблем.
Функция возвращает Объект, этот объект потом превращается в контент (к примеру в json или xml).
Функция может вернуть int, string, number, Object, null.
Пока не было типов функция могла ничего не возвращать, а просто записать что-то в хедеры и/или установить статус.
Пока весь остальной мир идёт по пути унификации обработки веб-запросов (см. WSGI, Rack, Clack, Plug, WAI, etc.), Вы предлагаете из роутера передавать управление к разнородным функциям, которые хз что возвращают?
Ну, ok… ¯\_(ツ)_/¯
Описанный мною подход — это крайне упрощенный JAX-RS.
На выходе получается крайне простой и самодокументированный код, который не требует пояснений, который не содержит смеси бизнес-логики и формирования конента.
ps: вот пример из мира PHP, чтобы не было притензий, что я с монстроузорной java лезу тут: https://laravel.com/docs/5.3/routing
остальных не нашелдержите: Clack, Plug, WAI.
Но, как мне показалось, это то как на пхп писали еще лет 10 назад.Нет, я 10 лет назад активно писал на PHP, и могу точно сказать, что ничего общего. Возможно, Вы не до конца поняли суть идеи…
Во-первых эти библиотеки не являются фреймворками, наоборот фреймворки (именно во множественном числе, т.е. это своеобразная спецификация, которую уважающий себя фреймворк обязан поддерживать) строятся поверх них.
Во-вторых, благодаря унификации обработчиков из их можно составлять цепочки произвольной длины, начиная с middlewares и заканчивая внутренними механизмами фреймворков. Кроме того, однажды написанную middleware можно опубликовать и люди смогут использовать её практически с любым веб-фреймворком в рамках данного ЯП, потому что никто из создателей фреймворков не стремится изобрести велосипед.
https://laravel.com/docs/5.3/routingПрочитал… И какое-то смешанное ощущение, то ли документашка очень куцая, то ли роутинг в Laravel находится пока ещё в зачаточном состоянии. Во всяком случае описано мало возможностей и самое главное непонятно в чём профит от возможности возвращать разнородные данные из routing callbacks и как эти данные преобразуются в HTTP-ответ?
Но это уже пошел оффтоп. Моя позиция была в том, что такой подход используется в довольно популярных фреймворках и решение по $x = f(), где function f():void, вполне могут быть обоснованы обратной совместимостью.
Так же, я считаю, что в этом случае должна быть какая-то опция, чтобы можно было контролировать уровень ошибки для такого кода: игнорить, ворнинг, эррор, со значением «ворнинг» по-умолчанию.
Эта фича в простом коде не будет сильно использоваться, но дает гибкость для построения абстракции (при разработке фреймворков и библиотек).
Интерфейс метода описывает максимальное допустимое множество значений, которые может обработать.
Имплементация может расширить это множество, скажем обрабатывать не только int, но еще и long, — это не сломает интерфейс int это подмножество множества long. А вот вместо int принимать short мы уже не сможем, т.к. множество short меньше множества int.
— а если работать через интерфейс, то сам интерфейс не позволит передать long, даже если в имплементации аргумент типа long.
Примерно такой же подход при возврате значения, мы можем Уменьшать множество ответов, но не можем его расширять. Уменьшать мы можем только, если меньшее множество ответов является подмножеством большего.
К примеру long в интерфейсе мы сможем заменить на int в имплементации, но вот заменить на bool — не сможем, bool — не является подмножеством множества long. (под bool подразумевается множество {true, false}, а не {1,0})
ps: примеры long, int, bool приведены как ограниченные множества, чтобы проще было понять идею, в реальности такие манипуляции могут не пройти.
void Test() { ... }
как во многих языках программирования это реализовано. Зачем они сделали:
function someNethod(): void { ... }
?
Уж извините за такой вопрос, но он мне покоя не дает.
Потому что родитель был Perl, а не Си.
Потому что типизация пока по желанию.
PHP 7.1: Обзор новых возможностей