【问题标题】:How to change value of field in FOSRestBundle/JMS Serializer?如何更改 FOSRestBundle/JMS 序列化程序中的字段值?
【发布时间】:2013-09-05 12:32:44
【问题描述】:

我在实体中有“图像”字段。但取决于行动,我想显示的不是原始图像,而是图像的预览(我在 LiipImagineBundle 中制作)。我能想象的一种解决方案:

public function cgetAction(Request $request)
{
    $events = $this->container->get('gc.event_manager')->getEvents();
    foreach ($events as &$event) {
        $previewURL = $this->getPreview($event->getPhoto());
        $event->setPhoto($previewURL);
    }
    $event = false;

    return array(
        'events' => $events,
    );
}

但我不喜欢它,因为如果一个实体有很深的子实体,代码会很混乱。

如何正确做?

【问题讨论】:

    标签: php symfony fosrestbundle jmsserializerbundle


    【解决方案1】:

    在使用 LiipImagine 和 FOSRest 时想要通过 API 返回绝对 url 时的常见问题

    将 EE\TYSBundle 改成你自己的,代码取自https://github.com/EE/TellYourStoryBundle/tree/develop

    带有注入缓存管理器的 JMSSerializer 处理程序服务以获取正确的前缀

    ee_tys.serializer.filename_handler:
        class: EE\TYSBundle\Handler\FilenameHandler
        arguments:
            - "@liip_imagine.cache.manager"
        tags:
            - { name: 'jms_serializer.handler', type: Filename, format: json}
    

    自定义文件名类型的处理程序

    EE\TYSBundle\Handler\FilenameHandler.php

    <?php
    
    namespace EE\TYSBundle\Handler;
    
    use EE\TYSBundle\Entity\Filename;
    use JMS\Serializer\GraphNavigator;
    use JMS\Serializer\Handler\SubscribingHandlerInterface;
    use JMS\Serializer\VisitorInterface;
    use Liip\ImagineBundle\Imagine\Cache\CacheManager;
    
    class FilenameHandler implements SubscribingHandlerInterface
    {
    
        function __construct(CacheManager $manager)
        {
            $this->manager = $manager;
        }
    
    
        public static function getSubscribingMethods()
        {
            return array(
                array(
                    'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
                    'format' => 'json',
                    'type' => 'Filename',
                    'method' => 'serializeFilenameToJson',
                ),
            );
        }
    
        public function serializeFilenameToJson(VisitorInterface $visitor, Filename $filename, array $type)
        {
            // `tile` is a name of Imagine filter you want to apply
            return $this->manager->getBrowserPath($filename, 'tile', true);
        }
    }
    

    EE\TYSBundle\Entity\文件名

    <?php
    
    namespace EE\TYSBundle\Entity;
    
    /**
     * Class Filename
     * @package EE\TYSBundle\Entity
     */
    class Filename {
    
        /**
         * @var string
         */
        public $name;
    
        /**
         * @var string
         */
        public $extension;
    
        public function __construct($filename)
        {
            $parts = explode(".", $filename);
    
            $this->setName($parts[0]);
    
            $this->setExtension($parts[1]);
    
        }
    
        /**
         * @param mixed $extension
         * @return Media
         */
        public function setExtension($extension)
        {
            $this->extension = $extension;
    
            return $this;
        }
    
        /**
         * @return mixed
         */
        public function getExtension()
        {
            return $this->extension;
        }
    
        /**
         * @param mixed $name
         * @return Filename
         */
        public function setName($name)
        {
            $this->name = $name;
        }
    
        /**
         * @return mixed
         */
        public function getName()
        {
            return $this->name;
        }
    
        /**
         * @return string filename
         */
        public function __toString()
        {
            return join(".", array($this->name, $this->extension));
        }
    
    }
    

    自定义文件名类型的使用

    /**
     * @var string|null
     *
     * @ORM\Column(name="background_filename", type="string", length=255, nullable=true)
     *
     * @Serializer\Expose
     * @Serializer\Type("Filename")
     * @Serializer\SerializedName("background_uri")
     */
    private $backgroundFilename;
    

    从现在开始,您将获得带有绝对网址的 background_uri 到您的预览图片

    【讨论】:

      【解决方案2】:

      一种可能的解决方案是定义Handler

      处理程序允许您更改序列化或反序列化 单一类型/格式组合的过程。

      类似

      class ImageHandler
      {
          public function serialize(VisitorInterface $visitor, \FQCN\Image $image, array $type, Context $context)
          {
              // do some stuff
      
              return ...;
          }
      }
      

      并在services.yml注册

      serializer.handler.image_handler:
          class: FQCN\Handler\ImageHandler
          arguments: []
          tags:
              - { name: "jms_serializer.handler", type: FQCN\AdvertImage, format: json, method: serialize }
      

      【讨论】:

      • 非常感谢您提供如此详细的回答!
      【解决方案3】:

      如果我很好理解你的问题,你需要在序列化之前更改正确的值,我认为手册可以帮助@Accessor

      class User
      {
          private $id;
      
          /** @Accessor(getter="getTrimmedName",setter="setName") */
          private $name;
      
          // ...
          public function getTrimmedName()
          {
              return trim($this->name);
          }
      
          public function setName($name)
          {
              $this->name = $name;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-02-12
        • 2017-09-01
        • 1970-01-01
        • 2015-09-05
        • 2020-08-17
        • 1970-01-01
        • 1970-01-01
        • 2012-02-15
        • 1970-01-01
        相关资源
        最近更新 更多