PHP 文件在析构函数中创建/写入
在析构函数中调用 file_put_contents()
时,它会导致文件写入 SERVER_ROOT
...(哎呀!)解决方法?
tldr:
我想缓存一个数组,可能包含序列化的类实例。我想,现在我会编写一个使用 unserialize()/file_get_contents()
和 serialize()/file_put_contents()
实现缓存的类,然后隐藏其功能在更通用的 Cache 类后面。 (我不知道我的客户端主机是否有共享内存或 PEAR 等)
<?php
class CacheFile {
private $filename;
private $data;
private $dirty = false;
function __construct($filename) {
$this->filename = $filename;
$this->load();
}
function __destruct() {
// Calling file_put_contents within a destructor causes files to be written in SERVER_ROOT...
$this->flush();
}
private function load() {
if(!file_exists($this->filename)) {
$this->data = array();
}
else {
$this->data = unserialize(file_get_contents($this->filename));
// todo
}
$this->dirty = false;
}
private function persist() {
file_put_contents($this->filename, serialize($this->data));
$this->dirty = false;
}
public function get($key) {
if(array_key_exists($key, $this->data)) {
return $this->data[$key];
}
else {
return false;
}
}
public function set($key, $value) {
if(!array_key_exists($key, $this->data)) {
$dirty = true;
}
else if($this->data[$key] !== $value) {
$dirty = true;
}
if($dirty) {
$this->dirty = true;
$this->data[$key] = $value;
}
}
public function flush() {
if($this->dirty) {
$this->persist();
}
}
}
$cache = new CacheFile("cache");
var_dump( $cache->get("item") );
$cache->set("item", 42);
//$cache->flush();
var_dump( $cache->get("item") );
?>
看到析构函数中对 flush()
的调用了吗?我真的不想使用 publiclush() 函数,因为它是特定于实现的。
When calling file_put_contents()
within a destructor, it causes files to be written in SERVER_ROOT
... (Yikes!) Workarounds?
tldr:
I want to cache an array, probably containing serialized class instances. I figured, for now, I would write a class that implements the cache using unserialize()/file_get_contents()
and serialize()/file_put_contents()
and then hide its functionality behind a more generic Cache class. (I don't know if my client's host will have shared memory or PEAR, etc)
<?php
class CacheFile {
private $filename;
private $data;
private $dirty = false;
function __construct($filename) {
$this->filename = $filename;
$this->load();
}
function __destruct() {
// Calling file_put_contents within a destructor causes files to be written in SERVER_ROOT...
$this->flush();
}
private function load() {
if(!file_exists($this->filename)) {
$this->data = array();
}
else {
$this->data = unserialize(file_get_contents($this->filename));
// todo
}
$this->dirty = false;
}
private function persist() {
file_put_contents($this->filename, serialize($this->data));
$this->dirty = false;
}
public function get($key) {
if(array_key_exists($key, $this->data)) {
return $this->data[$key];
}
else {
return false;
}
}
public function set($key, $value) {
if(!array_key_exists($key, $this->data)) {
$dirty = true;
}
else if($this->data[$key] !== $value) {
$dirty = true;
}
if($dirty) {
$this->dirty = true;
$this->data[$key] = $value;
}
}
public function flush() {
if($this->dirty) {
$this->persist();
}
}
}
$cache = new CacheFile("cache");
var_dump( $cache->get("item") );
$cache->set("item", 42);
//$cache->flush();
var_dump( $cache->get("item") );
?>
See the call to flush()
in the destructor? I really don't want to have the public flush()
function because it's implementation-specific.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我假设您没有在
$this->filename
中指定完整的限定路径。在某些 PHP 配置中,当调用析构函数时(在脚本关闭阶段),工作目录可能会更改。然后相对路径解析到另一个位置。
与PHP手册中的相关注释进行比较:
如果您将该路径设为绝对路径,它将按预期工作。
编辑:当您更新代码时,这是确保您获得绝对路径的简单方法:
或者在构造函数内更好:
I assume you have not specified a full qualified path in
$this->filename
.On some PHP configurations, when destructors are called (in the scripts shutdown phase), the working directory can change. Relative paths resolve to another location then.
Compare with the related note in the PHP Manual:
If you make that path absolute, it will work as expected.
Edit: As you've update your code, this is a simple way to ensure you've got the absolute path:
Or much better within the constructor:
您可以在
load()
中创建一个文件句柄,您可以在中使用它__destruct() 或
flush()
。You could create a file handle in
load()
which you can use in__destruct()
orflush()
.您是否使用相对路径作为 $filename ?我会传入您想要文件的位置的绝对路径。如果您希望它与脚本所在的位置相关,您可以使用类似以下内容的内容:
Are you using a relative path as $filename? I would pass in an absolute path to where you want the file. If you want it to be relative to where your script is you could use something like: