在析构函数中创建/写入PHP文件 [英] PHP file creation/write within destructor

查看:124
本文介绍了在析构函数中创建/写入PHP文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在析构函数中调用file_put_contents()时,是否导致将文件写入SERVER_ROOT ...(可能!)解决方法?

When calling file_put_contents() within a destructor, it causes files to be written in SERVER_ROOT... (Yikes!) Workarounds?

tldr:

我想缓存一个数组,可能包含序列化的类实例.我想现在,我将编写一个使用unserialize()/file_get_contents()serialize()/file_put_contents()实现缓存的类,然后将其功能隐藏在更通用的Cache类后面. (我不知道我的客户的主机是否将具有共享内存或PEAR等)

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") );
?>

在析构函数中看到对flush()的调用吗?我真的不想拥有public flush()函数,因为它是特定于实现的.

See the call to flush() in the destructor? I really don't want to have the public flush() function because it's implementation-specific.

推荐答案

我假设您尚未在$this->filename中指定完整的限定路径.

I assume you have not specified a full qualified path in $this->filename.

在某些PHP配置上,当调用析构函数时(在脚本关闭阶段),工作目录可以更改.然后,相对路径会解析到另一个位置.

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.

PHP手册中的相关注释进行比较:

Compare with the related note in the PHP Manual:

注意:

在脚本关闭期间调用的析构函数已经发送了HTTP标头.脚本关闭阶段的工作目录可能与某些SAPI(例如Apache)不同.

Destructors called during the script shutdown have HTTP headers already sent. The working directory in the script shutdown phase can be different with some SAPIs (e.g. Apache).

如果将该路径设为绝对路径,它将按预期工作.

If you make that path absolute, it will work as expected.

编辑:更新代码后,这是一种确保获得绝对路径的简单方法:

As you've update your code, this is a simple way to ensure you've got the absolute path:

$cache = new CacheFile(realpath("cache"));

或者更好的内部构造函数:

$this->filename = realpath($filename);

这篇关于在析构函数中创建/写入PHP文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆