Подтвердить что ты не робот

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 заданного

4b9b3361

Ответ 1

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

Ответ 2

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

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

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

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

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

(Не означает, что синтаксис действителен)

Ответ 3

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

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

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

Ответ 4

Вы не можете просто сказать "объект" при типе casting object... вы должны определить, какой объект 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';
}

Ответ 5

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

interface Object {

   // leave blank

}

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

class SomeBase implements Object {

   // your implementation

}

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

function myFunc (Object $obj);

myFunc($someBase);

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

Ответ 6

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

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

например.

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.

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

Ответ 7

Объекты в 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

Ответ 8

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

Ответ 9

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

    return unserialize(serialize($source));
}

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