3

ArrayAccessを実装するクラスを作成し、WRITEアクションを防止する関数を追加しました。

 $Obj->Add("key","something");
 $Obj->Add("key2","something2");
 $Obj->SetReadOnly(); // sets read only property
 unset($Obj["key2"]); // throws error, object is readonly

しかし、私もオブジェクトの設定を解除しないようにしたいです:

 unset($Obj);

私はそれをすることができますか?私は提案を聞きます。手伝ってくれてありがとう!。

4

4 に答える 4

2

unset()それがあなたが防ごうとしているものであれば、実際にはオブジェクトを破壊しません。

オブジェクトは、それへのすべての参照が設定解除されているか、スコープ内にない場合にのみ破棄されます。それでも、ガベージ コレクターが実行されるまでは発生しません。

そのため、オブジェクトを悪用するのではないかと心配しているコードがある場合は、読み取り専用ロジックでコードを不変にするという良い仕事をすでに行っています。

あなたが持っているとしましょう

$Obj = gotMyObjectSomehow();

$Obj を設定解除したくない他のコードにそれを渡す必要があります。そのコードが関数内で呼び出される限り、心配する必要はありません。電話すれば

someFunction($Obj);

そして、関数が渡されたパラメーターの設定を解除するとしましょう

function someFunction($anObj) {
    unset($anObj);
}

その後、元の$Obj変数は引き続き設定されます。

この関数は、元のオブジェクトを参照する 2 番目の変数を作成し、それを独自のスコープで使用します。

于 2012-10-26T06:58:03.223 に答える
2

あなたが本当にこれをやりたいと思うような状況は想像できません。また、これを行うと、すべてのオブジェクトが破棄されるスクリプトの終了時に深刻な問題が発生することも想像できます。PHP のマニュアルでは、デストラクタでの例外のスローについて次のように述べています。

ノート:

(スクリプトの終了時に呼び出される) デストラクタから例外をスローしようとすると、致命的なエラーが発生します。

上記のステートメントは、スクリプトの終了フェーズにない場合に例外をスローできることを意味しているため、次のことが可能である可能性があります。

public function __destruct ()
{
    if ($this -> isReadOnly ())
    {
        throw new Exception ('Class is read-only');
    }
}

ただし、マニュアルで指摘されているように、これによりスクリプトのシャットダウン中に致命的なエラーが発生します。

正直なところ、オブジェクトの破壊を防ぎたいと思う意味がわかりません。オブジェクトの有効期間を管理するのはプログラマ次第です。

于 2012-10-26T06:37:49.757 に答える
1

これらの名前は技術的に参照されるオブジェクトの一部ではないため、変数名の設定解除を制御することはできません。次の点を考慮してください。

$a = new MyObject();
$b = $a;

これで、同じオブジェクトへの2 つの参照ができました。との使用に違いはありません。PHP ではオブジェクトは常に参照によって使用されるためです (つまり、2 行目で行う必要はありません)。したがって、とは本質的に同じオブジェクトです。設定を解除してもオブジェクトは破壊されず、設定を解除してもオブジェクトは破壊されません。オブジェクトを破棄する前に、すべての参照を設定解除する必要があります。$a$b$b =& $a$a$b$a$b

于 2012-10-26T06:56:57.430 に答える
0

私はあなたがあなたが求めていることをすることができるとは思いません-そのように変数が設定解除されるのを防ぐことはできません。

しかし、上記のあなたのコメントは私に考えさせました。あなたが言った:

....サードパーティの拡張機能でシステム変数が設定されないようにしたい場合のアイデア

それで、私があなたを正しく理解しているなら、ここでのあなたの目的は、サードパーティのコード(つまりあなたのソフトウェア)が使用されている間、それに関連するすべての変数がそのまま残ることを保証することですか?

これで、このシステムにどの変数があるかについてはあまり指定していません。質問に1つのオブジェクトがありますが、おそらくそれ以上あるはずですか?たくさんのことを結びつけていると思いますよね?この種の質問では、もう少しコンテキストを提供するのに役立ちます。あなたが求めている実際のことは不可能ですが、あなたが何を達成したいのかについて少し理解すれば、私たちは代替案を考え出すことができます。

わかった。だから私の提案:あなたのオブジェクトをシングルトンとして作成してください。これは純粋主義者にしばしば眉をひそめられますが、あなたがしていることによっては、この状況ではうまくいくかもしれません。ここでの利点は、オブジェクトへのすべてのアクセスをクラスメソッド内にカプセル化できることです。つまり、コードを使用する開発者は、オブジェクトの設定を解除するためにオブジェクトのマスターコピーにアクセスできません。

シングルトンは次のように機能します。

<?php
class mySingletonClass {
    private static $masterObject=null;

    public static function getInstance() {
        if(!isset(self::$masterObject)) {
            self::$masterObject = new self;
        }
        return self::$masterObject;
    }

    private function __construct() {
        //your existing constructor, as it already exists, but marked as private.
    }

    //...and all the other methods as you already have them.
}

クラスコンストラクタメソッドはプライベートであるため、クラス内のメソッドからのみアクセスできます。したがって、あなたはもうすることができませんnew classname()。このクラスのオブジェクトを取得する唯一の方法は、静的getInstance()メソッドから取得することです。そして、ここで重要なことは、このメソッドが常にオブジェクトの同じコピーを返すことです。

$obj = mySingletonClass::getInstance();
unset($obj);
$obj = mySingletonClass::getInstance();  //will give the exact same object as the first time.

必要に応じて設定を解除できますが、元のオブジェクトは引き続き存在し、引き続きアクセスできます。他のクラスは、そのgetInstance()メソッドを使用して、プログラムのどこからでも同じオブジェクトの同じコピーを取得できます。これは破壊不可能なグローバル変数です。

シングルトンは、プログラムのメインデータベース接続オブジェクトによく使用されますが、ここでは便利なパターンになる可能性があります。

それがお役に立てば幸いです。それは私があなたが望むものに近づくために考えることができる唯一の方法についてです。

于 2012-10-26T20:51:56.137 に答える