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