Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从类中删除PHP对象?_Php_Oop - Fatal编程技术网

如何从类中删除PHP对象?

如何从类中删除PHP对象?,php,oop,Php,Oop,我知道,对于某些人来说,这可能听起来很愚蠢,但我在想,如果我在一个类中有一个delete()方法,可以删除所有对象数据(从DB和文件系统中),我如何从类中销毁/删除对象 这是一个PHP问题。类似于unset($this)的东西是否可能和明智?正确的方法是什么?这取决于你是如何组织你的课程的 如果您遵循DTO/DAO模式,那么您的数据将与您的模型分离,您可以简单地删除DTO。如果没有,只需取消类的数据部分就可以了 但实际上,我认为这是不必要的,因为PHP将在请求结束时自动清理。除非你正在研究一个巨

我知道,对于某些人来说,这可能听起来很愚蠢,但我在想,如果我在一个类中有一个delete()方法,可以删除所有对象数据(从DB和文件系统中),我如何从类中销毁/删除对象


这是一个PHP问题。类似于
unset($this)的东西是否可能和明智?正确的方法是什么?

这取决于你是如何组织你的课程的

如果您遵循DTO/DAO模式,那么您的数据将与您的模型分离,您可以简单地删除DTO。如果没有,只需取消类的数据部分就可以了

但实际上,我认为这是不必要的,因为PHP将在请求结束时自动清理。除非你正在研究一个巨大的物体,它占用了大量的内存,而且这是一个漫长的过程,否则你就不值得为此付出努力

有一个神奇的方法,它是PHP类的析构函数


也许您可以将删除代码放在其中,一旦删除对对象的所有引用,就会调用此析构函数并删除数据。

您无法取消设置
$this
。或者更准确地说:
unset()
on
$此
仅对变量有局部影响
unset()
从本地范围中删除变量,从而减少对象的引用计数。如果对象仍在其他地方引用,它将保留在内存中并工作


通常,ID属性的值用于确定对象是否存储在后端。如果ID具有正确的值,则存储该对象。如果ID为
null
,则尚未存储该ID。成功存储后,您可以相应地设置ID。在delete上,您再次将ID属性设置为
null

在框架上开发时,我也遇到了这样的问题
unset($this)
是完全不可能的,因为
$this
只是一个特殊的指针,允许您访问当前对象的属性和方法

唯一的方法是封装方法/函数中对象的使用,这样当方法/函数结束时,对对象的引用将丢失,垃圾收集器将自动释放内存用于其他事情

请参见示例
RaiseFile
,一个表示文件的类:

在RaiseFile类中,调用并删除文件后,RaiseFile对象也应该被删除

但是,由于您提到的问题,我实际上必须坚持RaiseFile指向一个文件,无论该文件是否存在。可以通过
exists()
方法跟踪文件的存在

假设我们有一个使用RaiseFile表示的剪切粘贴函数:

/**
 * Cut and paste a file from source to destination
 * @param string $file Pathname to source file
 * @param string $dest Pathname to destination file
 * @return RaiseFile The destination file
 */
function cutpaste($file, $dest){
    $f = new RaiseFile($file);
    $d = new RaiseFile($dest);
    $f->copy($d);
    $f->delete();
    return $d;
}

请注意,函数结束后,
$f
是如何被删除的,并被GC删除的,因为函数外部不再有对
RaiseFile
对象
$f
的引用。

另一种方法是将delete方法设置为静态,然后可以接收PDO对象和数据,以确定要删除的内容。这样你就不需要初始化对象了。

我现在也在这条船上

我正在从头开始构建一个CMS解决方案,并且在对象之间有很多引用;用户、组、类别、论坛、主题、帖子等

我还在每个类中使用“Object::getObject(id)”加载程序,这确保每个id只有一个对象实例,但也意味着代码更容易获取对现有对象的引用

当对象所代表的数据从数据源中删除时,我希望从内存中删除该对象,并使对它的所有引用无效,以确保其他代码不会尝试使用过时的数据集

理想情况下,应该删除所有引用——引用代码可以提供一个回调,该回调在删除对象时触发,随后可以删除/更新引用。但是,如果引用代码变得马虎,我宁愿用一个“Not a object”错误将其出错,而不是实际使用该对象

在不知道如何从物体本身内部进行破坏的情况下,我被迫:

  • 几乎每一个非静态方法都要检查对象是否被标记为“已删除”,如果被标记为“已删除”,则抛出异常。这确保了任何引用代码都不会造成任何伤害,但在代码中查看它是一件令人讨厌的事情

  • 从数据库中删除后,取消设置每个对象变量,这样它就不会留在内存中。没什么大不了的,但是,再一次:看起来很恶心


  • 如果我可以从内部销毁对象,这两种方法都不需要。

    这里有一个示例解决方案,当在定义良好的关系/引用模式中实现时,它将“合理可用”,通常我会在我的合成中删除类似的内容。在现实生活中,如我在本例中所做的那样,实际使用当前代码会遇到太多麻烦,但这只是为了说明如何使用

    一个对象不能只是神奇地消失——只有当没有任何东西指向它时,它才会被删除(垃圾收集)。所以“所有”一个对象必须做的就是跟踪引用它的所有东西。当您拥有所有内置的引用管理时,这是相当低的摩擦-对象仅通过固定方法创建和传递

    让我们从一个简单的接口开始,这样我们就能够判断将引用传递给对象是否安全

    interface removableChildInterface
    {
    
        public function removeChild($obj);
    
    }
    
    可以安全地保存对对象的引用的类

    class MyParent implements removableChildInterface
    {
    
        public $children = array();
    
        public function removeChild($child)
        {
            $key = array_search($child, $this->children);
            unset($this->children[$key]);
        }
    
    }
    
    最后,一个具有自毁能力的类触发了被所有父类移除的过程

    class Suicidal
    {
    
        private $parents = array(); // Store all the reference holders
        private $id; // For example only
        private $memory = ''; // For example only
        public static $counter = 0; // For example only
    
        public function __construct(&$parent)
        {
            // Store a parent on creation
            $this->getReference($parent);
            // For the example lets assing an id
            $this->id = 'id_' . ++self::$counter;
            // and generate some weight for the object.
            for ($i = 0; $i < 100000; $i++) {
                $this->memory .= md5(mt_rand() . $i . self::$counter);
            }
        }
    
        // A method to use for passing the object around after its creation.
        public function getReference(&$parent)
        {
            if (!in_array($parent, $this->parents)) {
                $this->parents[] = &$parent;
            }
            return $this;
        }
    
        // Calling this method will start the removal of references to this object.
        // And yes - I am not actually going to call this method from within this
        // object in the example but the end result is the same.
        public function selfDestruct()
        {
            foreach ($this->parents as &$parent) {
                if (is_array($parent)) {
                    $key = array_search($this, $parent);
                    unset($parent[$key]);
                    echo 'removing ' . $this->id . ' from an array<br>';
                } elseif ($parent instanceof removableChildInterface) {
                    $parent->removeChild($this);
                    echo 'removing ' . $this->id . ' from an object<br>';
                }
                // else throw your favourite exception
            }
        }
    
        // A final shout out right before being garbage collected.
        public function __destruct()
        {
            echo 'destroying ' . $this->id . '<br>';
        }
    
    }
    
    输出:

    memory usage with 2 items 6620672 bytes
    removing id_1 from an array
    removing id_1 from an array
    removing id_1 from an object
    destroying id_1
    memory usage with 1 item 3419832 bytes
    ---- before eof ----
    destroying id_2
    

    你在找DestructorI吗?我不明白这个问题。对象本身存在于RAM中,一旦没有对它的引用,垃圾收集器就会将其删除。如果您负责存储有关此对象的信息
    memory usage with 2 items 6620672 bytes
    removing id_1 from an array
    removing id_1 from an array
    removing id_1 from an object
    destroying id_1
    memory usage with 1 item 3419832 bytes
    ---- before eof ----
    destroying id_2