オブジェクトの評価/比較

変数

 状態:  閲覧数:3,322  投稿日:2010-06-02  更新日:  
PHP5ではプロパティを持っていてもいなくても常に“空ではない”と評価。
“PHP5ではオブジェクトは常に「TRUE」と評価”される。

▼生成したオブジェクトを「empty()」関数で“空”であるか否かを確認
 
<pre>
<?php
class C1{
var $var;
}
class C2{
//
}

echo "[PHP".substr(PHP_VERSION, 0, 1), ]\n";//substr(string $string , int $start [, int $length ] )文字列 string の、start で指定された位置から length バイト分の文字列を返す
echo "[PHP".PHP_VERSION, ]\n";

$c1 = new C1;
$c2 = new C2;

var_dump(empty($c1)); //empty ? 変数が空であるかどうかを検査。プロパティ(var $var;)を持つオブジェクト
var_dump(empty($c2)); //プロパティを持たないオブジェクト

unset($c1->var);//unset ? 指定した変数の割当を解除
$c2->var = NULL;

var_dump(empty($c1)); //持っていたプロパティをアンセット
var_dump(empty($c2)); //プロパティをセット(NULL)した
?>
</pre>


▼結果

  /demo/object3_evaluation.html





「インターフェイス」は「extends」を使って、他の「インターフェイス」を継承して拡張することができる。また、その場合は、「,(コンマ)」で区切って複数指定できる。

 
<pre>
<?php
interface I1{
const I1_CONST = "インターフェイス1定数";
function m1();
}

interface I2{
const I2_CONST = "インターフェイス2定数";
function m2();
}

#「インターフェイス」を継承
interface I3 extends I1, I2{
// const I1_CONST = "ダミー"; //「インターフェイス定数」再定義は不可 ⇒ Fatal error: Cannot inherit previously-inherited constant I1_CONST from interface I1
}

#「インターフェイス」実装
class I4 implements I1, I2{
public function m1(){
//
}
public function m2(){
//
}
}

#「インターフェイス」実装
class C1 implements I3{
public function m1(){
//
}
public function m2(){
//
}
}
?>
</pre>


▼結果

  /demo/interface2_extends.html





「インターフェイスを実装したクラス」を継承したクラスも、「インターフェイスを継承したインターフェイス」を実装したクラスも、そのクラスは「継承元のインターフェイスを実装」していると見做される。
 
<pre>
<?php
#「インターフェイス」の定義
interface I1{
//
}
interface I2 extends I1{//インターフェイスを継承したインターフェイス
//
}

#「インターフェイス」の実装
abstract class C1Base implements I1{//インターフェイスを実装したクラス
//
}
class C2 extends C1Base{//「インターフェイスを実装したクラス」を継承したクラス
//
}
class C3 implements I2{//「インターフェイスを継承したインターフェイス」を実装したクラス
//
}

#オブジェクトが実装する「インターフェイス」を調べる
$imp_arr["C2] = class_implements(new C2);//「class_implements()」関数 ⇒ 「指定したオブジェクトが実装するインターフェイス名を配列に格納して返す」
$imp_arr["C3] = class_implements(new C3);

print_r($imp_arr);
?>
</pre>


▼結果

  /demo/interface3.html





オブジェクト引数のインターフェイス指定

「関数」や「クラスのメンバ関数」の定義時には、「オブジェクト引数のクラス指定」だけではなく「オブジェクト引数のインターフェイス指定」もできる。この場合、渡されたオブジェクトが、指定された「インターフェイス」を実装しているか否かがチェックされる。
 
<pre>
<?php
interface I1{}
interface I2{}
interface I3 extends I1, I2{}//複数インターフェイスを継承したインターフェイス
interface I4{}

abstract class C1Base implements I3{}//インターフェイスを実装したクラス
class C1 extends C1Base{}//「インターフェイスを実装したクラス」を継承したクラス

function f1(C1Base $obj){//②
echo '$obj は、\'C1Base\'のインスタンスじゃなきゃダメ。', "\n";
echo '$obj は、\'', get_class($obj), "'のインスタンス。\n\n";
}
function f2(I1 $obj){//④
echo '$obj は、\'I1\'インターフェイスの実装じゃなきゃダメ。', "\n";
echo '$obj implements...', "\n";
print_r(class_implements($obj));
}
function f3(I4 $obj){
echo '$obj must implement interface \'I4\'.', "\n";
echo '$obj implements...', "\n";
print_r(class_implements($obj));
}

f1(new C1);//①
f2(new C1);//③
//f3(new C1); //インターフェイス「I4」を実装していなければならない ⇒ Catchable fatal error: Argument 1 passed to f3() must implement interface I4, instance of C1 given, called
?>
</pre>


▼結果

  /demo/interface4_object.html




定義済みのインターフェイス
PHPには予め幾つかの「インターフェイス」が定義されている。
定義済みの「インターフェイス」を確認してみる。
 
<pre>
<?php
#定義済み「インターフェイス」と定義されるメソッド名を取得・出力
foreach(get_declared_interfaces() as $interface_name)//get_declared_interfaces ? 宣言されている全てのインターフェースの配列を返す
$interfaces[$interface_name] = get_class_methods($interface_name);//get_class_methods ? クラスメソッドの名前を取得

print_r($interfaces);

echo "
";

#定義済み「インターフェイス」を実装する定義済みクラス名を抽出・出力
foreach(get_declared_classes() as $class_name){
$buf_arr = array();
$class_abj = new ReflectionClass($class_name);
$imp_arr = $class_abj->getInterfaces();
foreach($imp_arr as $imp_obj){
$imp_arr_ = get_object_vars($imp_obj);
$buf_arr[] = $imp_arr_["name];
}
if(count($buf_arr))
$arr[$class_name] = $buf_arr;
}

print_r($arr);
?>
</pre>


▼結果

  /demo/interface5_already.html





 
<pre>
<?php
function compare($param1, $param2){ #2つのオブジェクトを比較する関数を定義
#変数名を利用して変数へのリファレンスを取得
$obj1 =& $GLOBALS[$param1];
$obj2 =& $GLOBALS[$param2];
$param1 = '$'.$param1;
$param2 = '$'.$param2;
if(is_null($obj2))
return "N/A";
$str = $param1;
if($obj1 === $obj2)
$str .= " === ";
else if($obj1 == $obj2)
$str .= " == ";
else
$str .= " != ";
return $str.$param2;
}

#全く同じ構造をした2つのクラスを定義
class C1{
public $p1 = "プロパティ値1";
}
class C2{
public $p1 = "プロパティ値1";
}

$c1 = new C1;//①生成した「C1」クラスのインスタンスオブジェクトを「変数$c1」に結びつける
$c1Dis = new C1;//②生成した「C1」クラスのインスタンスオブジェクトを別の「変数$c1Dis」に結びつける
if(substr(PHP_VERSION, 0, 1) == 5){ #PHP5用の処理
$c1Ass = $c1;//「変数$c1Ass」に「変数$c1」を“割り当て”。「変数$c1Ass」に「変数$c1」と共通の「リファレンス(同じ変数の内容を異なった名前でコールすること。実体の別名)」をセット
$c1Clo = clone($c1); //「変数$c1Clo」に「変数$c1」のクローン(コピー)を代入。「clone $c1」はPHP4では不可(PHP5からという意)
$c1CloDis = clone($c1);//「変数$c1CloDis」に「変数$c1」のクローン(コピー)を代入
}else{ #PHP4用の処理
$c1Ass = NULL;
$c1Clo = $c1;
$c1CloDis = $c1;
}
$c1CloDis->p1 = "プロパティ値2";//「変数c1CloDis」のプロパティを更新
$c1Ref =& $c1;//「変数$c1Ref」に「変数$c1」へのリファレンスを代入
$c2 = new C2;//「変数c2」に「C1」クラスと全く同じ構造をした「C2」クラスのオブジェクトを代入

echo "[PHP".substr(PHP_VERSION, 0, 1), ]\n";//③

#比較する変数(オブジェクト)名を指定して結果を出力
echo
compare('c1', 'c1Dis'), "\n", //④比較対照 - 同じクラスの別オブジェクト ⇒ ==
compare('c1', 'c1Ass'), "\n", //比較対照 - 自身を割り当てられた変数 ⇒ ===
compare('c1', 'c1Clo'), "\n", //比較対照 - 自身のクローン ⇒ ==
compare('c1', 'c1CloDis'), "\n", //比較対照 - 自身のクローン(プロパティを更新) ⇒ !=
compare('c1', 'c1Ref'), "\n", //比較対照 - 自身へのリファレンスを格納した変数 ⇒ ===
compare('c1', 'c2');//比較対照 - 同じ構造の別クラスのオブジェクト ⇒ !=
?>
</pre>


▼結果

  /demo/object4_4-5.html




PHP5におけるオブジェクトを比較した際の評価の違い
比較対照 PHP5 演算子
同じクラスの別オブジェクト 一致 ==
自身を割り当てられた変数 完全一致 ===
自身のクローン 一致 ==
自身のクローン(プロパティを更新) 不一致 !=
自身へのリファレンスを格納した変数 完全一致 ===
同じ構造の別クラスのオブジェクト 不一致 !=



グローバルスコープ

コメント投稿(ログインが必要)



週間人気ページランキング / 6-7 → 6-13
順位 ページタイトル抜粋 アクセス数
1 PHPで定数を定義する方法は2種類ある / 配列定数の定義 9
2 コード例 … 「例外処理」はネストすることができる 5
2 ブラウザを閉じたらセッションデータはどうなるの? | セッション 5
3 Parse error: syntax error, unexpected 'public' (T_PUBLIC) | Parse error(エラーメッセージ) 4
4 ガベージコレクション | 機能 3
4 Warning: Unexpected character in input: '\' (ASCII=92) state=1 in ○○.php on line △△ | Warning(エラーメッセージ) 3
4 curl で Cookie を使用する 3
4 PHPにおけるメソッドのオーバーライドについて /「引数の数や型は、親クラスのメソッドと完全に一致していなければなりません。」とは具体的にどういう意味ですか? 3
4 Catchable fatal error: Object of class DateTime could not be converted to string | Fatal error(エラーメッセージ) 3
4 Fatal error: Uncaught PDOException: SQLSTATE[HY000] [2002] Connection refused | Fatal error(エラーメッセージ) 3
4 Warning: include() [function.include]: Failed opening '**.php' for inclusion (in | Warning(エラーメッセージ) 3
4 ( ! ) Deprecated: implode(): Passing glue string after array is deprecated. Swap the parameters in ★★★ headless-chromium-php/vendor/wrench/wrench/lib/Wrench/Protocol/Protocol.php | エラーメッセージ 3
5 Fatal error: Wrong parameters for Exception([string $exception [, long $code ]]) | Fatal error(エラーメッセージ) 2
5 セッション管理が必要な理由は、HTTPプロトコルには状態を保持する機能がないため | セッション 2
5 Fatal error: require_once(): Failed opening required 'PEAR.php' | Fatal error(エラーメッセージ) 2
5 Fatal error: Uncaught RuntimeException: SplFileObject::__construct(): failed to open stream: Permission denied in | Fatal error(エラーメッセージ) 2
5 ( ! ) Fatal error: Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'カラム名' cannot be null | Fatal error(エラーメッセージ) 2
5 session_start() | セッション 2
5 @ | 演算子 2
5 Parse error: syntax error, unexpected T_REQUIRE_ONCE, expecting T_FUNCTION | Parse error(エラーメッセージ) 2
2024/6/14 1:01 更新