[英]How to delete element and its children using php's HTMLDOMDocument class
[英]How to delete a PHP object from its class?
我知道对于一些可能听起来很愚蠢的人,但我在想如果我在一个删除所有对象数据(来自DB和文件系统)的类中有一个delete()方法,我怎么能从内部销毁/删除对象类。
这是一个PHP问题。 像未unset($this);
东西unset($this);
有可能吗?明智吗? 什么是正确的方法呢?
在开发框架的同时,我也遇到了这样的问题。 unset($this)
完全不可能,因为$this
只是一个特殊的指针,允许您访问当前对象的属性和方法。
唯一的方法是在方法/函数中封装对象的使用,这样当方法/函数结束时,对对象的引用就会丢失,垃圾收集器会自动释放内存以用于其他事情。
请参阅示例RaiseFile
,一个表示文件的类:
http://code.google.com/p/phpraise/source/browse/trunk/phpraise/core/io/file/RaiseFile.php
在RaiseFile类中,在调用delete()
方法并删除文件之后,还应该删除RaiseFile对象是明智的。
但是,由于您提到的问题,我实际上必须坚持RaiseFile指向文件,无论文件是否存在。 可以通过exists()
方法跟踪文件的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-ed,因为$f
外部没有更多对RaiseFile
对象$f
引用。
你不能取消$this
。 或者更正确: $this
unset()
上的unset()
只对变量有局部影响。 unset()
从本地范围中删除变量,这会减少对象的引用计数。 如果对象仍在其他地方引用,它将保留在内存中并工作。
通常,ID属性的值用于确定对象是否存储在后端。 如果ID具有适当的值,则存储该对象。 如果ID为null
,则尚未存储。 成功存储后,您可以相应地设置ID。 在删除时,您再次将ID属性设置为null
。
我现在在同一条船上。
我正在从头开始构建CMS解决方案,并在对象之间有很多引用; 用户,群组,类别,论坛,主题,帖子等
我还在每个类中使用“Object :: getObject(id)”加载器,确保每个ID只有一个对象实例,但也意味着代码更容易提取对现有对象的引用。
当对象表示的数据从数据源中删除时,我想从内存中擦除对象并取消对它的所有引用,以确保其他代码不会尝试使用过时的数据集。
理想情况下,应删除所有引用 - 引用代码可以提供在删除对象时触发的回调,随后可以删除/更新引用。 但是如果引用代码变得草率,我宁愿错误地使用“Not an 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>';
}
}
对于使用示例,将引用保存在array
,在实现我们的interface
的object
和$GLOBALS array
。
// Define collectors
$array = array();
$parent = new MyParent();
// Store objects directly in array
$array['c1'] = new Suicidal($array);
$array['c2'] = new Suicidal($array);
// Make a global reference and store in object
$global_refrence = $array['c1']->getReference($GLOBALS);
$parent->children[] = $array['c1']->getReference($parent);
// Display some numbers and blow up an object.
echo 'memory usage with 2 items ' . memory_get_usage() . ' bytes<br>';
$array['c1']->selfDestruct();
echo 'memory usage with 1 item ' . memory_get_usage() . ' bytes<br>';
// Second object is GC-d the natural way after this line
echo '---- before eof ----' . '<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
这取决于你的课程结构。
如果您遵循DTO / DAO模式,您的数据将与您的模型分开,您只需删除DTO即可。 如果不是,只需取消设置类的数据部分即可。
但实际上,我认为这是不必要的,因为PHP会在请求结束时自动清理。 除非你正在处理一个占用大量内存的巨大物体,而且这是一个漫长的过程,所以这并不值得付出努力。
有一个__destruct()魔术方法,它是PHP类的析构函数。
也许您可以将删除代码放在那里,只要删除对所有对象的引用,就会调用此析构函数并删除数据。
另一种方法是使delete-method静态,然后可以接收PDO对象和数据,确定要删除的内容。 这样您就不需要初始化对象了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.