PHP の DOM クラス (DOMNode、DOMEElement など) を使用していて、それらが本当に読み取り専用のプロパティを持っていることに気付きました。たとえば、DOMNode の $nodeName プロパティを読み取ることはできますが、書き込むことはできません (書き込むと、PHP が致命的なエラーをスローします)。
PHP で独自の読み取り専用プロパティを作成するにはどうすればよいですか?
PHP の DOM クラス (DOMNode、DOMEElement など) を使用していて、それらが本当に読み取り専用のプロパティを持っていることに気付きました。たとえば、DOMNode の $nodeName プロパティを読み取ることはできますが、書き込むことはできません (書き込むと、PHP が致命的なエラーをスローします)。
PHP で独自の読み取り専用プロパティを作成するにはどうすればよいですか?
次のように実行できます。
class Example {
private $__readOnly = 'hello world';
function __get($name) {
if($name === 'readOnly')
return $this->__readOnly;
user_error("Invalid property: " . __CLASS__ . "->$name");
}
function __set($name, $value) {
user_error("Can't set property: " . __CLASS__ . "->$name");
}
}
これは、本当に必要な場合にのみ使用してください。通常のプロパティ アクセスよりも低速です。PHP の場合、setter メソッドのみを使用して外部からプロパティを変更するというポリシーを採用するのが最善です。
あなたはすでにあなたの答えを得ているようですが、まだ探している人のために:
すべての「読み取り専用」変数をプライベートまたはプロテクトとして宣言し、魔法のメソッド __get() を次のように使用します。
/**
* This is used to fetch readonly variables, you can not read the registry
* instance reference through here.
*
* @param string $var
* @return bool|string|array
*/
public function __get($var)
{
return ($var != "instance" && isset($this->$var)) ? $this->$var : false;
}
ご覧のとおり、$this->instance 変数も保護しました。このメソッドにより、ユーザーは宣言されたすべての variabled を読み取ることができるからです。複数の変数をブロックするには、in_array() で配列を使用します。
シリアル化のためにプライベート/保護されたプロパティを公開する方法を探している人のために、getter メソッドを使用してそれらを読み取り専用にすることを選択した場合、これを行う方法があります (@Matt: 例として json の場合):
interface json_serialize {
public function json_encode( $asJson = true );
public function json_decode( $value );
}
class test implements json_serialize {
public $obj = null;
protected $num = 123;
protected $string = 'string';
protected $vars = array( 'array', 'array' );
// getter
public function __get( $name ) {
return( $this->$name );
}
// json_decode
public function json_encode( $asJson = true ) {
$result = array();
foreach( $this as $key => $value )
if( is_object( $value ) ) {
if( $value instanceof json_serialize )
$result[$key] = $value->json_encode( false );
else
trigger_error( 'Object not encoded: ' . get_class( $this ).'::'.$key, E_USER_WARNING );
} else
$result[$key] = $value;
return( $asJson ? json_encode( $result ) : $result );
}
// json_encode
public function json_decode( $value ) {
$json = json_decode( $value, true );
foreach( $json as $key => $value ) {
// recursively loop through each variable reset them
}
}
}
$test = new test();
$test->obj = new test();
echo $test->string;
echo $test->json_encode();
Class PropertyExample {
private $m_value;
public function Value() {
$args = func_get_args();
return $this->getSet($this->m_value, $args);
}
protected function _getSet(&$property, $args){
switch (sizeOf($args)){
case 0:
return $property;
case 1:
$property = $args[0];
break;
default:
$backtrace = debug_backtrace();
throw new Exception($backtrace[2]['function'] . ' accepts either 0 or 1 parameters');
}
}
}
これは、プロパティの取得/設定を処理する方法です。Value() を読み取り専用にしたい場合は、代わりに次のようにします。
return $this->m_value;
関数 Value() は現在、取得または設定されます。