如何用symfony保存缓存时解决“ touch():Utime失败:不允许操作”?

时间:2019-04-24 07:42:06

标签: php symfony caching

我想用symfony \ cache缓存一些响应。但是我的缓存出现了一些错误,有时甚至是symfony默认的缓存出现了问题。

配置:

流浪汉上的Debian 9(带有流浪汉的bindfs链接到源代码目录) 使用Apache2
php 7.2 / symfony 4.1
apcu已启用

要缓存我的响应,我将FilesystemAdapter与dir {projectDir} / var / cache / {env} / api-cache和命名空间app.cache一起使用

var / cache /

drwxrwxrwx 24 vagrant www-data 768 Apr 24 09:09 dev/
drwxrwxrwx 13 vagrant www-data 416 Apr 18 16:02 test/

var / cache / dev /

-rw-rw-rw-   1 vagrant www-data  165 Apr 24 09:09 annotations.map
-rw-rw-rw-   1 vagrant www-data  12K Apr 24 09:09 annotations.php
drwxrwxrwx   3 vagrant www-data   96 Apr 23 17:47 api-cache/
drwxrwxrwx 399 vagrant www-data  13K Apr 23 17:46 ContainerBrT4sD3/
-rw-rw-rw-   1 vagrant www-data    0 Apr 24 09:07 ContainerBrT4sD3.legacy
drwxrwxrwx 404 vagrant www-data  13K Apr 24 09:09 ContainerSaE63B9/
drwxrwxrwx   3 vagrant www-data   96 Apr 23 17:46 doctrine/
drwxrwxrwx   6 vagrant www-data  192 Apr 23 17:47 jms_serializer/
drwxrwxrwx   5 vagrant www-data  160 Apr 24 09:07 pools/
-rw-rw-rw-   1 vagrant www-data 220K Apr 24 09:09 srcDevDebugProjectContainerCompiler.log
-rw-rw-rw-   1 vagrant www-data 1.1K Apr 24 09:09 srcDevDebugProjectContainerDeprecations.log
-rw-rw-rw-   1 vagrant www-data  767 Apr 24 09:09 srcDevDebugProjectContainer.php
-rw-rw-rw-   1 vagrant www-data  58K Apr 24 09:09 srcDevDebugProjectContainer.php.meta
-rw-rw-rw-   1 vagrant www-data  49K Apr 23 17:46 srcDevDebugProjectContainerUrlGenerator.php
-rw-rw-rw-   1 vagrant www-data 5.4K Apr 23 17:46 srcDevDebugProjectContainerUrlGenerator.php.meta
-rw-rw-rw-   1 vagrant www-data  78K Apr 23 17:46 srcDevDebugProjectContainerUrlMatcher.php
-rw-rw-rw-   1 vagrant www-data 5.4K Apr 23 17:46 srcDevDebugProjectContainerUrlMatcher.php.meta
-rw-rw-rw-   1 vagrant www-data 519K Apr 24 09:09 srcDevDebugProjectContainer.xml
-rw-rw-rw-   1 vagrant www-data  58K Apr 24 09:09 srcDevDebugProjectContainer.xml.meta
drwxrwxrwx 108 vagrant www-data 3.4K Apr 23 17:46 translations/
drwxrwxrwx 142 vagrant www-data 4.5K Apr 24 09:09 twig/
-rw-rw-rw-   1 vagrant www-data   91 Apr 24 09:09 validation.php

登录默认的symfony代码:

 cache.WARNING: Failed to save key "%5B%5BC%5DApp%5CEntity%5CReport%5CReportItem%24hasBeenPushed%5D%5B1%5D" (integer) {"key":"%5B%5BC%5DApp%5CEntity%5CReport%5CReportItem%24hasBeenPushed%5D%5B1%5D","type":"integer","exception":"[object] (ErrorException(code: 0): touch(): Utime failed: Operation not permitted at /vagrant-bindfs/vendor/symfony/cache/Traits/FilesystemCommonTrait.php:90)"} []

使用我的代码登录:

php.DEBUG: User Warning: Failed to save key "my_tag" (string) {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\SilencedErrorContext: {\"severity\":512,\"file\":\"/vagrant-bindfs/vendor/symfony/cache/CacheItem.php\",\"line\":184,\"trace\":[{\"file\":\"/vagrant-bindfs/vendor/symfony/cache/Adapter/AbstractAdapter.php\",\"line\":242,\"function\":\"log\",\"class\":\"Symfony\\\\Component\\\\Cache\\\\CacheItem\",\"type\":\"::\"}],\"count\":1})"} []
app.ERROR: Cache not save : my_tag [] []

当我在Symfony \ Component \ Cache \ Adapter \ AbstractAdapter-> commit()中记录有关异常的一些信息时,我得到了: ErrorException touch(): Utime failed: Operation not permitted

我已经搜索了解决方案,但没有任何效果。 我认为这是缓存目录上的问题,也许是vagrant和vagrant-binfs的问题,但是我不明白。

我该怎么做/检查以解决此问题?

2 个答案:

答案 0 :(得分:0)

我有同样的问题。

您需要做的就是将synced_folder的类型更改为nfs,但是该选项仅适用于Mac主机。

要在Windows中使用它,您需要安装vagrant-winnfsd

$ vagrant plugin install vagrant-winnfsd

然后在您的Vagrantfile中更改同步的类型

Vagrant.configure("2") do |config|
  config.vm.synced_folder "../project", "/var/www", type: "nfs"
end

文档说,还需要将网络类型更改为dhcp,但是我不需要这样做即可解决我的问题。

config.vm.network "private_network", type: "dhcp"

我希望这对您有帮助

答案 1 :(得分:0)

如果您碰巧使用FAT / FAT32或时间戳范围受到严格限制的其他文件系统,则将出现该警告。

Symfony的FilesystemCommonTrait::write()方法使用unix时间戳0调用touch()函数,以强制过期缓存的内容。 Unix时间戳0代表1970-01-01日期。根据Wikipedia,在FAT文件系统中,允许的时间戳范围是1980-01-01至2099-12-31。因此touch()函数失败并发出警告。

解决方法是在第80行附近修改FilesystemCommonTrait::write()方法。

查找行:

if (null !== $expiresAt) {
    touch($this->tmp, $expiresAt);
}

在这些行之前插入:

if (0 === $expiresAt) {
    $expiresAt = time() - 1;
}

这应该通过立即使缓存的内容过期而获得几乎相同的结果,但不使用无效的文件系统时间戳记。

或者,更改文件系统类型。