PHP
Tipo de insinuación
Buscar..
Sintaxis
- función f (ClassName $ param) {}
- función f (bool $ param) {}
- función f (int $ param) {}
- función f (float $ param) {}
- función f (cadena $ param) {}
- función f (self $ param) {}
- función f (llamable $ param) {}
- función f (array $ param) {}
- función f (? tipo_nombre $ param) {}
- función f (): tipo_nombre {}
- función f (): vacío {}
- función f ():? type_name {}
Observaciones
Las sugerencias de tipo o las declaraciones de tipo son una práctica de programación defensiva que garantiza que los parámetros de una función sean de un tipo específico. Esto es particularmente útil cuando se trata de una sugerencia de tipo para una interfaz porque permite que la función garantice que un parámetro proporcionado tendrá los mismos métodos que se requieren en la interfaz.
Pasar el tipo incorrecto a una función de tipo insinuado provocará un error fatal:
Fatal error: no detectada TypeError: Argumento X pasa a foo () debe ser del tipo RequiredType, ProvidedType dado
Tipografía de tipos escalares, matrices y callables.
El soporte para los tipos de parámetros de matriz de sugerencias (y valores de retorno después de PHP 7.1) se agregó en PHP 5.1 con la array
palabras clave. Cualquier matriz de cualquier dimensión y tipo, así como las matrices vacías, son valores válidos.
El soporte para tipografías de insinuación de tipo se agregó en PHP 5.4. Cualquier valor que is_callable()
es válido para los parámetros y devuelve los valores indicados como callable
, es decir, objetos de Closure
, cadenas de nombre de función y array(class_name|object, method_name)
.
Si se produce un error tipográfico en el nombre de la función de modo que no sea is_callable()
, se mostrará un mensaje de error menos obvio:
Error grave: error de tipo no detectado: el argumento 1 que se pasa a foo () debe ser del tipo que se puede llamar, cadena / matriz dada
function foo(callable $c) {}
foo("count"); // valid
foo("Phar::running"); // valid
foo(["Phar", "running"); // valid
foo([new ReflectionClass("stdClass"), "getName"]); // valid
foo(function() {}); // valid
foo("no_such_function"); // callable expected, string given
Los métodos no estáticos también se pueden pasar como reclamables en formato estático, lo que resulta en una advertencia de desaprobación y un error de nivel E_STRICT en PHP 7 y 5, respectivamente.
Método de visibilidad se tiene en cuenta. Si el contexto del método con el parámetro callable
no tiene acceso al que se puede llamar proporcionado, terminará como si el método no existiera.
class Foo{
private static function f(){
echo "Good" . PHP_EOL;
}
public static function r(callable $c){
$c();
}
}
function r(callable $c){}
Foo::r(["Foo", "f"]);
r(["Foo", "f"]);
Salida:
Error grave: error de tipo no detectado: el argumento 1 pasado a r () debe ser invocable, se debe dar una matriz
El soporte para tipos de escalador de sugerencias de tipo se agregó en PHP 7. Esto significa que obtenemos soporte de sugerencias de tipo para boolean
s, integer
, float
sy string
s.
<?php
function add(int $a, int $b) {
return $a + $b;
}
var_dump(add(1, 2)); // Outputs "int(3)"
De forma predeterminada, PHP intentará convertir cualquier argumento proporcionado para que coincida con su sugerencia de tipo. Cambiar la llamada para add(1.5, 2)
da exactamente el mismo resultado, ya que el float 1.5
fue lanzado a int
por PHP.
Para detener este comportamiento, uno debe agregar declare(strict_types=1);
a la parte superior de cada archivo fuente PHP que lo requiera.
<?php
declare(strict_types=1);
function add(int $a, int $b) {
return $a + $b;
}
var_dump(add(1.5, 2));
El script anterior ahora produce un error fatal:
Error grave: error de tipo no detectado: el argumento 1 que se pasa a add () debe ser del tipo entero, flotante dado
Una excepción: tipos especiales
Algunas funciones de PHP pueden devolver un valor de tipo resource
. Como este no es un tipo escalar, sino un tipo especial, no es posible escribirlo.
Como ejemplo, curl_init()
devolverá un resource
, así como fopen()
. Por supuesto, esos dos recursos no son compatibles entre sí. Debido a eso, PHP 7 siempre lanzará el siguiente TypeError cuando escriba resource
sugerencias explícitamente:
TypeError: el argumento 1 pasado a sample () debe ser una instancia de recurso, recurso dado
Tipo de sugerencia de objetos genéricos
Dado que los objetos PHP no se heredan de ninguna clase base (incluyendo stdClass
), no hay soporte para el tipo de insinuación de un tipo de objeto genérico.
Por ejemplo, lo de abajo no funcionará.
<?php
function doSomething(object $obj) {
return $obj;
}
class ClassOne {}
class ClassTwo {}
$classOne= new ClassOne();
$classTwo= new ClassTwo();
doSomething($classOne);
doSomething($classTwo);
Y lanzará un error fatal:
Error grave: error de tipo no detectado: el argumento 1 pasado a doSomething () debe ser una instancia de objeto, instancia de OperationOne dada
Una solución a esto es declarar una interfaz degenerada que no define métodos y hacer que todos sus objetos implementen esta interfaz.
<?php
interface Object {}
function doSomething(Object $obj) {
return $obj;
}
class ClassOne implements Object {}
class ClassTwo implements Object {}
$classOne = new ClassOne();
$classTwo = new ClassTwo();
doSomething($classOne);
doSomething($classTwo);
Tipo de insinuación de clases e interfaces
Se agregaron sugerencias de tipo para clases e interfaces en PHP 5.
Indicación de tipo de clase
<?php
class Student
{
public $name = 'Chris';
}
class School
{
public $name = 'University of Edinburgh';
}
function enroll(Student $student, School $school)
{
echo $student->name . ' is being enrolled at ' . $school->name;
}
$student = new Student();
$school = new School();
enroll($student, $school);
Los resultados del script anterior:
Chris está siendo matriculado en la Universidad de Edimburgo
Sugerencia de tipo de interfaz
<?php
interface Enrollable {};
interface Attendable {};
class Chris implements Enrollable
{
public $name = 'Chris';
}
class UniversityOfEdinburgh implements Attendable
{
public $name = 'University of Edinburgh';
}
function enroll(Enrollable $enrollee, Attendable $premises)
{
echo $enrollee->name . ' is being enrolled at ' . $premises->name;
}
$chris = new Chris();
$edinburgh = new UniversityOfEdinburgh();
enroll($chris, $edinburgh);
El ejemplo anterior produce lo mismo que antes:
Chris está siendo matriculado en la Universidad de Edimburgo
Sugerencias de auto tipo
La palabra clave self
puede usarse como una sugerencia de tipo para indicar que el valor debe ser una instancia de la clase que declara el método.
Tipo de sugerencia de no retorno (nulo)
En PHP 7.1, el tipo de retorno void
fue agregado. Si bien PHP no tiene un valor de void
real, en general se entiende en todos los lenguajes de programación que una función que no devuelve nada devuelve un void
. Esto no debe confundirse con devolver null
, ya que null
es un valor que se puede devolver.
function lacks_return(): void {
// valid
}
Tenga en cuenta que si declara un retorno void
, no puede devolver ningún valor o obtendrá un error fatal:
function should_return_nothing(): void {
return null; // Fatal error: A void function must not return a value
}
Sin embargo, es válido usar return para salir de la función:
function returns_nothing(): void {
return; // valid
}
Consejos de tipo anulable
Parámetros
Se agregó una sugerencia de tipo anulable en PHP 7.1 usando el ?
operador antes de la sugerencia de tipo.
function f(?string $a) {}
function g(string $a) {}
f(null); // valid
g(null); // TypeError: Argument 1 passed to g() must be of the type string, null given
Antes de PHP 7.1, si un parámetro tiene una sugerencia de tipo, debe declarar un valor predeterminado null
para aceptar valores nulos.
function f(string $a = null) {}
function g(string $a) {}
f(null); // valid
g(null); // TypeError: Argument 1 passed to g() must be of the type string, null given
Valores de retorno
En PHP 7.0, las funciones con un tipo de retorno no deben devolver nulo.
En PHP 7.1, las funciones pueden declarar una sugerencia de tipo de retorno anulable. Sin embargo, la función todavía debe devolver null, no void (sin / declaraciones de retorno vacías).
function f() : ?string {
return null;
}
function g() : ?string {}
function h() : ?string {}
f(); // OK
g(); // TypeError: Return value of g() must be of the type string or null, none returned
h(); // TypeError: Return value of h() must be of the type string or null, none returned