¿Hay alguna manera de agregar más de un tipo de sugerencia a un método? Por ejemplo, foo (param) debe recibir una instancia de cadena OR bar O baz.¿Es posible especificar más de una sugerencia de tipo para un parámetro?
Respuesta
Type hinting sólo permite un atisbo por parámetro (y también, la insinuación es necesario que haya array
o un nombre de clase, no se puede hacer alusión string
), pero se puede hacer esto mediante la comprobación del tipo del parámetro dentro de su función , utilizando get_class
:
function foo($param)
{
if (!(is_string($param) || in_array(get_class($param), array("Bar", "Baz")))
{
// invalid type for $param!
}
}
incluso podría utilizar trigger_error
tener que fallar con un error de PHP (como sería si un tipo de pista no) si querías.
Sugeriría arrojar una 'InvalidArgumentException', para que al menos pueda intentar recuperarse del error ... – ircmaxell
@ircmaxell Solo estaba demostrando cómo el OP * podría * replicar cómo funcionan las sugerencias de tipo. –
No estoy diciendo que no 'trigger_error'. Todo depende de tu estilo (y no hay nada de malo con el uso de 'trigger_error'). Prefiero las excepciones, entonces uso 'InvalidArgumentException'. Si su objetivo es imitar sugerencias de tipo, entonces, por supuesto, desencadenar un error fatal ... – ircmaxell
Eso no es posible hacer cumplir (excepto dentro del método). Solo puede proporcionar una sugerencia de tipo único, y solo a objetos/interfaces y matrices (desde PHP 5.1).
Puede/sin embargo debe documentar en su método, es decir:
/**
* @param string|Bar|Baz $param1
*/
function foo($param1);
+1 para documentación – Hannes
Este es un uso de interfaces. Si usted quiere estar seguro de que el objeto tiene un método ->foobar($baz)
, se puede esperar una interfaz:
interface iFooBar {
public function foobar($baz);
}
class Foo implements iFooBar {
public function foobar($baz) { echo $baz; }
}
class Bar implements iFooBar {
public function foobar($baz) { print_r($baz); }
}
function doSomething(iFooBar $foo) {
$foo->foobar('something');
}
Entonces, al llamar, éstos funcionarán:
doSomething(new Foo());
doSomething(new Bar());
Estos no:
doSomething(new StdClass());
doSomething('testing');
¡Bastante bien! También hay tipos SPL (experimentales): http://pl.php.net/manual/en/book.spl-types.php – joao
de la misma manera que lo había hecho. – ITroubs
@joao: SPLTypes no funcionará en 5.3 (usan llamadas obsoletas c). Además, la última actualización fue en 2008, por lo que es bastante seguro decir que no es actual ... – ircmaxell
Pregunta fantástica. Se aplica tanto a la documentación IDE como a PHP 5 Type Hinting. Tienes que recordar que en OO polymorphism es tu amigo.
Si crea una clase base y la amplía, su sugerencia de tipo será la clase base ... toda la clase extendida funcionará. Vea el ejemplo a continuación.
//
$test = new DUITest();
// Calls below will work because of polymorphism
echo $test->test(new Molecule()) . '<br/>';
echo $test->test(new Vodka()) . '<br/>';
echo $test->test(new Driver()) . '<br/>';
echo $test->test(new Car()) . '<br/>';
// Will not work because different data type
echo $test->test(new Pig()) . '<br/>';
echo $test->test(new Cop()) . '<br/>';
echo $test->test('test') . '<br/>';
echo $test->test(array()) . '<br/>';
/**
* Class to test
*/
class DUITest {
public function __construct() {
;
}
/**
* Using type-hinting
*
* See below link for more information
* @link http://www.php.net/manual/en/language.oop5.typehinting.php
*
* @param Molecule|Car|Driver|Vodka $obj
*/
public function test(Molecule $obj) {
echo $obj;
}
}
/**
* Base Class
*/
class Molecule {
public function __construct() {}
/**
* Outputs name of class of current object
* @return <type>
*/
public function __toString() {
return get_class($this);
}
}
class Car extends Molecule {}
class Driver extends Molecule {}
class Vodka extends Molecule {}
class Pig {}
class Cop extends Pig{}
En este momento no hay soporte para múltiples tipos explícitos. Debe confiar en la documentación y en el sistema de tipo dinámico de PHP.
Sin embargo, tengo una propuesta casi incompleta para union types. Tiene como objetivo 7.NEXT (en el momento de escribir esto, esto es 7.1) u 8 (lo que ocurra primero).
Aquí es un simple ejemplo de algo que creo que sería muy valiosa: array | Traversable
:
function map(callable $fn, array|Traversable $input) {
foreach ($input as $key => $value) {
yield $key => $fn($value);
}
}
Por desgracia, la RFC no pasó; sin embargo, para el tipo específico array|Traversable
ahora existe un tipo iterable
que es exactamente eso.
- 1. ¿Hay una sugerencia de tipo PHPDoc para un parámetro booleano?
- 2. ¿Es posible especificar una restricción genérica para que un parámetro de tipo sea convertible DE OTRO tipo?
- 3. ¿Es posible especificar un std :: vector vacío como parámetro predeterminado?
- 4. ¿Es posible en Scala obligar al llamante a especificar un parámetro de tipo para un método polimórfico?
- 5. Tipo anulable como un parámetro genérico posible?
- 6. ¿Es posible especificar el formato de visualización para un dijit.form.DateTextBox
- 7. Clojure tipo sugerencia para Map.Entry
- 8. especificar el tipo de parámetro de función, pero no variables
- 9. ¿Es posible especificar el tipo de devolución de una función anónima en Scala?
- 10. ¿Es posible especificar la posición de un Toast?
- 11. ¿Se puede especificar en una restricción de tipo genérico que debe implementar un tipo genérico?
- 12. ¿Es posible restringir un parámetro de tipo de método genérico de C# como "asignable desde" el parámetro de tipo de clase que contiene?
- 13. ¿Es posible especificar el registrador para ant dentro de build.xml?
- 14. ¿Es posible especificar opciones de formato para to_yaml en ruby?
- 15. ¿Cuál es la forma más elegante en Ruby para eliminar un parámetro de una URL?
- 16. ¿Es posible restringir un parámetro de tipo genérico a String O Array
- 17. ¿Es posible anular un campo de tipo?
- 18. Cómo especificar el parámetro para el método de extensión de tipo de lista genérico en C#
- 19. ¿Es posible especificar una función de temporización personalizada para las transiciones de CSS?
- 20. Tipo Sugerencia para múltiples interfaces no relacionadas
- 21. Upcasting con un parámetro de tipo genérico
- 22. ¿Es posible especificar restricciones de límite superior e inferior en los parámetros de tipo en Java?
- 23. ¿Cómo especificar el parámetro IN que como tipo de datos Oracle de tipo TABLE?
- 24. Tipo de parámetro Tipo de
- 25. ¿Cómo verificar si un parámetro de tipo genérico es anulable?
- 26. ¿Es posible especificar un nombre de clase para Spring Framework en un archivo externo?
- 27. Es posible especificar dos páginas raíz en Rails (una para usuario anónimo otra para usuario conectado)
- 28. ¿Es posible guardar un Tipo (usando "typeof()") en una enumeración?
- 29. CSS dinámico con un parámetro de variable? (¿es posible?)
- 30. ¿Es posible especificar formatos de ubicación con capacidad de búsqueda para un diseño MVC Razor?
La sugerencia de tipo no admite escalas de cadena; solo señalando eso. – Qix
@Qix Ahora deberíamos mencionar que [PHP admite insinuaciones de tipo escalar a partir de PHP 7.0.0] (http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration). – faintsignal