Я что-то упустил или нет поддержки универсального типа объекта, намекающего на PHP 5.x?
Мне очень странно, что намеки на массивы поддерживаются, в то время как намекающие объекты не являются, по крайней мере, не из коробки.
Я хотел бы иметь что-то вроде этого:
function foo(object $o)
Так же, как у нас:
function foo(array $o)
Пример возможного использования: методы класса сбора объектов.
Обходной путь: используя интерфейс «Объект», реализованный всеми классами или распространяющий все классы из общего класса «Объект» и записывая что-то вроде этого:
function foo(Object $o)
Ну, это просто не мило.
Использование stdClass
в качестве подсказки типа не работает:
Допустимая фатальная ошибка: аргумент 1, переданный в c :: add (), должен быть экземпляром stdClass, экземпляр b задан
Так как тип 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)); }
Здесь вам понадобится.