Function return type in php

PHP RFC: Return Type Declarations

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:

Prevent sub-types from breaking the expected return type of the super-type 1) , especially in interfaces

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.

Code which does not declare a return type will continue to work exactly as it currently does. This RFC requires a return type to be declared only when a method inherits from a parent method that declares a return type; in all other cases it may be omitted.

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.

Covariant return types are considered to be type sound and are used in many other languages 2) . This RFC originally proposed covariant return types but was changed to invariant because of a few issues. It is possible to add covariant return types at some point in the future.

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:

interface A { static function make(): A; } class B implements A { static function make(): A { return new B(); } }

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

interface A { static function make(): A; } class B implements A { static function make(): B { // must exactly match parent; this will error return new B(); } }

The above sample does not work because this RFC proposes only invariant return types; this could be extended in the future to be allowed.

Читайте также:  Open file python buffering

Position of Type Declaration

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

The former position has been proposed in the past and the RFCs were either declined or withdrawn. One cited issue is that many developers wanted to preserve the ability to search for function foo to be able to find the definition for foo . A recent discussion about removing the function keyword has several comments that re-emphasized the value in preserving this.

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

This RFC does not change the location of & when returning by reference. The following examples are valid:

Disallowing NULL on Return Types

Consider the following function:

function foo(): DateTime { return null; // invalid }

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:

This aligns with current parameter type behavior. When parameters have a type declared, a value of null is not allowed 4) .

Allowing null by default works against the purpose of type declarations. Type declarations make it easier to reason about the surrounding code. If null was allowed the programmer would always have to worry about the null case.

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

// Using a generator: interface Collection extends IteratorAggregate { function getIterator(): Iterator; } class SomeCollection implements Collection { function getIterator(): Iterator { foreach ($this->data as $key => $value) { yield $key => $value; } } }

Examples of Invalid Use

The error messages are taken from the current patch.

// Covariant return-type: interface Collection { function map(callable $fn): Collection; } interface Set extends Collection { function map(callable $fn): Set; }

Fatal error: Declaration of Set::map() must be compatible with Collection::map(callable $fn): Collection in %s on line %d

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

// Int is not a valid type declaration function answer(): int { return 42; } answer();

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

// Cannot return null with a return type declaration function foo(): DateTime { return null; } foo();

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

// Missing return type on override class User {} interface UserGateway { function find($id): User; } class UserGateway_MySql implements UserGateway { // must return User or subtype of User function find($id) { return new User(); } }

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

Читайте также:  Run unit test java

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

This RFC purposefully omits reflection support as there is an open RFC about improving type information in reflection: https://wiki.php.net/rfc/reflectionparameter.typehint

Differences from Past RFCs

This proposal differs from past RFCs in several key ways:

The return type is positioned after the parameter list. See Position of Type Declaration for more information about this decision.

We keep the current type options. Past proposals have suggested new types such as void , int , string or scalar ; this RFC does not include any new types. Note that it does allow self and parent to be used as return types.

We keep the current search patterns. You can still search for function foo to find foo ‘s definition; all previous RFCs broke this common workflow.

We allow return type declarations on all function types. Will Fitch’s proposal suggested that we allow it for methods only.

We do not modify or add keywords. Past RFCs have proposed new keywords such as nullable and more. We still require the function keyword.

Other Impact

On Backward Compatiblity

This RFC is backwards compatible with previous PHP releases.

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)

Vote

This RFC modifies the PHP language syntax and therefore requires a two-third majority of votes.

Should return types as outlined in this RFC be added to the PHP language? Voting will end on January 23, 2015.

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

This RFC was merged into the master branch (PHP 7) in commit 638d0cb7531525201e00577d5a77f1da3f84811e.

Future Work

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

Improve parameter variance. Currently parameter types are invariant while they could be contravariant. Change the E_STRICT on mismatching parameter types to E_COMPILE_ERROR.

Читайте также:  Install python egg files

References

In the meeting in Paris on November 2005 it was decided that PHP should have return type declarations and some suggestions were made for syntax. Suggestion 5 is nearly compatible with this RFC ; however, it requires the addition of a new token T_RETURNS . This RFC opted for a syntax that does not require additional tokens so returns was replaced by a colon.

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.

Источник

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

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

Замечание:

Если конструкция return не указана, то функция вернет значение NULL .

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

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

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

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

function small_numbers ()
return array ( 0 , 1 , 2 );
>
list ( $zero , $one , $two ) = small_numbers ();
?>

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

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

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

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

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

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

Замечание:

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

Примеры

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

// Будет возвращаться значение типа float.
var_dump ( sum ( 1 , 2 ));
?>

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

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

function sum ( $a , $b ): int return $a + $b ;
>

var_dump ( sum ( 1 , 2 ));
var_dump ( sum ( 1 , 2.5 ));
?>

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

int(3) Fatal error: Uncaught TypeError: Return value of sum() must be of the type integer, float returned in - on line 5 in -:5 Stack trace: #0 -(9): sum(1, 2.5) #1 thrown in - on line 5

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

function getC (): C return new C ;
>

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

Источник

Оцените статью