PHPはデストラクタを好まない

PCPがOOP言語を宣言して以来、非常に多くの水が流れました。 正確な時期を明確にすることはできませんでしたが、2004年7月13日に、新しいZend Engine IIを搭載したPHP 5がリリースされました。 PHP 5には、オブジェクト指向プログラミングのサポートの改善などの新機能が含まれています。

つまり、理論的には、デザイナーとデストラクタがすでに登場しています。 私自身はバージョン5.3.2を使用していますが、彼はどこで起きたのでしょうか。





あなた自身について少し。 私はC ++プログラマで、4年の経験があります。 専門分野-コンピューターグラフィックスとネットワーク。 つまり、ネットワークゲームの作成。 しかし、そのようなゲームにはサーバーが必要であり、サーバーにはプレーヤーベースがあります。 また、プレイヤーはサイトも必要です。 「ウェブプログラマーを雇う理由は、私自身がかなり上手です。 言語も学びます。」

だから私は半年前に考えましたが、それでも理解できません!



クラシック


デストラクタで働いていた多くの人がかつて遭遇したと思います:

PHPの致命的エラー:行0のUnknownでスタックフレームなしで例外がスローされました

最初の反応は当惑です。 2番目のマット。 結局、どこでもexit()を押しても結果は得られません。なぜなら、デストラクタでの実行がすぐに行われないと推測され、それが発生した場合、おそらくコードベースが重要だからです。

回答c bugs.php.net/bug.php?id=33598

sniper@php.net:

Throwing exceptions in __desctruct() is not allowed.

Should be documented..

vrana@php.net:

Thank you for the report, and for helping us make our documentation better.

"Attempting to throw an exception from a desctructor causes a fatal error."






楽しんでください 個人的には、そうではありません。

暗黙の例外を伴うエラーの再現は非常に簡単です。

class a

{

// ...

public function __destruct()

{

global $_SESSION;

$_SESSION = "Some information";

}

}

$dummy = new a();







^注意、明示的な例外は時々正しく機能します。 影響する実験を掲載します。



逆洗浄順序


特定のスコープ内に次のコードがあると仮定します(グローバルではなく非常に):

$earth = new world();

$vasya = new human($earth);






したがって、人のコンストラクターのコードでは、彼は世界にプッシュされます。 (Vasyaは平和なくして存在しないと考えられています。哲学はさておき、まもなくプロジェクトを終了する必要があります。)

Vasyaのデストラクタコードには、ala $ this-> my_world-> RemoveHumanFromWorld($ this)が含まれており、RemoveAllMyStuff、CalculateKarmaなどが呼び出されます。 (私たちの世界では、Vasyaへのリンクはタスクの一部として必要ではなかったため、保存されていないと仮定します)

スコープを出るとき、phpは何をしますか? 世界を破壊し、「致命的なエラー:1956行の/home/god/my_projects/earth/creatures/reasonable/homo_sapiens.phpにある非オブジェクトのメンバー関数RemoveHumanFromWorld()の呼び出し」エラーでクラッシュします。

(そのため、ちなみに、世界はC ++で書かれています。なぜなら、神はどんな宇宙でも実行する必要がないからです。ガベージコレクターを備えた仮想空間。

bugs.php.net/bug.php?id=36759で返信します

dmitry@php.net

CVS HEADおよびPHP_5_2で修正されました。

このドミトリーを見つけ、その写真のように彼の鼻を突く。 最新バージョンではどのようになっているのかわかりません。まだ更新していませんが、5.3では関連しています。



スクリプトの完了は例外です


ああ、あなたはそれについてそんなに書くことができます。 グローバル変数(alaセッション)が無効になり、ファイルシステムへのアクセスが途切れます。 そして一般的に、私が理解しているように、スクリプトの正しい動作は保証されていません。 だから神はあなたがグローバルオブジェクトのデストラクタで何かをすることを禁じています...

しかし、これは省略されています。 PCP 5.1以前のドキュメント(スタンザと詩が見つかりません)では、「特定のオブジェクトへの他の参照がなくなるとすぐにデストラクタメソッドが呼び出されます」と書かれています。これは、原則として、厳密な削除構築要件(lat。設定解除)。

バグレポートの後bugs.php.net/bug.php?id=38572

ドキュメントが変更されました「デストラクタメソッドは、特定のオブジェクトへの参照がなくなるとすぐに、またはシャットダウンシーケンス中に任意の順序で呼び出されます」

便利ですか? 私にとって-そうでもない。



直接リンクのみ


言語のロジックに従って、オブジェクト$ aを$ bの前に削除する必要があるとします。

ただし、$ a-> some_dataフィールドへのリンクを$ bオブジェクトに保存します。

次に、論理的には、オブジェクト$ bをより早く残す必要があります。 悲しいかな、これはphpではそうではありません。 同様のバグは見つかりませんでしたが、状況は特定のものです(例外的な言葉は怖くありません)。 $ aへのリンクまで弱いパッチによって回避されますが、私は容認して報告しませんでした。



PHPスタイルのデッドロック


$ a-> ref = $ b;

$ b-> ref = $ a;

かつて、phpが相互参照にどのように対処するのかと思っていました。 ハングしますか? 「スコープから離れられない」という間違いがあり、英語でどのように聞こえるか。 悲しいかな、温室効果ガスはすべての変数が最後まで、それが来るまで、または「シャットダウンシーケンス中に任意の順序で」存在することを示しました



おわりに


現時点では、私が覚えていたことすべて。 または多分私が会ったすべて。 しかし、PCPのデストラクタは松葉杖であるという印象があったため、おそらくすぐにまたつまずくでしょう。

OOP Webプログラミングの未来はc ++インタープリターの背後にあり、おそらく準備ができていると思います。 誰かがいつかC ++を変更し、Web指向になるように標準の構造を追加することになるでしょう。 しかし、これまでのところ私は代替案を見つけていません。



参照資料


en.wikipedia.org/wiki/PHP

php.net/manual/en/language.oop5.decon.php

些細なことは何もありませんが:

[http://]。* php \ .net。*



All Articles