この質問がまだ関連しているかどうかはわかりませんが、php には組み込みのArrayObjectクラスがあり、オブジェクトを配列として扱うことができ、データベース レコードまたはコレクションのコンテナーとして使用するときに便利です。
厳密な型に関してはベスト プラクティスではないかもしれませんが、オブジェクトを配列として扱うことができ、両方のステートメントが有効です。
$obj = new ArrayObject(['a' => 'alpha']);
var_dump($obj['a']); //alpha
var_dump($obj->getOffset('a'));//alpha
ただし、次の動作に注意する必要があります。ArrayObject
$obj = new ArrayObject(['a' => 'alpha']);
//Access Property
var_dump($obj['a']); //alpha
var_dump($obj->offsetGet('a'));//alpha
var_dump($obj->a); //null Notice: Undefined property: ArrayObject::$a
//Serialization
var_dump(serialize($obj));// string 'C:11:"ArrayObject":41:{x:i:0;a:1:{s:1:"a";s:5:"alpha";};m:a:0:{}}' (length=65)
var_dump($obj->serialize());// string 'x:i:0;a:1:{s:1:"a";s:5:"alpha";};m:a:0:{}'
var_dump(serialize($obj) === $obj->serialize());// false !!!
//Setting Properties
$obj['b'] = 'beta'; //OK
$obj->c = 'gamma'; //value becomes object property!!!
var_dump($obj);
/* OBJECT DUMP
object(ArrayObject)[13]
public 'c' => string 'gamma' (length=5)
private 'storage' =>
array (size=2)
'a' => string 'alpha' (length=5)
'b' => string 'beta' (length=4)
*/
//Property validation as array
var_dump(isset($obj['a']));//true
var_dump(isset($obj['b']));//true
var_dump(isset($obj['c']));//false
//Property validation as object
var_dump(isset($obj->a));//false
var_dump(isset($obj->b));//false
var_dump(isset($obj->c));//true
//Typecasting
var_dump((array)$obj);
/*
array (size=2)
'a' => string 'alpha' (length=5)
'b' => string 'beta' (length=4)
*/
//var_dump((string)$obj);// Catchable fatal error: Object of class ArrayObject could not be converted to string
ArrayObject はArrayObject::STD_PROP_LIST
、デフォルトとArrayObject::ARRAY_AS_PROPS
代替として 2 つのフラグを受け入れます。
これにより、値を読み取る動作が変更されますが、その方法で新しいプロパティを設定することはサポートされていません。次に例を示します。
$obj = new ArrayObject(['a' => 'alpha'], ArrayObject::ARRAY_AS_PROPS);
//Access Property
var_dump($obj['a']); //alpha
var_dump($obj->offsetGet('a'));//alpha
var_dump($obj->a);//alpha
//Serialization
var_dump(serialize($obj));// string 'C:11:"ArrayObject":41:{x:i:0;a:1:{s:1:"a";s:5:"alpha";};m:a:0:{}}' (length=65)
var_dump($obj->serialize());// string 'x:i:0;a:1:{s:1:"a";s:5:"alpha";};m:a:0:{}'
var_dump(serialize($obj) === $obj->serialize());// false !!!
//Setting Properties
$obj['b'] = 'beta'; //OK
$obj->c = 'gamma'; //OK
var_dump($obj);
/* OBJECT DUMP
object(ArrayObject)[14]
private 'storage' =>
array (size=3)
'a' => string 'alpha' (length=5)
'b' => string 'beta' (length=4)
'c' => string 'gamma' (length=5)
*/
//Property validation as array
var_dump(isset($obj['a']));//true
var_dump(isset($obj['b']));//true
var_dump(isset($obj['c']));//false !!!
//Property validation as object
var_dump(isset($obj->a));//true
var_dump(isset($obj->b));//true
var_dump(isset($obj->c));//true
//Typecasting
var_dump((array)$obj);
/*
array (size=2)
'a' => string 'alpha' (length=5)
'b' => string 'beta' (length=4)
*/
この動作の一貫性を高めるには、このクラスを拡張して魔法のメソッド__get()
、__set()
、__isset()
およびを実装する必要があり__unset()
ます。
別のトリッキーな部分はシリアライゼーションです。デフォルトのメソッドserialize
は、オブジェクト自体ではなくコピーのシリアライズされた$storage
変数を返します。インスタンスのシリアライズされたコピーを返す回避策として、メソッドでデフォルトのシリアライゼーションを実装できます__toString
。このようにして正しく動作します。
class FooObject extends ArrayObject
{
public function __get($index)
{
if ($this->offsetExists($index)) {
return $this->offsetGet($index);
} else {
throw new UnexpectedValueException('Undefined key ' . $index);
}
}
public function __set($index, $value)
{
$this->offsetSet($index, $value);
return $this;
}
public function __isset($index)
{
return $this->offsetExists($index);
}
public function __unset($index)
{
return $this->offsetUnset($index);
}
public function __toString()
{
return serialize($this);
}
}
使用例
$obj2 = new FooObject(['a' => 'alpha']);
//Access Property
var_dump($obj2['a']); //alpha
var_dump($obj2->offsetGet('a'));//alpha
var_dump($obj2->a); //alpha
//Serialization
var_dump(serialize($obj));// string 'C:11:"ArrayObject":41:{x:i:0;a:1:{s:1:"a";s:5:"alpha";};m:a:0:{}}' (length=65)
var_dump($obj->serialize());// string 'x:i:0;a:1:{s:1:"a";s:5:"alpha";};m:a:0:{}'
var_dump(serialize($obj) === $obj->serialize());// false !!!
//Setting Properties
$obj2['b'] = 'beta'; //OK
$obj2->c = 'gamma'; //OK
var_dump($obj2);
/* OBJECT DUMP
object(FooObject)[14]
private 'storage' (ArrayObject) =>
array (size=3)
'a' => string 'alpha' (length=5)
'b' => string 'beta' (length=4)
'c' => string 'gamma' (length=5)
*/
//Property validation as array
var_dump(isset($obj2['a']));//true
var_dump(isset($obj2['b']));//true
var_dump(isset($obj2['c']));//true
//Property validation as object
var_dump(isset($obj2->a));//true
var_dump(isset($obj2->b));//true
var_dump(isset($obj2->c));//true
//Typecasting
var_dump((array)$obj2);
/*
array (size=3)
'a' => string 'alpha' (length=5)
'b' => string 'beta' (length=4)
'c' => string 'gamma' (length=5)
*/