Php class parameter type

Контроль типа

PHP 5 предоставляет возможность использовать контроль типов. На данный момент функции имеют возможность заставлять параметры быть либо объектами (путем указания имени класса в прототипе функции), либо интерфейсами, либо массивами (начиная с PHP 5.1), или колбеком с типом callable (начиная с PHP 5.4). Однако, если NULL использовался как значение параметра по умолчанию, то это будет также допустимо в качестве аргумента для последующего вызова.

Если класс или интерфейс указан для контроля типа, то все его потомки или реализации также допустимы.

Контроль типа не может быть использован со скалярными типами, такими как int или string . Ресурсы и Трейты также недопустимы.

Пример #1 Пример контроля типов

// Тестовый класс
class MyClass
/**
* Тестовая функция
*
* Первый параметр должен быть объектом типа OtherClass
*/
public function test ( OtherClass $otherclass ) echo $otherclass -> var ;
>

/**
* Другая тестовая функция
*
* Первый параметр должен быть массивом
*/
public function test_array (array $input_array ) print_r ( $input_array );
>

/**
* Первый параметр должен быть итератором
*/
public function test_interface ( Traversable $iterator ) echo get_class ( $iterator );
>

/**
* Первый параметр должен быть типа callable
*/
public function test_callable (callable $callback , $data ) call_user_func ( $callback , $data );
>
>

// Другой тестовый класс
class OtherClass public $var = ‘Hello World’ ;
>
?>

В случае передачи аргумента неправильного типа результатом будет фатальная ошибка.

// Экземпляры каждого класса
$myclass = new MyClass ;
$otherclass = new OtherClass ;

// Ошибка: Аргумент 1 должен быть экземпляром класса OtherClass
$myclass -> test ( ‘hello’ );

// Ошибка: Аргумент 1 должен быть экземпляром класса OtherClass
$foo = new stdClass ;
$myclass -> test ( $foo );

// Ошибка: Аргумент 1 не должен быть null
$myclass -> test ( null );

// Работает: Выводит Hello World
$myclass -> test ( $otherclass );

// Ошибка: Аргумент 1 должен быть массив
$myclass -> test_array ( ‘a string’ );

// Работает: Выводит массив
$myclass -> test_array (array( ‘a’ , ‘b’ , ‘c’ ));

// Работает: Выводит ArrayObject
$myclass -> test_interface (new ArrayObject (array()));

// Работает: Выводит int(1)
$myclass -> test_callable ( ‘var_dump’ , 1 );
?>

Также, контроль типов работает и с функциями:

// Пример класса
class MyClass public $var = ‘Hello World’ ;
>

/**
* Тестовая функция
*
* Первый параметр должен быть объект класса MyClass
*/
function myFunction ( MyClass $foo ) echo $foo -> var ;
>

// Это работает
$myclass = new MyClass ;
myFunction ( $myclass );
?>

Контроль типов допускает значения NULL:

/* Прием значения NULL */
function test ( stdClass $obj = NULL )

test ( NULL );
test (new stdClass );

Источник

PHP RFC: Object typehint

PHP 7 introduced scalar types for parameters and also for declaring return types for functions.

However it is not currently possible to declare that a function either needs to be passed an object as a parameter, or to declare that a function must return an object.

Читайте также:  Python как закоментить несколько строк

Proposal

This RFC proposes that object should be used as a parameter type and as a return type. Any object would pass the type check.

Passing a value that is not an object to a parameter that is declared as type object would fail the type check, and a TypeError would be thrown.

Similarly, if a function is declared as returning an object but does not return an object, again a TypeError would be thrown.

As it would be used internally, object would become a reserved classname, unavailable for use as a class name in userland code.

For class methods that use object as either a parameter or return type, the inheritance checks would use contravariance for parameter types, and covariance for return types.

Examples

Parameter type

function acceptsObject(object $obj) { . } // This code can be statically analyzed to be correct acceptsObject(json_decode('<>')); // This code can be statically analyzed to be correct acceptsObject(new \MyObject()); // This can be statically analysed to contain an error. // and would throw an TypeError at runtime. acceptsObject("Ceci n'est pas une object.");

Return type

Functions and methods can be declared with an object return type, to enforce that the function must return an object.

// This function can be statically analysed to conform to the // return type function correctFunction() : object { $obj = json_decode('<>'); return $obj; } // This function can be statically analysed to contain an error // and will also fail at runtime. function errorFunction() : object { return []; }

Benefits

Make code easier to understand

Although most code deals with specific types, there are several types of library where it is common to handle arbitrary object types.

Hydrators + data extractor

Hydrators allow objects to be filled with data from an array. Extractors do the opposite, they take an object and return an array of data.

interface Hydration { // Hydrate an object by populating data public function hydrate(array $data, object $object) : object; } interface Extraction { // Extract values from an object public function extract(object $object) : array; }

The extraction step can take an arbitrary object as the sole parameter. The hydration step can take an arbitrary object as the second parameter, and will return an arbitrary object. Having the type for the parameters and the return type be set as object will make the expected types be clearer to anyone using these functions, as well as detect incorrect types if there is an error in the code.

Service containers and DIC libraries

For both service containers and dependency injection libraries, it is common to want to put services and other objects into the container.

interface ServiceContainer { // Set service definition public function set(string $id, object $service); // Retrieve service object from container public function get(string $id) : object; }

Additionally, ORM libraries such as Doctrine have functions that will either consume or produce arbitrary objects.

Catching return errors

Having an object return type would allow some errors to be detected more quickly. The following function is meant to return an object. With the object return typ set for the function, failing to return an object would cause a TypeError to be thrown in the location where the bug is.

function unserialize($data) : object { $type = $data['type']; switch ($type) { case 'foo': { return new Foo(); } case 'bar': { return new Bar(); } case 'zot': { new zot(); } // Ooops, this is an error } }

Without the object return type, an incorrect value of null is returned from the function. This error can only be found by debugging at runtime.

Читайте также:  Html код кнопки ютуба

Enforcing signature in inheritance

Currently, as PHP does not allow ‘object’ to be used as a return type, it is not possible to enforce the return type in a child class. In this example the method is supposed to return an object, but a programmer has changed what the function does in the child class.

class WidgetFactory { function create() { return new Widget(); } } class CustomWidgetFactory extends WidgetFactory { function create() { $object = new Widget(); return true; //This is an error that cannot be statically analyzed. } }

This type of error can only be detected when running the code.

If we had object as a type, even if a programmer misunderstood what the method was supposed to do, and accidentally tried to create a child class that had a different signature, the code would not compile, and the error would be caught before the code is run:

class WidgetFactory { function create() : object { return new Widget(); } } class CustomWidgetFactory extends WidgetFactory { // This class would not compile, as the signature of the metod in // the child class is not compatible with the method signature in // the parent class. function create() : bool { . } }

If the programmer wrote the correct signature for the method in the child class, but returned the wrong value, this error would also be caught:

class WidgetFactory { function create() : object { return new Widget(); } } class CustomWidgetFactory extends WidgetFactory { function create() : object { $object = new Widget(); // returning something that is not an object throws a TypeError exception. return true; } }

This would also be an error detectable by a static analyzer.

Variance

Argument typehint contravariance

Classes that extend another class, or implement an interface may broaden a parameter type from a specific class, to more generic ‘object’ typehint.

class Foo { } class Bar { public function foo(Foo $object) : object { return $object; } } class Baz extends Bar { public function foo(object $object) : object { return $object; } }

This is normally known as contravariant.

Classes extending/implementing may not narrow method arguments types from ‘object’ to more specific type.

class Foo { } class Bar { public function foo(object $object) : object { return $object; } } class Baz extends Bar { public function foo(Foo $object) : object { return $object; } }

In this situation the standard PHP warning for incompatible signatures will be raised.

Declaration of Baz::foo(Foo $object): object should be compatible with Bar::foo(object $object): object

Return type covariance

Classes extending/implementing may narrow methods return types from ‘object’ to specified class name. This behavior is the similar as that proposed for ‘iterable’ and is normally called covariant.

class Foo { } class Bar { public function foo(object $object) : object { return $object; } } class Baz extends Bar { public function foo(object $object) : Foo { return $object; } }

In above example ‘object’ return type was narrowed to ‘Foo’ type in extending class.

Читайте также:  The javascript definitive guide pdf

Reflection

There are two changes in reflection:

Backward Incompatible Changes

Although ‘object’ is already a soft reserved word, this RFC adds object as fully reserved classname.

Источник

Type Hinting in PHP

In this Tutorial, we will learn about “Type Hinting in PHP”

Type Hinting is a programming term in which we can define types of parameters, arguments, return types of a class, parameters, and their functions. As you know there are two types of language. Static (Java, C++) and dynamic (PHP, Python)

  • In simple words, type hinting means providing type hints to function to only accept the given data type.
  • In technical word we can say that Type Hinting is a method by which we can force function to accept the desired data type.
  • Type Hinting in PHP, we can use type hinting for Object, Array, and callable data types.
  • Type hinting can help developers in any application by providing information regarding parameter types, function return types, etc.

Why should we use Type Hinting in PHP

Type Hinting will will help us to keep our code more organized and error free. It will help us by providing better error message. Also type hinting will increase the readability of the code.

Type Hinting in PHP Example:

 // SHOW STUDENTS FUNCTION DEFINATION WHERE ARE DEFINING THE ARGUMENT TYPE function showStudents(Students $student_list)< print_r($student_list->students) ; > // CALLING showStudents METHOD, WHERE WE CAN ONLY PASS STUDENTS TYPE showStudents(new Students()); ?>

Example Explanation:

  • As you can see, there is a Students class where Students is stored as an array in $students array.
  • There is a showStudents function definition which takes argument as a class. This function receives Class as argument. If we pass any integer or array as argument, it will give us an error. Such as, Let’s say: when we calling the method showStudents(), if we pass an array as parameter , like this:
showStudents(array('John', 'Doe'));

it will give us an error, like: Fatal error: Uncaught TypeError: Argument 1 passed to showStudents() must be an instance of Students, array given

    So as we type hinted that method as class argument type, we must pass class like this: showStudents(new Students());It will give us the expected result like below:
Array ( [0] => Walter [1] => White [2] => Jesse [3] => Pinkman )

Disadvantages of Type Hinting:

So, we can say that, Type Hinting will save us from many errors related to arguments and parameter. Type hinting can help us to catch certain types of mistakes. Also will help in the long run to work in a old/legacy codebase or to a future developer.

That’s all for today. See you in next one.

If you like this one, please checkout my other articles.

If you like this article, please checkout our others article as well.

Laravel:

PHP:

Источник

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