symfonyコンポーネントを使ってSilexでいくつかのプログラミングをしていますが、symfony/serializer
とsymfony/validator
コンポーネントのバグが見つかりました。このデータは別のコンポーネントによって上書きされますか?
まず、私が達成しようとしていることを説明してから、コードに行きましょう。 私の目的は、逐次化指令や検証指令のような情報でクラスに注釈を付けることです。これらの注釈を読むことはCPUのコストがかかるので、私はそれらをメモリにキャッシュするのが好きです。この目的のために、Doctrine/Common/Cache
パッケージにmemcacheラッパーを使用しています。
私が直面する問題は、symfony/serializer
とsymfony/validator
の両方が、クラス名をキーとしてキャッシュにメタデータを書き込むことです。後でメタデータを取得しようとすると、キャッシュに無効なメタデータ(Symfony\Component\Validator\Mapping\ClassMetadata
またはSymfony\Component\Serializer\Mapping\ClassMetadataInterface
のインスタンス)があるため、例外がスローされます。
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
class Foo
{
/**
* @var int
* @Assert\NotBlank(message="This field cannot be empty")
*/
private $someProperty;
/**
* @return int
* @Groups({"some_group"})
*/
public function getSomeProperty() {
return $this->someProperty;
}
}
use Doctrine\Common\Annotations\AnnotationReader;
use \Memcache as MemcachePHP;
use Doctrine\Common\Cache\MemcacheCache as MemcacheWrapper;
$loader = require_once __DIR__ . '/../vendor/autoload.php';
\Doctrine\Common\Annotations\AnnotationRegistry::registerLoader([$loader, 'loadClass']);
$memcache = new MemcachePHP();
if (! $memcache->connect('localhost', '11211')) {
throw new \Exception('Unable to connect to memcache server');
}
$cacheDriver = new MemcacheWrapper();
$cacheDriver->setMemcache($memcache);
$app = new \Silex\Application();
$app->register(new Silex\Provider\SerializerServiceProvider());
$app['serializer.normalizers'] = function() use ($app, $cacheDriver) {
$classMetadataFactory = new Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory(
new Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader(new AnnotationReader()), $cacheDriver);
return [new Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer($classMetadataFactory) ];
};
$app->register(new Silex\Provider\ValidatorServiceProvider(), [
'validator.mapping.class_metadata_factory' =>
new \Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory(
new \Symfony\Component\Validator\Mapping\Loader\AnnotationLoader(new AnnotationReader()),
new \Symfony\Component\Validator\Mapping\Cache\DoctrineCache($cacheDriver)
)
]);
$app->get('/', function(\Silex\Application $app) {
$foo = new Foo();
$app['validator']->validate($foo);
$json = $app['serializer']->serialize($foo, 'json');
return new \Symfony\Component\HttpFoundation\JsonResponse($json, \Symfony\Component\HttpFoundation\Response::HTTP_OK, [], true);
});
$app->error(function (\Exception $e, \Symfony\Component\HttpFoundation\Request $request, $code) {
return new \Symfony\Component\HttpFoundation\Response('We are sorry, but something went terribly wrong.' . $e->getMessage());
});
$app->run();
あなたは致命的なエラーが発生します。この例を実行した後:
後は(その大きい場合には、私は可能な限り小さく作ってみました申し訳ありません)reproductible例です。 誰かが私がここで間違いを犯さないことを確認できますか?
現在のところ、この問題を回避するには、キャッシュキーに名前空間を使用するDoctrineCache
クラスを書き直してください。その仕事は、私はその醜いと思います。