Подсказка типа PHP: массив поддерживается, объект НЕ? - PullRequest
23 голосов
/ 10 октября 2009

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

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

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

function foo(object $o)

Так же, как мы имеем:

function foo(array $o)

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

Обходной путь: используя интерфейс "Object", реализованный всеми классами, или расширяя все классы из универсального класса "Object", и напишите что-то вроде этого:

function foo(Object $o)

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

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

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

Ответы [ 9 ]

7 голосов
/ 10 октября 2009

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

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

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

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

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

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

6 голосов
/ 18 апреля 2010

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

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

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

6 голосов
/ 20 октября 2009

Нет, это не может быть сделано. Я ничего не пропустил.

4 голосов
/ 27 августа 2010

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

От: 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';
}
3 голосов
/ 28 апреля 2014

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

interface Object {

   // leave blank

}

Тогда в ваших базовых классах вы можете реализовать Object.

class SomeBase implements Object {

   // your implementation

}

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

function myFunc (Object $obj);

myFunc($someBase);

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

2 голосов
/ 15 августа 2010

Вот еще один пример, где это требуется ...

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

* 1005 Е.Г. *

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 () и выдавать исключение, но я бы предпочел сделать это с помощью подсказок типов.

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

1 голос
/ 05 июня 2015

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

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

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

0 голосов
/ 02 августа 2012
public static function cloneObject($source)
{
    if ($source === null)
    {
        return null;
    }

    return unserialize(serialize($source));
}

Это то место, где оно вам понадобится.

0 голосов
/ 20 октября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...