我制作了一个类似于文件包装器的类。当用户调用删除方法时,我想取消设置对象(实际上是 $this)。有没有办法(解决方法)做到这一点?说明书上说不行,没办法……
7 回答
据我所知,没有办法从类本身中销毁类实例。您必须在其范围内取消设置实例。
$myClass = new fooBar();
unset($myClass);
有些相关:执行上述操作将自动调用__destruct()
该类的任何现有魔术方法,以便您可以进行任何额外的清理。更多信息
说明书是对的。不可能。
unset
本质上是用来说“我已经使用完一个特定的变量;就我而言,它可以被认为是垃圾收集。
问题在于,$this
无论如何,这仅在方法调用的上下文中才有意义。一旦方法完成,$this
将超出范围(本质上)并且不再算作对对象的引用。(出于实际目的。)
因此,您无需担心释放$this
. PHP 会解决这个问题。
您可能正在尝试做的是可能引用同一实例unset
的其他变量。除非您可以从方法中访问它们,否则您无法触摸它们,更不用说unset
它们了。
我花了很多时间寻找一种方法,从它自身内部将一个对象设置为 NULL。
请尝试以下代码:
<?php
class bike{
public $color = "black";
function destroySelf(bike &$me){
$me = NULL;
//$me = new bike();
}
}
$iRide = new bike();
$iRide->color = "red";
var_dump($iRide);echo " -before <br>";
$iRide->destroySelf($iRide);
var_dump($iRide);echo " -after <br>";
?>
诀窍是 $this 不起作用,您需要通过对类的引用将实际引用传递给它。
访问实际引用而不传递它的另一种方法是将对象定义为全局对象:
class bike{
public $color = "black";
function destroySelf(){
global $iRide;
$iRide = NULL;
//$iRide = new bike();
}
}
$iRide = new bike();
$iRide->color = "red";
var_dump($iRide);echo " -before <br>";
$iRide->destroySelf();
var_dump($iRide);echo " -after <br>";
好吧,不,只有反过来,你可以使用神奇的 __destruct() 函数:
public function __destruct() {
//delete file
}
这将在有人 unset() 对象和脚本结束时触发。但是一个对象不能自我毁灭。
我和你有同样的问题,在某些时候我想让对象自己删除,但在 php 中是不可能的,所以这是一个可以帮助你的解决方法。
您可以设置一个私有标志并在每个需要该对象的方法中检查该标志仍然存在,例如:
<?php
class Bar {
// internal flag
private $_removed = false;
public function remove() {
// ... some code
$this->_removed = true;
}
private function checkExceptionRemoved() {
if ($this->_removed) throw new RuntimeException("The object has been removed");
}
public function show() {
$this->checkExceptionRemoved();
// ... some code
}
}
?>
其他方法可能是重载 _ call 方法并在调用该方法之前查看标志,这也可能需要使用诸如“pub ”之类的前缀重命名方法以在 __call 方法内进行调用。这是一个例子:
class Foo {
private $_value;
private $_valid = true;
public function IsValid() {
return $this->_valid;
}
private function IsValidException() {
if (!$this->IsValid()) throw new RuntimeException("The object has been removed");
}
public function __construct($value) {
$this->_value = $value;
}
public function __call($name, $arguments) {
if (!$this->IsValid()) throw new RuntimeException("The object has been removed");
if (!method_exists($this, "_$name")) throw new Exception("Invalid call, method '$name' does not exists");
return call_user_func_array(array($this, "_$name"), $arguments);
}
protected function _show() {
echo print_r($this->_value, true)."\n";
}
protected function _remove() {
$this->_valid = false;
}
}
$foo = new Foo("Foo Object");
$foo->show();
$foo->remove();
$foo->show(); // Exception !!!
?>
恕我直言,对象无法将自己从内存中删除是一个真正的问题,但它是 PHP 设计的一部分,它不是 C++。作为左派的想法,对于这个和其他事情,您可以在其他语言/库中传递应用程序的逻辑,这些语言/库是用 C++/C# 等其他语言开发的,并使用 PHP 来使用该逻辑,例如“HTML/CSS/JS/PlainText <-> PHP <-> C# Cli <-> 数据库/文件/存储"
如果您想同时删除对象及其包装的文件,请将您的删除代码放入析构函数中。然后只是unset
对象而不是调用删除方法。
如果你有课
class XXX
{
....
}
你有对象
$obj = new XXX();
您可以只使用 unset() 函数来删除对象
unset($obj);