php return type declaration

Php return type declaration

Type declarations can be added to function arguments, return values, and, as of PHP 7.4.0, class properties. They ensure that the value is of the specified type at call time, otherwise a TypeError is thrown.

When overriding a parent method, the child’s method must match any return type declaration on the parent. If the parent doesn’t define a return type, then the child method may do so.

Single types

Output of the above example in PHP 8:

mixed

Examples

Example #1 Basic class type declaration

class C <>
class D extends C <>

// This doesn’t extend C.
class E <>

f (new C );
f (new D );
f (new E );
?>

Output of the above example in PHP 8:

Example #2 Basic interface type declaration

// This doesn’t implement I.
class E <>

Output of the above example in PHP 8:

Example #3 Basic return type declaration

The above example will output:

Example #4 Returning an object

function getC (): C <
return new C ;
>

The above example will output:

Nullable type

Example #5 Nullable argument type declaration

The above example will output:

Example #6 Nullable return type declaration

Prior to PHP 7.1.0, it was possible to achieve nullable arguments by making null the default value. This is not recommended as this breaks during inheritance.

Example #7 Old way to make arguments nullable

The above example will output:

Union types

Nullable union types

null cannot be used as a standalone type.

false pseudo-type

The true literal type does not exist.

Duplicate and redundant types

Note: This does not guarantee that the type is “minimal”, because doing so would require loading all used class types.

function foo (): int | INT <> // Disallowed
function foo (): bool | false <> // Disallowed

use A as B ;
function foo (): A | B <> // Disallowed («use» is part of name resolution)

Return only types

void is a return type indicating the function does not return a value. Therefore it cannot be part of a union type declaration. Available as of PHP 7.1.0.

static

The value must be an instanceof the same class as the one the method is called in. Available as of PHP 8.0.0.

Strict typing

It is possible to enable strict mode on a per-file basis. In strict mode, only a value corresponding exactly to the type declaration will be accepted, otherwise a TypeError will be thrown. The only exception to this rule is that an int value will pass a float type declaration.

Function calls from within internal functions will not be affected by the strict_types declaration.

To enable strict mode, the declare statement is used with the strict_types declaration:

Strict typing applies to function calls made from within the file with strict typing enabled, not to the functions declared within that file. If a file without strict typing enabled makes a call to a function that was defined in a file with strict typing, the caller’s preference (coercive typing) will be respected, and the value will be coerced.

Strict typing is only defined for scalar type declarations.

Example #8 Strict typing for arguments values

declare( strict_types = 1 );

Output of the above example in PHP 8:

Example #9 Coercive typing for argument values

The above example will output:

Example #10 Strict typing for return values

declare( strict_types = 1 );

The above example will output:

Coercive typing with union types

As an exception, if the value is a string and both int and float are part of the union, the preferred type is determined by the existing “numeric string” semantics. For example, for «42» int is chosen, while for «42.0» float is chosen.

Types that are not part of the above preference list are not eligible targets for implicit coercion. In particular no implicit coercions to the null and false types occur.

Example #11 Example of types being coerced into a type part of the union

Example #12 Typed pass-by-reference Parameters

Declared types of reference parameters are checked on function entry, but not when the function returns, so after the function had returned, the argument’s type may have changed.

Output of the above example in PHP 8:

Example #13 Catching TypeError

declare( strict_types = 1 );

Output of the above example in PHP 8:

User Contributed Notes 2 notes

same data type and same value but first function declare as a argument type declaration and return int(7)
and second fucntion declare as a return type declaration but return int(8).

While waiting for native support for typed arrays, here are a couple of alternative ways to ensure strong typing of arrays by abusing variadic functions. The performance of these methods is a mystery to the writer and so the responsibility of benchmarking them falls unto the reader.

PHP 5.6 added the splat operator (. ) which is used to unpack arrays to be used as function arguments. PHP 7.0 added scalar type hints. Latter versions of PHP have further improved the type system. With these additions and improvements, it is possible to have a decent support for typed arrays.

declare ( strict_types = 1 );

Источник

PHP RFC: Return Type Declarations

Introduction

Many developers would like to be able to declare the return type of a function. The basic idea of declaring a return type has been included in at least three RFCs and has been discussed in a few other places (see references). This RFC proposes a different approach from previous RFC ‘s to accomplish this goal in a simple way.

Declaring return types has several motivators and use-cases:

Proposal

This proposal adds an optional return type declaration to function declarations including closures, functions, generators, and methods. This RFC does not change the existing type declarations nor does it add new ones (see differences from past RFCs).

Here is a brief example of the syntax in action:

More examples can be found in the Examples section.

Variance and Signature Validation

The enforcement of the declared return type during inheritance is invariant; this means that when a sub-type overrides a parent method then the return type of the child must exactly match the parent and may not be omitted. If the parent does not declare a return type then the child is allowed to declare one.

If a mismatch is detected during compile time (e.g. a class improperly overriding a return type) then E_COMPILE_ERROR will be issued. If a type mismatch is detected when the function returns then E_RECOVERABLE_ERROR will be issued.

Note that this topic of variance is about the declared return type of the function; this means that the following would be valid for either invariant or covariant return types:

The class B implements A so it is therefore valid. Variance is about the allowed types when overriding the declared types:

Position of Type Declaration

The two major conventions in other programming languages for placing return type information are:

The latter position is used in several languages 3) ; notably C++11 also places the return type after the parameter lists for certain constructs such as lambdas and auto-deducing return types.

Declaring the return type after the parameter list had no shift/reduce conflicts in the parser.

Returning by Reference

Disallowing NULL on Return Types

Consider the following function:

It declares that it will return DateTime but returns null ; this type of situation is common in many languages including PHP. By design this RFC does not allow null to be returned in this situation for two reasons:

The Nullable Types RFC addresses this shortcoming and more.

Methods which cannot declare return types

Class constructors, destructors and clone methods may not declare return types. Their respective error messages are:

Examples

Here are some snippets of both valid and invalid usage.

Examples of Valid Use

Examples of Invalid Use

The error messages are taken from the current patch.

Catchable fatal error: Return value of get_config() must be of the type array, integer returned in %s on line %d

Catchable fatal error: Return value of answer() must be an instance of int, integer returned in %s on line %d

Catchable fatal error: Return value of foo() must be an instance of DateTime, null returned in %s on line %d

Fatal error: Declaration of UserGateway_MySql::find() must be compatible with UserGateway::find($id): User in %s on line %d

Fatal error: Generators may only declare a return type of Generator, Iterator or Traversable, %s is not permitted in %s on line %d

Multiple Return Types

This proposal specifically does not allow declaring multiple return types; this is out of the scope of this RFC and would require a separate RFC if desired.

If you want to use multiple return types in the meantime, simply omit a return type declaration and rely on PHP’s excellent dynamic nature.

Reflection

Differences from Past RFCs

This proposal differs from past RFCs in several key ways:

Other Impact

On Backward Compatiblity

On SAPIs

There is no impact on any SAPI.

On Existing Extensions

The structs zend_function and zend_op_array have been changed; extensions that work directly with these structs may be impacted.

On Performance

An informal test indicates that performance has not seriously degraded. More formal performance testing can be done before voting phase.

Proposed PHP Version(s)

Patches and Tests

Dmitry and I have updated the implementation to a more current master branch here: https://github.com/php/php-src/pull/997

Future Work

Ideas for future work which are out of the scope of this RFC include:

References

The following (tiny) patch would allow the syntax in suggestion 5 to be used alongside the current syntax. This RFC does not propose that both versions of syntax should be used; the patch just shows how similar this RFC is to that suggestion from 2005.

Источник

Новый PHP, часть 1: Return types

php return type declaration. Смотреть фото php return type declaration. Смотреть картинку php return type declaration. Картинка про php return type declaration. Фото php return type declarationКаждый мажорный релиз PHP добавляет ряд новых возможностей, некоторые из которых действительно имеют значение. Для PHP 5.3 — это были пространства имен и анонимные функции. Для PHP 5.4 — трейты. Для PHP 5.5 — генераторы. Для 5.6 — списки аргументов переменной длины.

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

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

Возвращаемые типы

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

Постфиксный синтаксис для возвращаемых типов может показаться странным для разработчиков, привыкших к C/C++ или Java. Однако, на практике подход с префиксным объявлением не подходит для PHP, т.к. перед именем функции может идти множество ключевых слов. Во избежание проблем с парсером PHP выбрал путь схожий с Go, Rust и Scala.

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

Большинство читателей быстро заметит, что `findById()` имеет баг, т.к. в случае, если мы попросим несуществующий идентификатор сотрудника PHP будет возвращать `null` и наш вызов `getAddress()` умрет с ошибкой «method called on non-object». Но на самом деле ошибка не там. Она заключается в том, что `findById()` должен возвращать сотрудника. Мы указываем возвращаемый тип `Employee`, чтобы было ясно чья это ошибка.

Что же делать, если действительно нет такого сотрудника? Есть два варианта: первый — исключение; если мы не можем вернуть то, что мы обещаем — это повод для особой обработки за пределами нормального течения кода. Другой — указание интерфейса, имплементация которого и будет возвращена (в том числе и «пустая»). Таким образом, оставшаяся часть кода будет работать и мы сможем контролировать происходящее в «пустых» случаях.

Выбор подхода зависит от варианта использования и также определяется рамками недопустимости последствий в случае невозвращения правильного типа. В случае репозитория, я бы поспорил с выбором в пользу исключений, поскольку шансы попасть именно в такую ситуацию минимальны, а работа через исключения является довольно дорогостоящей по производительности. Если бы мы имели дело со скалярной переменной, то обработка «пустого значения» было бы приемлемым выбором. Модифицируем наш код соответственно (для краткости показаны только измененные части):

Теперь getStreet() будет отдавать хорошее пустое значение.

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

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

Источник

Революция PHP7: Типы возвращаемых значений и удаление артефактов

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

PHP 5.7 vs. PHP7

php return type declaration. Смотреть фото php return type declaration. Смотреть картинку php return type declaration. Картинка про php return type declaration. Фото php return type declaration

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

Обратите внимание, что пока голосование неоднозначно, это говорит о том, что идея окончательно не похоронена. Участники высказываются против 5.7 из-за отсутствия значительных изменений, но с учетом новых голосов на других RFC, они вполне могут изменить свое решение. Давайте посмотрим что произойдет.

Типы возвращаемого значения (Return Types)

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

Улучшение? Однозначно. Но идеальное ли? К сожалению, нет:

Некоторые люди также жаловались на объявления типа после закрывающей скобки списка аргументов, а не перед именем функции, но для меня это придирки. Популярные языки, такие как современный C++, используют “пост”-синтаксис, при этом сохраняется возможность поиска «function foo» без какой-либо необходимости прибегать к regex-модификациям. Более того, это согласуется с тем, что использует HHVM, таким образом получается непредвиденный бонус в совместимости.

php return type declaration. Смотреть фото php return type declaration. Смотреть картинку php return type declaration. Картинка про php return type declaration. Фото php return type declaration

Другие жаловались на «строгость» PHP, но, как заявил один из комментаторов, вы действительно должны знать что хотите получить еще до начала кодирования, через интерфейсы и наследование чужого кода. Кроме того, пока указание возвращаемых типов необязательно, и его наличие никак не влияет на общую производительность или стабильность PHP, не нужно раздувать из этого проблему. Жаловаться на такую фичу, все равно что жаловаться на наличие ООП в PHP в те времена, когда процедурные спагетти были хорошим способом решить задачу. Языки эволюционируют, и это один из шагов в правильном направлении.

Удаление артефактов

php return type declaration. Смотреть фото php return type declaration. Смотреть картинку php return type declaration. Картинка про php return type declaration. Фото php return type declaration

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

Приговор «код, который я написал 10 лет назад, по-прежнему должен запускаться сегодня и должна быть возможность выполнить его через 10 лет» — для меня безумие — вы, безусловно, не должны ожидать подобного ни от одного популярного языка в рамках перехода от одной основной его версии к другой. Проведите параллель с реальным миром, вы не должны ожидать разрешения иметь рабов сегодня, только потому, что когда-то давно закон это разрешал. Да, был кровавый переход, но когда большинство сторонников рабства либо покаялись либо умерли, настал мир.

php return type declaration. Смотреть фото php return type declaration. Смотреть картинку php return type declaration. Картинка про php return type declaration. Фото php return type declaration

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

Мой совет тем, кто опасается PHP7 — стоп. Если вы не хотите обновляться, то и не делайте этого. Если вы сидели на 5.3 или 5.2 так долго (привет, любители CodeIgniter), то посидите на 5.6 еще десяток лет, не мешайте PHP быть современным. Оставьте прогресс для тех, кто готов принять его.

Что думаете вы по этому поводу? Вся эта затея с удалением артефактов бред или действительно нужный шаг?

В сторону: изменения Extension API

В качестве интересной заметки на полях, есть некоторые изменения в PHP7, которые могут стать причиной небольшой задержки с портированием расширений на версию 7. API для создания расширений попало под рефакторинг (чистку) и все может поменяться, тем не менее этот провакационный твит от Sara Golemon собрал немного внимания.

Damn. There are some serious surprises in the PHP7 Extension API changes. Not for nothin’, but it’s a good time to switch to HHVM.
— SaraMG (@SaraMG) January 3, 2015

Она в основном говорит о том, что изменения в создании расширений при переходе от 5.6 до 7 будет настолько большими, что проще узнать как делать расширения под HHVM. А затем она продолжает развивать тему серией статей на тему как создать HHVM extension.

Вы разрабатываете расширения? Изучали ли вы изменения и как вы относитесь к всему этому, не слишком ли рано сейчас говорить о будущем эффекте?

Edit: Мое внимание обратили на то, что Сара уже после всего этого начала документировать новое API расширений, совместимое и с HHVM и с PHP7. Похоже, можно делать расширения, совместимые с обоими рантаймами!

Вывод

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

Что вы думаете об этих RFC? Как вы относитесь PHP7 в целом? Движется ли он в правильном направлении? Дайте нам знать — мы хотим услышать ваши мысли!

Источник

Возврат значений

Использование выражения return

Пример #1 Использование конструкции return

Функция не может возвращать несколько значений, но аналогичного результата можно добиться, возвращая массив.

Пример #2 Возврат нескольких значений в виде массива

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

Пример #3 Возврат результата по ссылке

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

Объявление типов возвращаемых значений

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

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

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

Примеры

Пример #4 Обычное объявление типа возвращаемого значения

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

Пример #5 То же в режиме строгой типизации

declare( strict_types = 1 );

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

Пример #6 Возврат объектов

function getC (): C <
return new C ;
>

Источник

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *