1

Object to ID Data Transformer を作成しました。これは、「ドキュメント」フォーム タイプを使用する代わりに、ドキュメントの ID を入力できるカスタム ObjectIdType の一部です。これは、MongoDB で便利です (1 億のドキュメントから選択できる場合)。

Data Transformer は ID に対してクエリを実行し、オブジェクトを返します。オブジェクトが見つからない場合は、null を返します。問題は、null が許容値である場合とそうでない場合があることです。

NotNull バリデーターを追加しても、次のエラーが発生します -

Catchable Fatal Error: Character::setPlayer() に渡される引数 1 は Document\Player のインスタンスでなければなりません。

したがって、検証の失敗に関係なく、セッターを呼び出しています。トランスフォーマー内で TransformationFailedException をスローすることでこれを修正しましたが、これは悪い考えのようです。検証に Data Transformer を使用するべきではありません。

トランスのコードは以下です。私が望むのは、バリデーターを正しい場所に配置し、セッターを傍受して呼び出されないようにすることです。一般的に、これは少しコードのにおいがするように思えます。他の人がこの問題をどのように解決したか知りたいです。

class ObjectToIdTransformer implements DataTransformerInterface
{
    private $objectLocator;
    private $objectName;
    private $optional;

    /**
     * @param ObjectLocator $objectLocator
     * @param $objectName
     */
    public function __construct(ObjectLocator $objectLocator, $objectName, $optional = false)
    {
        $this->objectLocator = $objectLocator;
        $this->objectName    = $objectName;
        $this->optional      = $optional;
    }

    /**
     * {@inheritdoc}
     */
    public function transform($value)
    {
        if (null === $value) {
            return null;
        }

        if (!$value instanceof BaseObject) {
            throw new TransformationFailedException("transform() expects an instance of BaseObject.");
        }

        return $value->getId();
    }

    /**
     * {@inheritdoc}
     */
    public function reverseTransform($value)
    {
        if (null === $value) {
            return null;
        }

        $repo = $this->objectLocator->getRepository($this->objectName);
        $object = $repo->find($value);

        if (!$this->optional && !$object) {
            throw new TransformationFailedException("This is probably a bad place to validate data.");
        }

        return $object;
    }
}
4

1 に答える 1

3

実際、これは非常に非直感的な PHP の癖です。Java のような他の (論理的で、直感的で、まともな) 言語から来た人にとっては特にそうです。nullタイプヒンティングされたパラメーターに引数を渡せるようにしたい場合は、デフォルト値をnull次のように設定する必要があります。

public function setPlayer(Player $player = null)
{
    // ...
}

ええ、ここでいくつかの一貫性について話してください...

于 2013-09-16T17:04:06.893 に答える