PHP Type Hinting: поддерживается массив, объект NOT?

Я что-то упустил или нет поддержки универсального типа объекта, намекающего на PHP 5.x?

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

Я хотел бы иметь что-то вроде этого:

function foo(object $o) 

Так же, как у нас:

 function foo(array $o) 

Пример возможного использования: методы класса сбора объектов.

Обходной путь: используя интерфейс «Объект», реализованный всеми классами или распространяющий все классы из общего класса «Объект» и записывая что-то вроде этого:

 function foo(Object $o) 

Ну, это просто не мило.

Использование stdClass в качестве подсказки типа не работает:

Допустимая фатальная ошибка: аргумент 1, переданный в c :: add (), должен быть экземпляром stdClass, экземпляр b задан

Related of "PHP Type Hinting: поддерживается массив, объект NOT?"

Так как тип hinting должен сделать клиентский код адаптированным к вашему API, ваше решение с принимающими интерфейсами кажется почти правильным.

Посмотрите на это следующим образом: yourMethod(array $input) предоставляет yourMethod() для использования, тем самым вы точно знаете , какие родные функции применяются и могут использоваться yourMethod() .

Если вы укажете свой метод, например: yourSecondMethod(yourInterface $input) вы также узнаете, какие методы могут быть применены к $input поскольку вы знаете / можете искать, какой набор правил, который сопровождает интерфейс yourInterface .

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

 function foo(Object $o) { return $o->thisMethodMayOrMayNotExist(); } 

(Не подразумевая, что синтаксис действителен)

Нет, это невозможно. Я ничего не пропустил.

Я чувствую твою боль, но я тоже не могу найти способ сделать это.

Несмотря на то, что сказал ряд других плакатов, имеет смысл хотеть намек типа «Объект»; они просто не рассматривали сценарий, который этого требует.

Я пытаюсь выполнить некоторую работу с API отражения, и из-за этого мне все равно, какой класс передан моей функции. Мне все равно, что это объект. Я не хочу int, float, строку или массив. Я хочу объект. Учитывая, что отражение теперь является частью PHP, определенно имеет смысл намекать на тип объекта.

Вы не можете просто сказать «объект», когда вы набрасываете объект … вы должны определить объект WHICH, который вы ожидаете.

От: http://php.net/manual/en/language.oop5.typehinting.php

 class MyClass { /** * A test function * * First parameter must be an object of type OtherClass */ public function test(OtherClass $otherclass) { echo $otherclass->var; } /** * Another test function * * First parameter must be an array */ public function test_array(array $input_array) { print_r($input_array); } } // Another example class class OtherClass { public $var = 'Hello World'; } 

Лучший способ обеспечить это – создать вырожденный интерфейс под названием Object . Вырожденный интерфейс означает, что он не имеет определенных методов.

 interface Object { // leave blank } 

Затем в базовых классах вы можете реализовать Object .

 class SomeBase implements Object { // your implementation } 

Теперь вы можете вызывать свою функцию так, как вы хотели

 function myFunc (Object $obj); myFunc($someBase); 

Если вы передадите любой объект, который наследуется от вашего интерфейса Object , этот тип подсказки пройдет. Если вы передадите массив, int, строку и т. Д., Подсказка типа не будет выполнена.

Вот еще один пример, где это необходимо …

Я создал класс для реализации блокировки записей. Записи являются одним из нескольких типов объектов. Класс блокировки имеет несколько методов, для которых требуется объект (тот, который должен быть заблокирован), но не заботятся о том, какой тип объекта он имеет.

Например

 public static function lockRecord($record, User $user, $timeout=null) { if(!is_object($record)) throw new \InvalidException("Argument 1 must be an object."); $lock=new Lock(); $lock->setRecord($record); $lock->setUser($user); $lock->setTimeout($timeout); $lock->activate(); return($lock); } 

Вы увидите, что мое решение заключалось в использовании is_object () и генерировании исключения, но я бы скорее сделал это с помощью типа hinting.

Хорошо, так что не конец света, но я думаю, что это позор.

Объекты в php не являются подклассами какого-либо StdClass или Object, как в других языках ООП. Таким образом, тип типа не намекает на объект. Но я вижу вашу точку зрения, потому что иногда вы хотите удостовериться, что объект передан, поэтому я предполагаю, что единственный способ – повысить проблему вручную.

 public function yourFunction($object){ if(is_object($object)){ //TODO: do something }else{ throw new InvalidArgumentException; } } 

Начиная с php 5.4 существует также тип подсказки. См. Руководство по php http://php.net/manual/en/language.types.callable.php

Почему вы хотите намекнуть object если вы можете вместо этого называть фактическое имя класса – это было бы гораздо более полезным. Также помните, что вы не можете намекать int , float , bool , string или resource .

 public static function cloneObject($source) { if ($source === null) { return null; } return unserialize(serialize($source)); } 

Здесь вам понадобится.