簡體   English   中英

串行器Symfony上的回調

[英]Callback on serializer Symfony

我正在運行Symfony 2.7,我正在嘗試輸出一個對象(Doctrine實體)作為JSON。

當我正在標准化對象時,我想轉換它的一些值。 為此,我在文檔中找到了“setCallbacks”方法,但我對如何將其應用於我的案例感到困惑。

有沒有辦法在調用Symfonys序列化服務器時設置的規范化器上調用“setCallbacks”方法?

這是我想要實現的一個簡短示例:

//ExampleController.php

public function getJSONOrderByIdAction($id) {
    $serializer = $this->get('serializer');
    $normalizer = $serializer->getNormalizer(); // <- This is what I'm unable to do

    $dateTimeToString = function ($dateTime) {
        return $dateTime instanceof \DateTime ? $dateTime->format(\DateTime::ISO8601) : '';
    };

    $normalizer->setCallbacks(['time' => $dateTimeToString]);


    $order = $this->getDoctrine()->find("AppBundle:Order", $id);

    return new JsonResponse(["order" => $serializer->normalize($order, null, ["groups" => ["public"]])]);
}

我知道大多數人已經切換到JMS序列化器。 看起來好像內置的序列化程序應該能夠處理我想要實現的內容。

默認的Serializer服務是在依賴注入階段創建的,而Serializer接口不允許編輯規范器的(完整)檢索。

我想你在這里有(至少)三種選擇:

  1. 將自定義規范化程序添加到默認的Serializer服務
  2. 將NormalizableInterface添加到您的實體
  3. 按照您的嘗試創建一個新的Serializer服務(或文檔建議的本地對象)。

我認為在你的場景中,情況1是首選(因為2變得很無聊很快)。

我會做這樣的事情; 首先創建一個自定義規范器

<?php
namespace AppBundle; 

class DateTimeNormalizer extends SerializerAwareNormalizer implements NormalizerInterface, DenormalizerInterface
{
    /**
     * {@inheritdoc}
     */
    public function normalize($object, $format = null, array $context = array())
    {
        return $object->format(\DateTime::ISO8601);
    }

    /**
     * {@inheritdoc}
     */
    public function denormalize($data, $class, $format = null, array $context = array())
    {
        return new $class($data);
    }

    /**
     * Checks if the given class is a DateTime.
     *
     * @param mixed  $data   Data to normalize.
     * @param string $format The format being (de-)serialized from or into.
     *
     * @return bool
     */
    public function supportsNormalization($data, $format = null)
    {
        return $data instanceof \DateTime;
    }

    /**
     * Checks if the given class is a DateTime.
     *
     * @param mixed  $data   Data to denormalize from.
     * @param string $type   The class to which the data should be denormalized.
     * @param string $format The format being deserialized from.
     *
     * @return bool
     */
    public function supportsDenormalization($data, $type, $format = null)
    {
        $class = new \ReflectionClass($type);

        return $class->isSubclassOf('\DateTime');
    }
}

然后將其注冊到您的服務:

# app/config/services.yml
services:
    datetime_normalizer:
        class: AppBundle\DateTimeNormalizer
        tags:
            - { name: serializer.normalizer }

我自己的解決方案

根據giosh94mhz的建議,我嘗試切換到JMS Serializer但最終回到Symfonys序列化器。

JMS Serializer提出了它自己的問題,在搜索那些我偶然發現Thomas Jarrand博客文章的答案時,他們在Symfony中解釋了如何制作實現自己的規范化程序。

在我看來,你似乎試圖使事情過於復雜。 這是我在需要將實體序列化為JSON時采用的方法:

PHP 2.5及更高版本允許您在對象上實現jsonSerialize方法,並直接在對象上調用json_encode

如果您仍在使用PHP 2.4,則只需在對象上手動調用jsonSerialize()

例如:

/**
 * @ORM\Entity
 */
class MyEntity {
    ...
    public function jsonSerialize() {
        $data = array("foo" => $this->bar());
        // add other data here ...
        return $data
    }
}

然后在調用代碼時:

// for PHP 2.5 and up:
$normalized = json_encode($myEntityInstance);

// for PHP 2.4 and below
$normalized = json_encode($myEntityInstance->jsonSerialize());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM