Объявление типа PHP 7 для сущностей Symfony - PullRequest
0 голосов
/ 27 апреля 2018

В PHP 7 объявления типов могут использоваться для создания исключения, если предоставленный параметр имеет тип, отличный от ожидаемого. Может ли это использоваться, чтобы разрешить только сущности Symfony?

/**
 * @param User|MyOtherEntity $entity
 */
public function serialize(TYPEHINTFORENTITY $entity)
{
    $json = json_decode($this->serializer->serialize(
        $entity,
        'json'
    ), true);

    return $json;
}

public function deserialize($json, string $class): TYPEHINTFORENTITY
{
    $entity = $this->serializer->deserialize(
        json_encode($json),
        'MyBundle\Entity\' . $class,
        'json',
        DeserializationContext::create()->setGroups(
            array('group')
        )
    );

    return $entity;
}

Если я использую одну и ту же функцию для сериализации разных сущностей, я не могу использовать

public function serialize(User $entity)

потому что это не позволило бы сериализовать сущности MyOtherEntity.

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Объекты не являются «специальными» объектами с точки зрения PHP. Вы можете подойти к этому двумя способами

  1. Определите общий интерфейс (возможно, без каких-либо методов), напишите его и пусть все сущности реализуют это
  2. Используйте тип object для ввода текста, который был введен в PHP 7.2

С первым решением вы в безопасности, если кто-то пытается передать что-то, что не является реализацией этого интерфейса . Конечно, вы должны помнить, что каждый раз, когда в кодовой базе создается новый объект, он должен реализовывать этот интерфейс.

Со вторым решением вы не в безопасности, как в первом пункте, но при этом уверены, что все, что передано, не является скалярным или примитивным типом

С первым решением вы в итоге напишите что-то вроде

interface Entity { }
class FooEntity implements Entity { }
class BarEntity implements Entity { }
...
public function serialize(Entity $entity) { }

Со вторым решением просто

public function serialize(object $entity) { }

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

Редактировать

Я видел другие ответы, предлагающие расширить, а не реализовывать интерфейс: пожалуйста, не расширяйте его из суперкласса, если это не является строго необходимым, поскольку классы PHP могут расширяться только из одного класса, тогда как они могут реализовывать несколько интерфейсов. Интерфейс - это то, что нужно, если вам нужно первое решение, иначе у вас будут проблемы, если вам понадобится расширение real , наложенное моделью

0 голосов
/ 27 апреля 2018

Лучший способ использовать подсказки типов для различных типов объектов - это использовать общий Интерфейс , реализованный всеми объектами, который должен быть действительным для вашей функции.

Например, в вашем случае я бы использовал

public function serialize(\Serializable $entity)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...