この記事では、PHP5のオブジェクトコピー技術を簡単なものから詳細なものまで解説します。 間違いや不適切な点があれば、ご指摘いただければ幸いです。
オブジェクトコピーの起源なぜオブジェクトに「コピー」という概念があるのでしょうか? これは、PHP5 のオブジェクトの値の転送方法と密接に関係しています。次の簡単なコードを見てみましょう。
PHPコード
/**
- *テレビカテゴリ
- */
- クラステレビ
- {
- /**
- *画面の高さ
- */
- 保護された $_screenLength = 300;
- /**
- *画面幅
- */
- 保護された $_screenHight = 200;
- /**
- ※テレビ出演カラー
- */
- 保護された $_color = '黒';
- /**
- ※テレビ出演カラーに戻ります
- */
- パブリック関数 getColor()
- {
- return $ this-> _color;
- }
- /**
- *テレビの外観色を設定します
- */
- パブリック関数 setColor($color)
- {
- $this->_color = (string)$color; $これを返します
- }
- }
- $tv1 = 新しいテレビ ();
- $tv2 = $tv1;
- このコードはテレビ クラス Television を定義します。$tv1 はテレビのインスタンスです。その後、通常の変数代入方法に従って $tv1 の値を $t2 に代入します。これで、$tv1 と $tv2 という 2 つのテレビができました。これは本当に事実でしょうか?試してみましょう。
- PHPコード
echo 'tv1 の色は: ' . $tv1->getColor();//tv1 の色は黒です
エコー '
';
エコー '
';
-
// tv2 を白にペイントします
- $tv2->setColor('白');
- echo 'tv2 の色は: ' . $tv2->getColor();//tv2 の色は白です
-
エコー '
';
echo 'tv1 の色は: ' . $tv1->getColor();//tv1 の色は白です - $tv1 = 新しいテレビ (); $tv2 = $tv1 をクローンします。
- echo 'tv1 の色は: ' . $tv1->getColor();//tv1 の色は黒です
-
エコー '
';
echo 'tv2 の色は: ' . $tv2->getColor();//tv2 の色は黒です - エコー '
- //tv2 を置き換えて白にペイントします
- $tv2->setColor('白');
- echo 'tv2 の色は: ' . $tv2->getColor();//tv2 の色は白です
- エコー '
- echo 'tv1 の色は: ' . $tv1->getColor();//tv1 の色は黒です
- このコードの 2 行目では、clone キーワードを使用して tv1 をコピーしています。これで、tv1 と tv2 の実際のコピーが作成されました。引き続き、コピーが成功したかどうかを確認します。 tv2 の色を白に変更しましたが、tv1 の色はまだ黒であることがわかり、コピー操作は成功しました。
- __クローンマジックメソッド
- /**
- *テレビカテゴリ
- */
- クラス テレビ
- {
- /**
- *テレビ番号
- */
- 保護された $_identity = 0;
- /**
- *画面の高さ
- */
- protected $_screenLength = 300;
- /**
- *画面幅
- */
- 保護された $_screenHight = 200;
- /**
- ※テレビ出演カラー
- */
- protected $_color = '黒';
- /**
- ※テレビ出演カラーに戻ります
- */
- パブリック関数getColor()
- {
- return $this->_color;
- }
- /**
- *テレビの外観色を設定します
- */
- パブリック関数 setColor($color)
- {
- $this->_color = (文字列)$color;
- $this を返します。
- }
- /**
- * TV番号に戻る
- */
- パブリック関数 getIdentity()
- {
- return $this->_identity;
- }
- /**
- *テレビ番号を設定します
- */
- パブリック関数 setIdentity($id)
- {
- $this->_identity = (int)$id;
- $this を返します。
- }
- パブリック関数 __clone()
- {
- $this->setIdentity(0);
- }
- }
- $tv1 = 新しいテレビ (); $tv1->setIdentity('111111');
- echo 'tv1 の ID は ' $tv1->getIdentity();//111111
-
エコー '
'; - $tv2 = $tv1 をクローンします。
- echo 'tv2 の ID は ' $tv2->getIdentity();//0
- テレビ セット tv1 を作成し、その番号を 111111 に設定しました。次に、clone を使用して tv1 をコピーし、__clone マジック メソッドがトリガーされました。このメソッドは、コピーされたオブジェクト tv2 に直接作用します。メソッドでは、setIdentity メンバー メソッドを呼び出して tv2 の _identity 属性をクリアし、後で番号を付け直すことができるようにします。このことから、__clone マジック メソッドを使用すると、オブジェクトのクローンを作成するときにいくつかの追加操作を非常に便利に実行できることがわかります。
- /**
- *テレビカテゴリ
- */
- クラス テレビ
- {
- /**
- *テレビ番号
- */
- 保護された $_identity = 0;
- /**
- *画面の高さ
- */
- protected $_screenLength = 300;
- /**
- *画面幅
- */
- 保護された $_screenHight = 200;
- /**
- ※テレビ出演カラー
- */
- protected $_color = '黒';
- /**
- * リモコンオブジェクト
- */
- protected $_control = null;
- /**
- * リモコンオブジェクトをコンストラクターにロードします
- */
- パブリック関数 __construct()
- {
- $this->setControl(new Telecontrol());
- }
- /**
- * リモコンオブジェクトを設定します
- */
- public function setControl(Telecontrol $control)
- {
- $this->_control = $control;
- $this を返します。
- }
- /**
- * リモコンオブジェクトを返します
- */
- パブリック関数 getControl()
- {
- return $this->_control;
- }
- /**
- ※テレビ出演カラーに戻ります
- */
- パブリック関数getColor()
- {
- return $this->_color;
- }
- /**
- *テレビの外観色を設定します
- */
- パブリック関数 setColor($color)
- {
- $this->_color = (文字列)$color;
- $this を返します。
- }
- /**
- * TV番号に戻る
- */
- パブリック関数 getIdentity()
- {
- $ this-& gt; を返します。 }
- /**
- *テレビ番号を設定します
- */
- パブリック関数 setIdentity($id)
- {
- $this->_identity = (int)$id;
- $これを返します
- }
- パブリック関数 __clone()
- {
- $this->setIdentity(0);
- }
- }
- /**
- *リモコンカテゴリ
- */
- クラステレコントロール
- {
- }
- $contr1 = $tv1->getControl(); //tv1 のリモコン contr1 を取得します
- $contr2 = $tv2->getControl(); //tv2 のリモコン contr2 を取得します
- echo $tv1; //tv1 のオブジェクト ID は #1 です
-
エコー '
';
echo $contr1; // contr1 のオブジェクト ID は #2 です - エコー '
- echo $tv2; //tv2 のオブジェクト ID は #3 です
-
エコー '
';
echo $contr2; // contr2 のオブジェクト ID は #2 です - コピー後、オブジェクト ID を確認し、クローン操作によって tv1 から tv2 をコピーします。tv1 と tv2 のオブジェクト ID はそれぞれ 1 と 3 です。これは、tv1 と tv2 が 2 つの異なる TV オブジェクトを参照していることを意味します。これは、クローンと一致しています。の操作の結果。次に、tv1 のリモコン オブジェクト contr1 と tv2 のリモコン オブジェクト contr2 をそれぞれ取得しました。それらのオブジェクト ID を確認すると、contr1 と contr2 のオブジェクト ID は両方とも 2 であり、同じものへの参照であることがわかります。オブジェクト、つまり、tv1 から tv2 をコピーしたが、リモコンはコピーされていないというのは明らかに不合理です。各テレビにはリモコンが装備されているはずであり、ここで tv2 と tv1 はリモコンを共有しています。
- クローン操作には非常に大きな欠陥があることがわかります。クローン操作を使用してオブジェクトをコピーする場合、コピーされたオブジェクトに他のオブジェクトへの参照がある場合、参照されたオブジェクトはコピーされません。ただし、この状況は現在、「継承の再利用」に代わる「合成/集約の再利用」が主に提唱されており、「合成」と「集約」は、あるオブジェクトに別のオブジェクトへの参照を持たせることで、それを再利用します。参照されるオブジェクトのメソッド。クローンを使用する場合は、この状況を考慮する必要があります。では、オブジェクトを複製するときにこのような欠陥をどのように解決すればよいでしょうか?おそらく、前述の __clone マジック メソッドをすぐに思いついたかもしれません。これは確かに解決策です。
- パブリック関数 __clone()
- {
- $this->setIdentity(0); // リモート コントロール オブジェクトをリセットします
- $this->setControl(new Telecontrol());
- }
- $contr1 = $tv1->getControl(); //tv1 のリモコン contr1 を取得します
- $contr2 = $tv2->getControl(); //tv2 のリモコン contr2 を取得します
- echo $tv1; //tv1 のオブジェクト ID は #1 です
- エコー '
- echo $contr1; // contr1 のオブジェクト ID は #2 です
-
エコー '
';
echo $tv2; //tv2 のオブジェクト ID は #4 です - エコー '
- echo $contr2; // contr2 のオブジェクト ID は #5 です
- 出力を見ると、tv1 と tv2 に異なるリモコンがあることがわかります。これは、オプション 1 よりもはるかに便利です。シリアル化は再帰的なプロセスです。オブジェクト内で参照されるオブジェクトの数や、オブジェクトを完全にコピーできるレイヤーの数を気にする必要はありません。このソリューションを使用する場合、__clone マジック メソッドをトリガーして追加の操作を完了することはできないことに注意してください。 もちろん、ディープ コピー後に再度クローン操作を実行して __clone マジック メソッドをトリガーすることはできますが、効率には多少の影響があります。さらに、この解決策はコピーされたオブジェクトとすべての参照オブジェクトの __sleep および __wakeup マジック メソッドをトリガーするため、これらの状況を考慮する必要があります。
- まとめ
まず、tv1 と tv2 の色が両方とも黒であることがわかります。次に、tv2 の色を変更したいので、その色を白に設定します。実際に、一致しているように見えます。要件は満たしていましたが、tv1 の色を確認すると、期待したほどスムーズではありませんでした。 tv1 の色をリセットしなかったのはなぜですか?なぜなら、PHP5におけるオブジェクトの代入や値の受け渡しはすべて「参照」によって行われるからです。 PHP5 は Zend Engine II を使用しており、オブジェクトは他の一般変数のように Zval に保存されるのではなく、別の構造のオブジェクト ストアに保存されます (PHP4 では、オブジェクトは一般変数と同様に Zval に保存されます)。オブジェクトの内容 (値) ではなく、オブジェクトのポインターのみが Zval に格納されます。オブジェクトをコピーする場合、またはオブジェクトをパラメーターとして関数に渡す場合、データをコピーする必要はありません。同じオブジェクト ポインターを保持し、この特定のオブジェクトが別の zval を介してポイントしていることをオブジェクト ストアに通知するだけです。オブジェクト自体はオブジェクト ストアに配置されているため、オブジェクトに加えた変更は、そのオブジェクトへのポインタを保持するすべての zval 構造に影響します。これは、ターゲット オブジェクトに対する変更がソース オブジェクトに影響するため、プログラムに明示されています。これにより、PHP オブジェクトが常に参照によって渡されるように見えます。したがって、上記の tv2 と tv1 は実際には同じ TV インスタンスを指しており、tv1 または tv2 で行う操作は実際にはこの同じインスタンスに対するものです。したがって、「コピー」は失敗しました。このため、PHP5 ではオブジェクトのコピーに特化した操作 (clone) が提供されています。ここでオブジェクトのコピーが登場します。
クローンを使用してオブジェクトをコピーします
PHP5 のクローン言語構造を使用してオブジェクトをコピーするコードは次のとおりです:
PHPコード
';
';
ここで、各テレビに独自の番号が必要であるという状況を考えます。この番号は、ID 番号と同様に一意である必要があるため、テレビをコピーするときに、トラブルを避けるために番号もコピーされることは望ましくありません。私たちが考え出した戦略の 1 つは、割り当てられている TV 番号をクリアし、必要に応じて番号を再割り当てすることです。
このような問題を解決するために、__clone マジック メソッドが特に使用されます。オブジェクトがコピーされる (つまり、クローン操作) ときに、__clone マジック メソッドがトリガーされます。 TV クラス Television のコードを変更し、number 属性と __clone メソッドを追加しました。コードは次のとおりです。
PHPコード
以下では、このようなテレビのオブジェクトを作成します。
PHP代
クローン操作の致命的な欠陥
クローンは本当に理想的なコピー効果を実現できるのでしょうか?場合によっては、クローン操作が想像したほど完璧ではないことがわかるはずです。上記の TV タイプを変更してテストしてみましょう。
各テレビにはリモコンが付属しているので、リモコンのクラスを開きます。リモコンとテレビは「集合」関係です (「組み合わせ」関係と比較すると、依存関係は弱いです。一般的に言えば、次のとおりです)。テレビはリモコンがなくても通常どおり使用できます)。これで、TV オブジェクトはすべてリモコン オブジェクトへの参照を保持するはずです。以下のコードを見てください
PHPコード
次に、そのような TV オブジェクトをコピーし、TV のリモコン オブジェクトを観察します。
PHPコード
$tv1 = 新しいテレビ ();
-
$tv2 = $tv1 をクローンします。
';
__clone マジック メソッドの使用についてはすでに紹介しました。コピーされたオブジェクト内の他のオブジェクトの参照を、__clone メソッド内の新しいオブジェクトに再参照できます。変更された __clone() マジック メソッドを見てみましょう:
PHPコード
04 行目では、コピーした TV オブジェクトのリモコンをリセットします。前の方法に従ってオブジェクト ID を確認すると、2 つの TV のリモコンのオブジェクト ID が異なることがわかり、問題は解決されました。
しかし、この方法はおそらくあまり良くありません。コピーされたオブジェクトに他のオブジェクトへの参照が複数ある場合、__clone メソッドでそれらを 1 つずつリセットする必要があります。さらに悪いことに、コピーされたオブジェクトのクラスが によって提供されている場合です。ただし、コードを変更することはできないため、コピー操作は基本的にスムーズに完了しません。
オブジェクトをコピーするにはクローンを使用します。この種のコピーは「浅いコピー」と呼ばれます。コピーされたオブジェクトのすべての変数には元のオブジェクトと同じ値が含まれており、他のオブジェクトへの参照はすべて元のオブジェクトを指し続けます。つまり、浅いコピーは、参照しているオブジェクトではなく、問題のオブジェクトのみをコピーします。 「浅いコピー」と比較すると、もちろん「深いコピー」もあります。コピーされたオブジェクトのすべての変数には、他のオブジェクトを参照する変数を除き、元のオブジェクトと同じ値が含まれます。つまり、ディープ コピーでは、コピー対象のオブジェクトが参照するすべてのオブジェクトがコピーされます。ディープ コピーでは、何層まで進むかを決定する必要がありますが、これは簡単に決定できない問題であり、さらに、循環参照の問題が発生する可能性があるため、慎重に処理する必要があります。オプション 2 はディープ コピー ソリューションです。
解決策 2: ディープコピーにシリアル化を使用する
PHP にはシリアル化 (シリアル化) 関数と逆シリアル化 (アンシリアル化) 関数があり、serialize() を使用してオブジェクトをストリームに書き込み、ストリームからオブジェクトを読み取るだけで、オブジェクトがコピーされます。 JAVA 言語では、このプロセスは「冷却」および「解凍」と呼ばれます。以下でこのメソッドをテストします:
PHPコード
$tv1 = 新しいテレビ ();
-
$tv2 = unserialize(serialize($tv1));//シリアル化してから逆シリアル化します
';
';
オブジェクトのコピー方法が異なれば効果も異なります。どの方法を使用するか、特定のアプリケーション要件に基づいてコピー方法を改善する方法を検討する必要があります。 PHP5 のオブジェクト指向機能は比較的 JAVA に近いので、JAVA から多くの貴重な経験を学ぶことができると思います
。
PHPは、電子商取引、コンテンツ管理システム、API開発で広く使用されています。 1)eコマース:ショッピングカート機能と支払い処理に使用。 2)コンテンツ管理システム:動的コンテンツの生成とユーザー管理に使用されます。 3)API開発:RESTFUL API開発とAPIセキュリティに使用されます。パフォーマンスの最適化とベストプラクティスを通じて、PHPアプリケーションの効率と保守性が向上します。

PHPにより、インタラクティブなWebコンテンツを簡単に作成できます。 1)HTMLを埋め込んでコンテンツを動的に生成し、ユーザー入力またはデータベースデータに基づいてリアルタイムで表示します。 2)プロセスフォームの提出と動的出力を生成して、XSSを防ぐためにHTMLSPECIALCHARSを使用していることを確認します。 3)MySQLを使用してユーザー登録システムを作成し、Password_HashおよびPreprocessingステートメントを使用してセキュリティを強化します。これらの手法を習得すると、Web開発の効率が向上します。

PHPとPythonにはそれぞれ独自の利点があり、プロジェクトの要件に従って選択します。 1.PHPは、特にWebサイトの迅速な開発とメンテナンスに適しています。 2。Pythonは、データサイエンス、機械学習、人工知能に適しており、簡潔な構文を備えており、初心者に適しています。

PHPは依然として動的であり、現代のプログラミングの分野で重要な位置を占めています。 1)PHPのシンプルさと強力なコミュニティサポートにより、Web開発で広く使用されています。 2)その柔軟性と安定性により、Webフォーム、データベース操作、ファイル処理の処理において顕著になります。 3)PHPは、初心者や経験豊富な開発者に適した、常に進化し、最適化しています。

PHPは、現代のWeb開発、特にコンテンツ管理とeコマースプラットフォームで依然として重要です。 1)PHPには、LaravelやSymfonyなどの豊富なエコシステムと強力なフレームワークサポートがあります。 2)パフォーマンスの最適化は、Opcacheとnginxを通じて達成できます。 3)PHP8.0は、パフォーマンスを改善するためにJITコンパイラを導入します。 4)クラウドネイティブアプリケーションは、DockerおよびKubernetesを介して展開され、柔軟性とスケーラビリティを向上させます。

PHPは、特に迅速な開発や動的なコンテンツの処理に適していますが、データサイエンスとエンタープライズレベルのアプリケーションには良くありません。 Pythonと比較して、PHPはWeb開発においてより多くの利点がありますが、データサイエンスの分野ではPythonほど良くありません。 Javaと比較して、PHPはエンタープライズレベルのアプリケーションでより悪化しますが、Web開発により柔軟性があります。 JavaScriptと比較して、PHPはバックエンド開発により簡潔ですが、フロントエンド開発のJavaScriptほど良くありません。

PHPとPythonにはそれぞれ独自の利点があり、さまざまなシナリオに適しています。 1.PHPはWeb開発に適しており、組み込みのWebサーバーとRich Functionライブラリを提供します。 2。Pythonは、簡潔な構文と強力な標準ライブラリを備えたデータサイエンスと機械学習に適しています。選択するときは、プロジェクトの要件に基づいて決定する必要があります。

PHPは、サーバー側で広く使用されているスクリプト言語で、特にWeb開発に適しています。 1.PHPは、HTMLを埋め込み、HTTP要求と応答を処理し、さまざまなデータベースをサポートできます。 2.PHPは、ダイナミックWebコンテンツ、プロセスフォームデータ、アクセスデータベースなどを生成するために使用され、強力なコミュニティサポートとオープンソースリソースを備えています。 3。PHPは解釈された言語であり、実行プロセスには語彙分析、文法分析、編集、実行が含まれます。 4.PHPは、ユーザー登録システムなどの高度なアプリケーションについてMySQLと組み合わせることができます。 5。PHPをデバッグするときは、error_reporting()やvar_dump()などの関数を使用できます。 6. PHPコードを最適化して、キャッシュメカニズムを使用し、データベースクエリを最適化し、組み込み関数を使用します。 7


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境
