PHP Okunabiir Özellikleri?

5 Cevap php

PHP'nin DOM sınıfları (DOMNode, DOMEElement, vb) kullanarak ben onlar gerçekten readonly özelliklere sahip olduğunu fark etmişsinizdir. Örneğin, ben bir DOMNode bir $ nodeName özelliğini okuyabilir, ama (ben yaparsam PHP bir ölümcül hata atar) kendisine yazamıyor.

PHP nasıl benim kendi salt okunur özelliklerini oluşturabilir?

5 Cevap

Bunu şöyle yapabilirsiniz:

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");
    }
}

Eğer gerçekten ihtiyacınız olduğunda sadece bunu kullanabilirsiniz - bu normal bir özellik erişimi daha yavaştır. PHP için, sadece dışarıdan bir özelliğini değiştirmek için setter yöntemleri kullanarak bir politika benimsemeye en iyisidir.

Json_encode (örneğin) - Ama özel özellikleri yalnızca __ get (), bir nesnenin üyeleri numaralandırılamıyor işlevlerine görünmez kullanarak maruz.

Bir veritabanından nüfuslu veri birçok karmaşık yapıları geçmek için iyi bir yol gibi görünüyor ben düzenli () json_encode kullanarak Javascript PHP nesneleri geçmek. Ben bu verileri kullanır JavaScript aracılığıyla doldurulur, böylece bu nesnelerin ortak özelliklerini kullanmak zorunda, ama bu bu özellikler kamu (ve dolayısıyla riski olması anlamına gelir değil, muhtemelen aynı dalga boyunda (veya başka bir programcı kötü bir gece sonra kendimi)) doğrudan değiştirmek olabilir. Onları özel yapmak ve __ get () ve __ set () kullanırsanız, o zaman json_encode () onları görmüyor.

Bir "salt okunur" erişilebilirlik anahtar kelime olması güzel olmaz mıydı?

Ben zaten cevabı var ama olanlar için kim hala arıyoruz bakın:

Sadece bu gibi özel veya korunan ve sihirli yöntemini kullanın __ get () gibi tüm "salt okunur" değişkenleri bildirmek:

/**
 * 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;
}

Gördüğünüz gibi bu yöntem kullanıcıların tüm ilan değişkenli okumak için izin verecek gibi ben de bu-> örnek değişken $ korumuş. Birkaç değişken İn_Array'in ile bir dizi kullanmak engellemek için ().

Eğer salt okunur bunları yapmak için bir alıcı yöntemi kullanmak isterseniz serileştirme için özel / korumalı özelliklerini açığa bir yol arayanlar için, burada (Matt @: Bir örnek olarak json) Bunu yapmanın bir yolu:

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');
            }
        }


}

Bu benim / sen Değer () yapmak istiyorsanız readonly ... o zaman sadece sadece yerine aşağıdakileri yapın, benim özelliklerini ayarlayarak alma ile nasıl başa olduğunu:

    return $this->m_value;

() Işlevi Değer olarak hemen almak veya set istiyorum ya nerede.