我正在尝试使用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'
);
?>
答案 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)
所以这是一个很小的完整例子。每当您创建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时找到