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

时间:2013-01-31 15:20:45

标签: 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);
?>

这是例外

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.

我通过composer

为项目安装了以下库
{
    "require": {
        "jms/serializer": "1.0.*@dev"
    }
}

由于我没有使用整个Doctrine 2解决方案,是否有一些我不知道的东西?

编辑:我的最终解决方案是使用以下内容创建一个bootstrap文件:

<?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'
);
?>

6 个答案:

答案 0 :(得分:70)

非常确定这会启用静默自动加载,这比自己注册名称空间要方便得多。

AnnotationRegistry::registerLoader('class_exists');

答案 1 :(得分:40)

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

问题是,JMSSerializer Annotations使用的Doctrine Annotations does NOT use normal PHP autoloading

  

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

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

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

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

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

小心registerAutoloadNamespace中的路径。我首先尝试使用registerFile

以相同的方式注册注释的整个路径
<PROJECT ROOT> . "/vendor/jms/serializer/src/JMS/Serializer/Annotation 
但是那失败了。 :d

我希望这会让你更进一步。 :)

答案 2 :(得分:4)

@SirArturio对这个自动加载拼图有正确的答案,我只想更加清晰地回应@messified或其他任何努力使其工作的人。正如他雄辩地解释的那样,作曲家或SPL中的自动PSR-0处理程序不会因为使用Doctrine的自动加载而削减它以加载这些注释。

所以这是一个很小的完整例子。每当您创建JMS Serializer对象以开始序列化时,都是将注释命名空间添加到doctrine的自动加载器的好时机。为清楚起见,我假设没有IoC和完全限定的命名空间(提示提示,使用依赖注入):

<?php
Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespace(
'JMS\Serializer\Annotation', 
$your_app_basepath . "/vendor/jms/serializer/src");


$serializer = JMS\Serializer\SerializerBuilder::create()->build();
$json_output = $serializer->serialize('MyProject\MyClass', 'json');

然后在你的MyProject \ MyClass中:

<?php
use JMS\Serializer\Annotation as JMS;

class MyClass{

    /** @JMS\Exclude */
    private $something_secret;
}

这应该削减它,使用doctrine而不是composer自动加载正确的注释文件。

答案 3 :(得分:3)

检查注释的大小写。从Windows开发环境部署到Ubuntu服务器时遇到类似的问题,这是由我的注释中的拼写引起的。 Windows文件不区分大小写,因此它在那里工作但在Linux上失败。

答案 4 :(得分:0)

如果使用Composer,则可以通过在require中指定路径来获取加载器:

$loader = require(__DIR__ . '/../vendor/autoload.php');
AnnotationRegistry::registerLoader(array($loader, 'loadClass'));

答案 5 :(得分:-3)

这是解决方案

1.到php目录然后安装composer php composer-setup.php 2.转到项目sdk目录 例如

cd / Applications / XAMPP / xamppfiles / htdocs / streetreturn / adn_sdk-php-master

更新composer以安装依赖项 php /Users/zakir/composer.phar update

*注意:/Users/zakir/composer.phar将在步骤1中安装composer时找到