Как стать автором
Обновить

Комментарии 38

> при наследовании тип не может быть изменен, даже нельзя сделать его более конкретным (подклассом, например)

На самом деле это грустно, ибо для конкретных объектов от абстрактов, имело бы смысл сужать круг подозреваемых результатов… Но это лучше конечно чем ничего :)
Вы не можете переопределить сигнатуру, но вы можете вернуть объект класса-наследника.
Это ясно, и ясно что по принципу Лисков это может и не нужно. И по сути возможность переопределять сигнатуру означало бы перегрузку функции, но тем не менее с тайп хинтингом это можно сейчас делать, а с возвращаемыми типами уже нет
… вообщем то движение очень в сторону Java идут, и не факт что это хорошо для php именно для php, потому как если нет разницы то зачем выбирать в сторону php, когда экосистема java и синтаксис уже проверен годами!
На сколько я знаю, сейчас в STRICT режиме интерпретатор ругается на изменение сигнатуры в наследнике. За исключение конструкторов.

вообщем то движение очень в сторону Java идут, и не факт что это хорошо для php именно для php

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

А если хочется что-то не такое строгое как Java и не такое фривольное как Ruby — то PHP самое то.
<зануда>
PHP все-таки по умолчанию является слабо-типизированным языком с динамической типизацией. Да, в 7-ой версии должен появиться strict-mode, но по умолчанию он выключен. А то, о чем Вы говорите, является все-таки type-hinting'ом.
</зануда>

Ну а вообще, отсутствие возможности вернуть null — довольно сомнительный плюс, теперь вместо обычной проверки на null, например при использовании ORM, нужно будет городить велосипед. Да и вообще создается впечатление, что php пытается напялить на себя костюм джавы, постоянно усложняясь, а за ним идет и весь php-мир, за некоторыми исключениями. И вот это по-моему не очень хорошо, ведь основным преимуществом php была простота разработки.
Вы по прежнему можете вернуть null, но тогда метод должен быть без типизации результата, а если с типизацией, то надо выкидывать исключение, делов-то.
Исключения для такого случая всё-таки сомнительная практика (по крайней мере в PHP).
Доктрина при попытке найти ентити по ключу кидает исключение. И это правильно

Другое дело что java обязывает отлавливать все исключение, чего пхп пока делать не научился
чего пхп пока делать не научился

не PHP не научился а PHP-ники не научились. в Java это надо что бы не уранить все, в PHP всем пофигу.
Нет вы не поняли ) В Java на уровне языка запрещено неотлавливать исключения. Или объяви явно что ты пробрасываешь исключение дальше, или обработай его сразу в коде. От этого больше писанины, но насколько увереннее писать код в таком случае.
Доктрина при попытке найти ентити по ключу кидает исключение. И это правильно


/** @return object|null The entity instance or NULL if the entity can not be found. */


И это правильно. Поиск по ключу операция семантически отличная от, например, получения значения в массиве по ключу. Для поиска результат «не найден» — не исключение.
Потому что это getSingleResult. Есть еще getOneOrNullResult
Как уже выше отметили для некоторых случаев исключения — не лучший выход. А вот null все-таки очень универсальный тип, означающий «ничто».
Давайте рассмотрим примеры, когда корректно выбрасывать исключение, а когда все-таки лучше null(примеры очень субъективны, буду рад конструктивной критике):
  • Корректнее вернуть null, например, при работе с ORM, например, какой-нибудь абстрактный Model::findByPk($id). При этом лучше, если у нас будет возможность указать хинтом, экземпляр какого класса должен быть возвращен методом findByPk
  • Доступ к элементу связанного списка по индексу(хотя кто же на php использует связанные списки!). В этом случае лучше выбросить исключение. При этом возвращаемые значения могут быть определенного типа либо же любого типа.
Не соглашусь: если вы говорите точно, что этот метод должен вернуть SomeClass, то он уже не просто МОЖЕТ, а ДОЛЖЕН вернуть его. И если у метода нет такой возможности, то это исключительная ситуация. Так же как и при передаче параметра в функцию, если вы передадите null вместо SomeClass, то получите «Argument 1 passed to some_func() must be an instance of SomeClass, null given».
Если вы добавляете строгости своему коду, то нужно ее соблюдать, а если хотите null, то не надо закладывать строгость.
Мне интуитивно понятен именно такой подход, не понимаю полустрогости.
Ваш ник намекает, что вам ближе maybe-подход к обработке подобных случаев.
Но в php это получится дороговато по ресурсам.

>> если вы говорите точно, что этот метод должен вернуть SomeClass
речь о том, что я хочу сказать, что этот метод должен вернуть SomeClass_или_null
Мой ник совсем не связан с моими пристрастиями :-)

Я понял, вам надо это https://wiki.php.net/rfc/nullable_types
Ну я не против, если в таком виде, но предпочитаю очевидную строгость.
НЛО прилетело и опубликовало эту надпись здесь
Ок, передайте в своем php null в функцию с type-hinting-ом, и не получите fatal error.
НЛО прилетело и опубликовало эту надпись здесь
разные школы кунг-фу
Передавать в метод null при налачии типизированно параметра можно, при условии если этот параметр имеет значение по умолчанию null

Например

function doSomething(SomeClass $arg=null){}


не вызовет ошибки при передачи null

однако

function doSomething(SomeClass $arg){}


действительно даст «Argument 1 passed to doSomething must be an instance of SomeClass, null given»
Возвращение объекта определенного класса или null (вернее какого-то специального значения, будь то null, NullObject, false и т. п.) во многих случаях вполне нормальная ситуация, а не исключительная, например тот же поиск по уникальному ключу в репозитории — для репозитория это просто «не найден», а исключительная это ситуация (договор ссылается на несуществующего клиента, например) или нормальная (раз не найден, то надо создать нового) решается одним, как минимум, уровнем выше, клиентом репозитория. Но уж если возвращает не признак «не найден», то должен вернуть объект строго определенного класса. И это не полустрогость, а вполне нормальная строгость «или ..., или ...».
К сожалению это все последствие зимней драмы с тайп хинтингом. Пока все холиварили RFC добавляющее нулабл как-то упустили
Это понятно. Я к тому, что бросать исключения, если не можешь вернуть полноценный объект не потому, что не смог его создать, хотя от тебя это ожидалось, а потому, что не смог его найти в хранилище или ещё где — порочная практика в общем случае. И вернуть какое-то особое значение — нормально. А null это будет, особый инстанс обычного класса, обычный инстанс особого наследника обычного класса, обычный инстанс особого класса с тем же интерфейсом, что обычный класс — детали реализации, зачастую диктуемые языком.
Запрет на null должен быть в языках с подержкой maybe типов и сопоставления с образцом. Там это очень лаконично вписывается. В php же это проблема, которая уже на рассмотрении, просто это не успели включить в версию. Ждем nullable значения в 7.1
НЛО прилетело и опубликовало эту надпись здесь
Тут вы не совсем правы. Один из разработчиков обещал после принятия указания скалярных типов, написать JIT для PHP, и во многом он будет основываться на type-hinting.
Так что ждём что у него получится.
НЛО прилетело и опубликовало эту надпись здесь
Нет, я о другом. В ходе обсуждения rfc про type-hinting скалярных типов, один из разработчиков обещал после принятия этого rfc заняться написанием JIT.

По поводу phpng, там ситуация была в том что они исследовали возможности улучшения производительности, и по началу пробовали JIT, но поняв что он не даёт сильного прироста производительности, после этого они копнули глубже и в итоге переписали очень много внутренностей. Что и позволило получить стоить значительный прирост. Но при этом идею с JIT они всё же не выкинули, а просто отложили. В своём докладе Дмитрий Стогов, в том числе говорил что на данный момент они без JIT очень близки к производительности HHVM, и он видит в этом место для роста. Т.е. вполне вероятно что в скором будущем JIT всё же появиться. И что учитывая изменения произошедшие в движке PHP уже может сулить так же не малый прирост производительности.

Хотя нужно сказать что это ИМХО, так как прямых заявлений что кто-то _уже_ занимается разработкой JIT, я пока не видел.
после принятия этого rfc заняться написанием JIT.

Не JIT а полноценный компилятор, ну мол… информация о типах есть, так что предполагалось что PHP код написанный в стрикт режиме можно просто компилить напрямую в машинный код.

прямых заявлений что кто-то _уже_ занимается разработкой JIT, я пока не видел

А никто и не занимается. К этому скорее всего вернутся после стабилизации и релиза PHP7, глядишь в каком-нибудь PHP8 уже будет JIT.
НЛО прилетело и опубликовало эту надпись здесь
Ну информация о типах только для аргументов и возвращаемых значениях, не более…

Так сложно вычислить тип в момент компиляции? Почти все взрослые языки это умеют уже.

В поставке php идут функции которые в стрикт режиме просто не собрать

Они уже собраны, речь идет только о компиляции PHP в нативный код в обход виртуальной машины (грубо говоря экстеншены для PHP на PHP), с минимумом оверхэда связанного именно с вызовом вот этих ненадежных функций. Опять же, никто насколько я знаю еще ничего такого не пишет, а Антонио Ферера (не помню как его фамилия правильно произносится) только приводил идею подобной штуки как идею на будущее и хорошее подспорье для оптимизаций внутри JIT.
НЛО прилетело и опубликовало эту надпись здесь
В любом случае работаем с zval

А вот тут уже зависит от реализации. В прочем без типизированных массивов мечтать о анпакинге переменных не приходится… А компиляция штук вида:

function foo(int $a, int $b) : int {
    return $a + $b;
}


явного профита не даст.
Надеюсь что в будущих версиях все еще можно будет использовать NULL. А то судя по всему PHP медленно но уверенно превращается в Java, где на одну строчку «кода» нужно добавлять 100 строк для различных типизаций и опработки ошибок.
где на одну строчку «кода» нужно добавлять 100 строк для различных типизаций и опработки ошибок.

Вас никто не заставляет использовать тайпхинтинг для возвращаемых значений или для скаляров. А вот мне эти плюшки будут полезны. Правда без nullable будет грустно пока, но думаю в PHP 7.1 и оно появится.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории