ファイルラッパーのように機能するクラスを作成しました。ユーザーがdeleteメソッドを呼び出すとき、オブジェクト(実際には$ 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() したとき、およびスクリプトが終了したときにトリガーされます。しかし、オブジェクトはそれ自体を破壊することはできません。
オブジェクトとそれがラップするファイルを同時に削除したい場合は、削除コードをデストラクタに入れます。次にunset
、delete メソッドを呼び出す代わりに、オブジェクトだけを呼び出します。
私はあなたと同じ問題を抱えています。ある時点でオブジェクト自体を削除したいのですが、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 を使用してそのロジックを消費することができます。 <-> PHP <-> C# Cli <-> DB/ファイル/ストレージ"