jlm/serializer-expression

此包已被废弃,不再维护。未建议替代包。

允许您通过使用Symfony表达式语言在运行时通过表达式排除字段

dev-master / 0.1.x-dev 2016-01-16 04:00 UTC

This package is not auto-updated.

Last update: 2021-04-26 09:58:24 UTC


README

Build Status Coverage Status Total Downloads Latest Stable Version

#JLMSerializerExpression

这个库为Johannes Schmitt的Serializer库增加了表达式语言支持,以便在运行时通过@excludeIf注解根据表达式隐藏单个字段。

安装

您可以通过将以下内容添加到您的composer.json文件中来包含此库

"require": {
    # ..
    "jlm/serializer-expression": "dev-master"
    # ..
}

使用方法

此库提供了一种排除策略,必须进行配置然后添加到您的序列化上下文中。使用此序列化上下文,在序列化对象时,会检查对象上的@excludeIf注解,然后在运行时处理这些注解。

排除策略有两个依赖项,一个是Johannes Schmitt的Metadata库中的JMS\Metadata\MetadataFactory实例,另一个是必须扩展以提供所需功能的Symfony\Component\ExpressionLanguage\ExpressionLanguage实例。

为您的对象添加注解

@excludeIf注解接受一个表达式,该表达式必须由您传递给排除策略的ExpressionLanguage实例进行处理。在下面的示例中,我们使用了一个在下面的创建表达式语言部分创建的虚拟hasAccessIfTrue表达式函数。它自然是没有用的。创建有用的表达式语言是特定于应用程序的,由您来完成。要查看Symfony应用程序的示例,请查看此库的Symfony包

<?php

use JLM\SerializerExpression\Annotation\ExcludeIf;

class User
{
    /**
     * @ExcludeIf("hasAccessIfTrue(true)")
     */
    public $firstName = 'Jason';
    /**
     * @ExcludeIf("hasAccessIfTrue(true)")
     */
    public $lastName = 'McClellan';
    /**
     * @ExcludeIf("hasAccessIfTrue(false)")
     */
    public $phone = '555-555-5555';
    /**
     * @ExcludeIf("hasAccessIfTrue(false)")
     */
    public $address ='New York, NY';

    public $occupation = 'Software';
}

根据上述注解,如果使用配置了我们的自定义ExpressionLanguageExpressionBasedExclusionStrategySerializationContext序列化此对象,我们只会看到序列化输出中的3个字段

  • first_name
  • last_name
  • occupation

创建元数据工厂

元数据工厂使我们能够存储注解中的表达式。因此,它需要我们提供一种方法来读取我们的@excludeIf注解。此库附带了一个具有注解功能的内置元数据驱动程序:JLM\SerializerExpression\Metadata\Driver\AnnotationDriver,可以直接使用,但需要提供注解读取器。我们使用来自Doctrine Common LibraryDoctrine\Common\Annotations\AnnotationReader

use Doctrine\Common\Annotations\AnnotationReader;
use JLM\SerializerExpression\Metadata\Driver\AnnotationDriver;
use JMS\Metadata\MetadataFactory;

$annotationReader = new AnnotationReader();
$annotationDriver = new AnnotationDriver($annotationReader);
$metadataFactory = new MetadataFactory($annotationDriver);

为了提高性能,强烈建议您为元数据工厂启用缓存。以下是如何使用文件缓存的方法

use Metadata\Cache\FileCache;

$metadataCache = new FileFache('/path/to/cache/dir');
$metadataFactory->setCache($metadataCache);

创建表达式语言

表达式语言超出了本文档的范围。有关详情,请参阅相关的Symfony文档

但是,这里有一个快速(且无用的)示例

use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;

class CustomExpressionLanguage extends BaseExpressionLanguage
{
    protected function registerFunctions()
    {
        parent::registerFunctions();

        // Test expression which always returns the opposite of the value we pass to it
        $this->register('hasAccessIfTrue', function ($arg) {
            return sprintf('return !%s', $arg);
        }, function (array $variables, $value)  {
            return !$value;
        });
    }
}

完整示例

use JMS\Metadata\MetadataFactory;
use JMS\Serializer\SerializerBuilder;
use JMS\Serializer\SerializationContext;
use Doctrine\Common\Annotations\AnnotationReader;
use JLM\SerializerExpression\Metadata\Driver\AnnotationDriver;


$expressionLang = new CustomExpressionLanguage();

$metadataDriver = new AnnotationDriver($annotationReader);
$metadataFactory = new MetadataFactory($metadataDriver);

$exclusionStrategy = new ExpressionBasedExclusionStrategy($metadataFactory, $expressionLang);

$serializationContext = SerializationContext::create();
$serializationContext->addExclusionStrategy($exclusionStrategy);

$serializer = SerializerBuilder::create()->build();

$serializedContent = $serializer->serialize($data, 'json', $serializationContext);