PHP のオブジェクト処理部分の中核は、より多くの機能を提供し、パフォーマンスを向上させるために完全に再開発されました。以前のバージョンの PHP では、オブジェクトは基本型 (数値、文字列) と同じ方法で処理されました。この方法の欠点は、オブジェクトを変数に代入するとき、またはオブジェクトをパラメータに渡すときに、オブジェクトが完全にコピーされてしまうことです。新しいバージョンでは、上記の操作は値の代わりに参照 (参照はオブジェクトの識別子として理解できます) を渡します。
多くの PHP プログラマーはオブジェクトの古い処理方法を知らないかもしれません。実際、ほとんどの PHP アプリケーションは問題なく動作します。または、最小限の変更のみが必要です。
プライベートおよび保護されたメンバー
PHP5 では、プライベートおよび保護されたメンバー変数の概念が導入されました。これを使用して、クラス メンバーの可視性を定義できます。
例
保護されたメンバーにはサブクラスからアクセスできますが、プライベート メンバーにはクラス自体からのみアクセスできます。
class MyClass {
private $Hello = "Hello, World!n";
protected $Bar = "Hello, Foo!n"; $Foo = "Hello, Bar!n";
function printHello() {
print "MyClass::printHello() " . $this->Hello; printHello() " . $this->Bar;
print "MyClass::printHello() " . $this->Foo;
}
}
class MyClass2 extends MyClass {
protected $Foo;
function printHello() {
MyClass::printHello(); /* print
"MyClass2::printH ello() " . this ->Hello; /* 何も出力しません */
print "MyClass2::printHello() " . $this->Bar; /* 出力しません (宣言されていません) */
print "MyClass2::printHello() " . $this->Foo; /* 出力する必要があります */
}
}
$obj = new MyClass(); $ obj->Hello; /* 何も出力しません */
print $obj->Bar; /* 何も出力しません */
print $obj->Foo; * 何も出力しません */
$obj->printHello(); /* 出力する必要があります */
$obj = new MyClass2();
print $obj->;こんにちは ; /* 何も出力しません */
print $obj->Bar; /* 何も出力しません */
print $obj->Foo; out anything */
$obj->printHello();
?>
プライベート メソッドと保護されたメソッド
PHP5 では、プライベート メソッドと保護されたメソッドの概念も導入されています。
例:
class Foo {
private function aPrivateMethod() {
echo "Foo::aPrivateMethod() called.n";
}
保護された関数 aProtectedMethod() {
echo "Foo::aProtectedMethod() known.n";
$this->aPrivateMethod()
}
>
class Bar extends Foo {
public function aPublicMethod() {
echo "Bar::aPublicMethod() added.n";
$this->aProtectedMethod(); }
}
$o = new Bar;
$o->aPublicMethod();
以前はクラスを使用していなかった古いコードアクセス修飾子 (public、protected、private) を含むコードは変更せずに実行できます。
抽象クラスと抽象メソッド
Php5 では、抽象クラスと抽象メソッドの概念も導入されました。抽象メソッドはメソッドの署名を宣言するだけで、その実装は提供しません。抽象メソッドを含むクラスは抽象として宣言する必要があります。
例:
abstract class AbstractClass {
abstract public function test();
}
class ImplementedClass extends AbstractClass {
public function test() {
echo "ImplementedClass::test() added.n";
}
}
$o = new ImplementedClass; test();
?>
抽象クラスをインスタンス化できません。抽象クラスを使用していない古いコードは変更せずに実行できます。
インターフェース
Php5 で導入されたインターフェース。クラスは複数のインターフェイスを実装できます。
例:
インターフェース Throwable {
public function getMessage();
}
class MyException 実装 Throwable {
public function getMessage() {
>
クラス型ヒント
PHP5 は依然として弱い型指定ですが、関数パラメータを定義するときにクラス型ヒントを使用して、期待されるオブジェクト型を宣言できます
例
interface Foo {
function a(Foo $foo)
}
interface Bar {
function b(Bar $bar) );
}
class FooBar 実装 Foo, Bar {
function a(Foo $foo) {
function b (Bar $bar) {
a->a( $b);
$a->b($b);
?>
他の強く型付けされた言語と同様に、php5 クラスの型ヒントは実行中ではなく実行時にチェックされます。編集。つまり、
function foo(ClassName $object) {
// ...
}
?>以下のコードは同じです:
function foo($object) {
if (!($objectinstanceof ClassName)) {
die("引数 1 でなければなりませんClassName") のインスタンスである必要があります。
}
}
?>
この構文はクラスにのみ適用され、組み込み型には適用されません。
Final
PHP 5 では、final メンバーと Final メソッドを宣言するための Final キーワードが導入されました。 Final メンバーと Final メソッドはサブクラスによってオーバーライドできません。
例
class Foo {
final function bar() {
さらに、クラスをfinalとして宣言できます。クラスをfinalと宣言すると、クラスが継承されなくなります。最終クラスのメソッドはデフォルトで Final であるため、再度宣言する必要はありません。
例
final class Foo {
// クラス定義
}
// 次の行は不可能
// class Bork extends Foo {}
?>
プロパティを Final として定義することはできません。
を変更せずに実行できます。オブジェクトの複製
Php4 には、ユーザーがオブジェクトのコピー プロセスを制御する独自のコピー コンストラクターを定義するメカニズムが提供されていません。 Php4 はバイナリ コピーを実行するため、オブジェクトのすべてのプロパティを非常に正確に複製します。
オブジェクトのすべてのプロパティを正確にコピーすることは、私たちが常に望んでいることではないかもしれません。 GTK Window オブジェクトなどのコピー コンストラクターが必要であることを示す例があります。 a には必要なすべてのリソースが保持されます。この GTK ウィンドウをオブジェクト b にコピーするときは、b が新しいリソース オブジェクトを保持することを推奨します。別の例: オブジェクト a をオブジェクト c にコピーすると、オブジェクト a にはオブジェクト c が含まれます。オブジェクト b には、オブジェクト c への参照ではなく、新しいオブジェクト c のコピーが含まれる方が望ましい場合があります。 (翻訳者注: ここで説明しているのは、シャロー クローン作成とディープ クローン作成です。)
オブジェクトのコピーは、clone キーワードを通じて実行されます (Clone は、クローン化されたオブジェクトの __clone() メソッドを呼び出します)。オブジェクトの __clone メソッドを直接呼び出すことはできません。
$copy_of_object = clone $object;
?>
開発者がオブジェクトのコピーを作成すると、php5 は __clone() メソッドが存在するかどうかを確認します。 。存在しない場合は、デフォルトの __clone() メソッドを呼び出して、オブジェクトのすべての属性をコピーします。__clone() メソッドが定義されている場合、 _clone() メソッドは新しいオブジェクトのプロパティを設定します。便宜上、エンジンはデフォルトですべてのプロパティをコピーします。したがって、__clone() メソッドでは、変更する必要があるプロパティを上書きするだけで済みます。以下のように:
例
class MyCloneable {
static $id = 0;
function MyCloneable() {
$this->id = self ::$id ;
function __clone() {
$this->address = "ニューヨーク"; id ;
}
}
$obj = new MyCloneable();
$obj->name = "Hello"; = "テルアビブ";
print $obj->id . "n"; id . "n";
print $obj_cloned->name . "n";
Php5 では、開発者がクラスのコンストラクターを宣言できます。コンストラクターを持つクラスは、新しいオブジェクトを作成するたびにこのメソッドを呼び出すため、コンストラクターはオブジェクトを使用する前に初期化するのに適しています。
Php4 では、コンストラクターの名前は名前と同じです。クラスの。サブクラスのコンストラクターから親クラスのコンストラクターを呼び出すことが非常に一般的であり、継承システムからクラスを再配置することによって親クラスが変更されると、クラスのコンストラクターを変更する必要が生じることがよくあることを考慮すると、php4 のアプローチは明らかにあまり適切ではありません。 。 合理的。
Php5 では、コンストラクター関数を宣言する標準的な方法 __construct() が導入されました。次のようになります。
例
class BaseClass {
function __construct() ) {
print "In BaseClass コンストラクター";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct(); 🎜 > print "サブクラスコンストラクター内";
}
}
$obj = new BaseClass();
$obj = new SubClass()>; >
下位互換性を維持するために、php5 が __construct() を見つけられない場合、クラスと同じ名前のメソッドである昔ながらのコンストラクター メソッドを探します。簡単に言えば、古いコードに __construct() メソッドが含まれている場合にのみ、互換性の問題が発生します。
破棄メソッド
オブジェクト指向プログラミングの場合、デストラクター メソッドを定義できることは非常に便利な機能です。デストラクター メソッドは、デバッグ情報の記録、データベース接続の終了、その他のクリーンアップ作業に使用できます。 Php4 にはデストラクター メソッドはありませんが、php4 はリクエストの終了時に呼び出される関数を登録する機能をすでにサポートしています。
Php5 で導入されたデストラクター メソッドの概念は、他のオブジェクト指向言語 (Java など) と一致しています。このオブジェクトへの最後の参照が破棄されると、デストラクター メソッドが呼び出され、呼び出しの完了後にメモリが解放されます。注: デストラクター メソッドはパラメーターを受け入れません。
例
class MyDestructableClass {
function __construct() {
print "コンストラクター内"
$this->name = "MyDestructableClass"; ;
}
function __destruct() {
print "破壊中" . "n";
}
}
$ obj = new MyDestructableClass();
?>
構築メソッドと同様に、親クラスのデストラクター メソッドは暗黙的に呼び出されません。サブクラスは、parent::__destruct() を呼び出すことで、独自のデストラクター内で明示的にこれを呼び出すことができます。
定数
Php5 ではクラスレベルの定数が導入されました。
class Foo {
const constant = "constant";
}
echo "Foo::constant = " 。 "n";
?>
const を使用しない古いコードは引き続き正常に実行されます。
例外
Php4 には例外制御がありません。 Php5 では、他の言語 (Java) と同様の例外制御モデルが導入されています。 php5 はすべての例外のキャッチをサポートしていますが、finally 句はサポートしていないことに注意してください。
catch ステートメント ブロックでは、例外を再スローできます。複数の catch ステートメントが存在する場合もあります。この場合、キャッチされた例外は上から下に向かって比較され、タイプが一致する最初の catch ステートメントが実行されます。最後まで検索しても一致する catch 句が見つからない場合は、次の try/catch ステートメントを探します。キャッチできなかった最後の例外が表示されます。例外がキャッチされると、プログラムは catch ステートメント ブロックの下で実行を開始します。
例
class MyException {
function __construct($Exception) {
$this->Exception = $Exception;
}
function Display() {
print "MyException: $this->Exceptionn";
}
}
class MyExceptionFoo extends MyException {
function __construct($Exception) ) {
$this->例外 = $例外;
}
function Display() {
print "MyException: $this->Exceptionn";
🎜>}
try {
throw new MyExceptionFoo('Hello');
}
catch (MyException $Exception) {
$Exception->Display(); 🎜>}
catch (Exception $Exception) {
echo $Exception;
}
?>
上記の例は、次のような例外を定義できることを示しています。 Exception クラスから継承することはできませんが、Exception から継承して独自の例外を定義することをお勧めします。これは、システムの組み込み Exception クラスは多くの有用な情報を収集できるが、それを継承しない例外クラスはこの情報を取得できないためです。次の PHP コードは、システムの組み込み Exception クラスを模倣します。各属性の後にはコメントが続きます。各プロパティにはゲッターがあります。これらのゲッター メソッドはシステムの内部処理によって呼び出されることが多いため、これらのメソッドは Final としてマークされます。
例
class Exception {
function __construct(string $message=NULL, int code=0) {
if (func_num_args()) {
$this->メッセージ = $メッセージ;
}
$this->code = $code;
$this->file = __FILE__; // throw 句の
$this->line = __LINE__; // throw 句の
$this->trace = debug_backtrace();
$this->string = StringFormat($this);
}
protected $message = '不明な例外'; // 例外 メッセージ
protected $code = 0; // ユーザー定義の例外コード
protected $file; // 例外のソース ファイル名
protected $line; // 例外のソース行
private $trace; // 例外のバックトレース
private $string; // 内部のみ!!
final function getMessage() {
return $this->message;
}
final function getCode() {
return $this->code;
}
final function getFile() {
return $this->file;
}
final function getTrace() {
return $this->trace;
}
final function getTraceAsString() {
return self::TraceFormat($this);
}
function _toString() {
return $this->string;
}
static private function StringFormat(Exception $Exception) {
//...PHP スクリプトでは利用できない関数
// すべての関連情報を文字列として返す
}
静的プライベート関数 TraceFormat(Exception $Exception) {
//...PHP スクリプトでは利用できない関数
// バックトレースを文字列として返す
}
}
?>
私が定義した場合、例外ベースの種類
の互換性の問題から継承されています。古い世代コードはこの特性の影響を受けません。
逆参照関数から返されたオブジェクト
Php4 では関数から返されたオブジェクトを再度参照することはできませんが、呼び出しによってオブジェクトを返す方法がありますが、php5 では可能です。
class Circle {
function draw() {
print "Circlen";
}
}
class Square {
function draw() {
print "Square";
}
}
function ShapeFactoryMethod($shape) {
switch ($shape) {
case "Circle":
return new Circle();
case "Square":
return new Square();
}
}
ShapeFactoryMethod("Circle")->draw();
ShapeFactoryMethod("Square")->draw();
?>
は静的に初期化できます。
例
class foo {
static $my_static = 5;
public $my_prop = 'bla';
}
print foo: :$my_static;
$obj = new foo;
print $obj->my_prop;
?>PHP 5 では静的メソッドが導入されました。クラスをインスタンス化せずに静的メソッドを呼び出す場合に使用されます。
例
class Foo {
public static function aStaticMethod() {
🎜>Foo::aStaticMethod()
?<🎜; >
疑似変数 $this は静的メソッドでは使用できません。
instanceof
Php5 では、instanceof キーワードが導入され、オブジェクトがクラスのインスタンスであること、派生クラスのインスタンスであること、またはインターフェイス
を実装していることをテストするために使用できるようになりました。例
classbaseClass { }
$a = new baseClass;
if ($ainstanceofbaseClass) {
echo "Hello World";
}
?>
静的関数変数
これで、静的変数はコンパイル段階で処理されます。したがって、プログラマは参照によって静的変数に値を割り当てることができます。これによりパフォーマンスが向上しますが、静的変数への間接参照は使用できません。
参照によって渡される関数パラメータにもデフォルト値を設定できるようになりました。
例
function my_function(&$var = null) {
if ($var === null) {
die("$var は値があります");
}
}
?>
__autoload()
__autoload() インターセプト関数は、宣言されていないクラスが初期化されるときに自動的に呼び出されます。クラスの名前は、__autoload() 関数に自動的に渡されます。また、__autoload() にはパラメータが 1 つだけあります。
例
function __autoload($className) {
include_once $className . ".php";
}
$object = new ClassName;
?>
オーバーロード可能なメソッド呼び出しと属性アクセス
メソッド呼び出しと属性アクセスは、__call、__get()、__set() メソッドを通じてオーバーロードできます。
例: __get() および __set()
class Setter {
public $n;
public $x = array("a" => 1, "b" => 2, "c" => 3);
function __get($nm) {
print "[$nm]n を取得しています";
if (isset($this->x[$nm])) {
$r = $this->x[$nm];
print "Returning: $rn";
$r を返す;
} else {
print "何もありません!n";
}
}
function __set($nm, $val) {
print "[$nm]を$valnに設定します";
if (isset($this->x[$nm])) {
$this->x[$nm] = $val;
print "OK!n";
} else {
print "Not OK!n";
}
}
}
$foo = new Setter();
$foo->n = 1;
$foo->a = 100;
$foo->a ;
$foo->z ;
var_dump($foo);
?>
例: __call()
class Caller {
private $x = array(1, 2, 3);
function __call($m, $a) {
print "メソッド $m called:n";
var_dump($a);
return $this->x;
}
}
$foo = new Caller();
$a = $foo->test(1, "2", 3.4, true);
var_dump($a);
?>
逐次
は、オブジェクトを同時に使用するときに、逐次的な方法で再ロードされます。 節約された実行は、逐次クラスのすべてのプロパティです。 ;?php
class Foo {
public $x = 1;
パブリック $y = 2;
}
$obj = 新しい Foo;
foreach ($obj as $prp_name => $prop_value) {
// using the プロパティ
}
?>
1 つのクラスのすべてのオブジェクトは、このクラスが 1 つの空のインターフェイスを達成している場合、代替え可能です。
インターフェイス IteratorAggregate と Iterator は、指定されたクラスのオブジェクトがコード内でどのように実行されるかを許可します。IteratorAggregateインターフェイスのあるメソッド:getIterator() 必ず一数グループを返す必要があります
例
class ObjectIterator implements Iterator {
private $obj;
プライベート $num;
function __construct($obj) {
$this->obj = $obj;
}
関数 rewind() {
$this->num = 0;
}
関数 valid() {
return $this->num < $this->obj->max;
}
function key() {
return $this->num;
}
function current() {
switch($this->num) {
case 0: return "1st";
ケース 1: 「2 番目」を返します。
ケース 2: 「3 番目」を返します。
デフォルト: return $this->num."th";
}
}
function next() {
$this->num ;
}
}
class Object implements IteratorAggregate {
public $max = 3;
function getIterator() {
return new ObjectIterator($this);
}
}
$obj = 新しい オブジェクト;
// this foreach ...
foreach($obj as $key => $val) {
echo "$key = $valn";
}
// 次の 7 行が for ディレクティブと一致します。
$it = $obj->getIterator();
for($it->rewind(); $it->hasMore(); $it->next) {
$key = $it->current();
$val = $it->key();
echo "$key = $valn";
}
unset($it);
?>
新しい __toString メソッド
は、__toString メソッドをオーバーライドすることで、オブジェクトから文字列への変換を制御できます。
例
class Foo {
function __toString() {
return "What ever";
}
}
$obj = new Foo;
echo $obj; // call __toString()
?>
Reflection API
Php5 は、クラス、インターフェイス、関数、メソッドの逆プロセスをサポートするために、完全なリフレクション API を導入しました。反射 API の詳細参考資料:http://sitten-polizei.de/php/reflection_api/docs/ language.reflection.html
例
class Foo {
public $prop;
function Func($name) {
echo "Hello $name";
}
}
reflection_class::export('Foo');
reflection_object::export(new Foo);
reflection_method::export('Foo', 'func');
reflection_property::export('Foo', 'prop');
reflection_extension::export('standard');
?>
新しい内部メモリ管理
Php5 には、マルチネットワーク環境でのミューテックスのロック/解除を再度使用せずに、より効率的に動作できるようにする、まったく新しい内部メモリ管理機構があります。锁定