JMSSerializer独立 - 注释不存在,或者无法自动加载

Jos*_*h J 36 php jmsserializerbundle

我试图使用JMSSerializer作为一个独立的库来将API的JSON响应映射到我的模型类,并且遇到了一些问题.

执行以下代码会导致异常:

<?php
require dirname(__DIR__) . '/vendor/autoload.php';

use JMS\Serializer\Annotation AS JMS;

class Trii {
    /**
     * User ID for this session
     * @JMS\SerializedName("userID")
     * @JMS\Annotation(getter="getUserId")
     * @JMS\Type("string")
     * @var string
     */
    private $userId;

    public function getUserId() {
        return $this->userId;
    }

    public function setUserId($userId) {
        $this->userId = $userId;
    }
}

$serializer = \JMS\Serializer\SerializerBuilder::create()->setDebug(true)->build();
$object = $serializer->deserialize('{"userID":"Trii"}', 'Trii', 'json');
var_dump($object);
?>
Run Code Online (Sandbox Code Playgroud)

这是例外

Doctrine\Common\Annotations\AnnotationException: [Semantical Error] The annotation "@JMS\Serializer\Annotation\SerializedName" in property Trii::$userId does not exist, or could not be auto-loaded.
Run Code Online (Sandbox Code Playgroud)

我通过composer为项目安装了以下库

{
    "require": {
        "jms/serializer": "1.0.*@dev"
    }
}
Run Code Online (Sandbox Code Playgroud)

因为我没有使用整个Doctrine 2解决方案,有什么明显的东西我不知道了吗?

编辑:我的最终解决方案是创建一个包含以下内容的引导程序文件:

<?php
// standard composer install vendor autoload magic
require dirname(__DIR__) . '/vendor/autoload.php';

// Bootstrap the JMS custom annotations for Object to Json mapping
\Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespace(
    'JMS\Serializer\Annotation',
    dirname(__DIR__).'/vendor/jms/serializer/src'
);
?>
Run Code Online (Sandbox Code Playgroud)

Fli*_*lip 70

非常确定这可以实现静默自动加载,这比自己注册命名空间要方便得多.

AnnotationRegistry::registerLoader('class_exists');
Run Code Online (Sandbox Code Playgroud)

  • 如果要为此使用简写形式,请确保添加`use Doctrine \ Common \ Annotations \ AnnotationRegistry;`行。我把它放在我的应用程序启动程序(`/ app / boostrap / app.php`)中,尽管它可以放在自动加载器(`/ app / boostrap / autoload.php`)中,只要它遵循作曲家的自动加载即可。 (2认同)

小智 40

我遇到了同样的问题,通过谷歌发现了你的问题.不幸的是你还没有收到任何答案,所以我不得不自己挖掘.:P

问题是,JMSSerializer Annotations使用的Doctrine Annotations 不使用普通的PHP自动加载.

这些注释是如何加载的?通过查看代码,您可以猜到ORM Mapping,Assert Validation和完全限定的注释可以使用定义的PHP自动加载器加载.但情况并非如此:出于错误处理的原因,AnnotationReader中对类存在的每次检查都将class_exists($ name,$ autoload)的第二个参数$ autoload设置为false.为了完美地工作,AnnotationReader需要静音自动加载器,许多自动加载器不需要.静默自动加载不是PSR-0自动加载规范的一部分.

这意味着您必须自己注册Annotation文件:

AnnotationRegistry::registerFile(
   <PROJECT ROOT> . 
   "/vendor/jms/serializer/src/JMS/Serializer/Annotation/SerializedName.php");
Run Code Online (Sandbox Code Playgroud)

...或整个命名空间(首选方法):

AnnotationRegistry::registerAutoloadNamespace(
    'JMS\Serializer\Annotation', 
    <PROJECT ROOT> . "/vendor/jms/serializer/src");
Run Code Online (Sandbox Code Playgroud)

小心路径registerAutoloadNamespace.我首先尝试以相同的方式注册注释的整个路径registerFile:

<PROJECT ROOT> . "/vendor/jms/serializer/src/JMS/Serializer/Annotation 
Run Code Online (Sandbox Code Playgroud)

但那失败了.:d

我希望这能让你更进一步.:)