Symfony BadMethodCallException:使用AWS预签名URL时无法序列化FilesystemAd



我使用Symfony 6.0和PHP 8.1,在将自定义AWSService注入自定义对象时,日志中出现以下错误:

Uncaught PHP Exception BadMethodCallException: "Cannot serialize SymfonyComponentCacheAdapterFilesystemAdapter" at /app/vendor/symfony/cache/Traits/FilesystemCommonTrait.php line 176
Channel: request
Context: exception: 
{
"class": "BadMethodCallException",
"message": "Cannot serialize Symfony\Component\Cache\Adapter\FilesystemAdapter",
"code": 0,
"file": "/app/vendor/symfony/cache/Traits/FilesystemCommonTrait.php:176",
"trace": [
"/app/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php:241",
"/app/vendor/symfony/http-foundation/Session/Session.php:195",
"/app/vendor/symfony/http-kernel/EventListener/AbstractSessionListener.php:132",
"/app/vendor/symfony/event-dispatcher/EventDispatcher.php:270",
"/app/vendor/symfony/event-dispatcher/EventDispatcher.php:230",
"/app/vendor/symfony/event-dispatcher/EventDispatcher.php:59",
"/app/vendor/symfony/http-kernel/HttpKernel.php:185",
"/app/vendor/symfony/http-kernel/HttpKernel.php:173",
"/app/vendor/symfony/http-kernel/HttpKernel.php:74",
"/app/vendor/symfony/http-kernel/Kernel.php:202",
"/app/public/index.php:25"
]
}

我在整个代码中添加了其他日志记录,这似乎发生在我的控制器退出并成功返回之后。我不清楚如何进一步调试这个问题,因为在控制器退出后,它会进入Symfony陆地。

我的AWSService处理AWS服务(如S3或DynamoDB(的存储和检索等事务。我将它注入到一个对象中,该对象将调用者的信息保存在会话中以便于访问,对于引发此错误的调用,我将使用它为对象的一个属性创建一个预签名URL。

我觉得奇怪的是AWSService没有显式地访问文件系统。。。它使用AWS的$s3->createPresignedRequest()调用获取一个对象并从中创建一个字符串。即使是createPresignedRequest()的AWS文档也暗示该函数只是根据提供的设置给出了一个答案:

重要

此方法返回的URL不会经过验证以确保bucket或密钥存在,也不会确保对象允许未经验证的访问。

此外,如上所述,在抛出此异常之前,函数调用完成时没有出现错误,调用它的控制器也完成时没有错误。因此,很难相信AWSService本身造成了这个问题。

很明显,这与对象的序列化方式有关,但我不确定具体是什么,因为这个错误非常模糊,我正在创建一个字符串(而不是资源(。任何想法都将不胜感激!

经过几个小时的努力,我终于明白了。。。由于我在StackOverflow上找不到任何专门解决这个问题的东西,下面是我的笔记。

事实证明,Symfony似乎序列化了会话中的所有对象,以便在主处理完成后,以及调用侦听器、后处理器等之前,可以对它们进行去水合/重新水合。

我从这篇StackOverflow文章中得到了一个提示,它告诉我序列化数据中不支持资源。但我不认为获得预签名的URL会引起问题。。。事实证明,这是正确的。

最后,我为对象创建了一个助手类,并且在构建对象时只在外部而不是内部设置属性。只有在那一点上,我才得到一个更好的错误:

request.CRITICAL: Uncaught PHP Exception RuntimeException: "Instances of AwsDynamoDbDynamoDbClient cannot be serialized" at /app/vendor/aws/aws-sdk-php/src/AwsClient.php line 276

所以。。。因为AWSService包含DynamoDbClient的一个实例,并且因为我将AWSService放入一个对象中,然后将其存储在会话中,所以当对象到达内部序列化程序时,Symfony崩溃了。

我不知道为什么这个例外没有更好地出现,但是。。。至少现在它已经在这里被记录下来了。希望它能帮助其他人!

最新更新