2010-08-30 29 views
10

PHP'de bir nesnenin salt okunur özelliğini yapmanın bir yolu var mı? İçinde birkaç dizi olan bir nesnem var. Normaldesalt okunur özellikleri?

echo $objObject->arrArray[0]; 

Bir dizinin olur Ama onlar inşa ediyoruz sonra bu diziler yazmaya muktedir istemiyorum onları erişmek istediğiniz. o nesneye bozulmamış dizi saklarken yerel dizi değişkeni yeniden yazma beni engellemez,

$arrArray = $objObject->getArray1(); 
echo $arrArray[0]; 

Ve zaten: Bu yerel bir değişken oluşturmak için bir PITA gibi hissediyor.

cevap

25

Peki, soru nereden yazmayı önlemek istersiniz?

ilk adım dizisi korumalı veya nesne kapsam dışından yazma önlemek için özel yapıyor:

protected $arrArray = array(); 

dizinin "dışarıdan" gelen, gaz giderici bir ince sizi yapacağız. Ya:

public function getArray() { return $this->arrArray; } 

Ve erişen

$array = $obj->getArray(); 

veya

public function __get($name) { 
    return isset($this->$name) ? $this->$name : null; 
} 

Ve gibi erişen

gibi: onlar referanslar dönmemeleri

$array = $obj->arrArray; 

dikkat edin. Böylece, orijinal diziyi nesnenin kapsamı dışında değiştiremezsiniz. Eğer gerçekten tam değişmez dizi gerekiyorsa Sen ArrayAccess kullanarak Nesne kullanabilirsiniz, dizi kendisi ...

değiştirebilir ...

Veya sadece ArrayObject uzatmak ve yazma yöntemlerinin hepsi üzerine yazabilirsiniz: Hala gibi en diziyi destekler

public function __construct(array $input) { 
    $this->arrArray = new ImmutableArrayObject($input); 
} 

: Sonra

class ImmutableArrayObject extends ArrayObject { 
    public function append($value) { 
     throw new LogicException('Attempting to write to an immutable array'); 
    } 
    public function exchangeArray($input) { 
     throw new LogicException('Attempting to write to an immutable array'); 
    } 
    public function offsetSet($index, $newval) { 
     throw new LogicException('Attempting to write to an immutable array'); 
    } 
    public function offsetUnset($index) { 
     throw new LogicException('Attempting to write to an immutable array'); 
    } 
} 

, basitçe $this->arrArray nesnesinin bir örneği yapmak kullanımları:

count($this->arrArray); 
echo $this->arrArray[0]; 
foreach ($this->arrArray as $key => $value) {} 

$newArray = $this->arrArray->getArrayCopy(); 
//Edit array here 
$this->arrArray = new ImmutableArrayObject($newArray); 
+0

Immutable Array'ım var mı? kendini oluşturmadaki verilerle yüklerim __construct işlevinin üzerine yazılır, üst yapıcıyı çağırırdım, ancak nesnenin içeriklerini nasıl ayarlayabilirim? –

+0

Çok iyi cevap! Ancak bir dizinin nesneler içerebileceğine dikkat edin: Her nesne bir referans olarak döndürülür ve değişmez sınıfınızla bile değiştirilebilir: '$ a = new ImmutableArrayObject ((object) ['foo' => 'bar']); $ b = $ a [0]; $ b-> foo = 'değiştirildi'; – Philipp

3

Eğer __set() ve __get() yöntemlerle yapabilir 5+ PHP kullanıyorsanız.

Nasıl çalıştıklarını tanımlamanız gerekir, ancak bunu yapmalıdır.

Bir örnek düzenleme şöyle olurdu. Var olmayan bir zaman

class Example { 
    private $var; 
    public function __get($v) { 
     if (is_array($v)) { 
      foreach() { 
       // handle it here 
      } 
     } else { 
      return $this->$v; 
     } 
    } 
} 

Bu bunu yapmanın "iyi" yolu olmayabilir ama tanımlanan Eğer

+3

Patron: Client "Ben size algoritma bitmiş söylemiştin": "Ben patron yaptım, sorun nedir" Patron: "işe yaramaz" Müşteri: "ne ihtiyacınız bağlı olarak çalışır" – Chris

+1

@ Chris neden müşteri patrondan emir alıyor? Lol. –

4

gerekenler bağlı çalışacağız, sihirli fonksiyonlar __get() ve __set() adı verilecek veya özel mülke erişilebilir. Bu özellik, özel özellikler için "get" ve "set" yöntemleri oluşturmak için kullanılabilir ve örneğin bunları depolandığında veya alınırken salt okunur veya manipüle eder. Örneğin

:

class Foo 
{ 
    private $bar = 0; 
    public $baz = 4; // Public properties will not be affected by __get() or __set() 
    public function __get($name) 
    { 
    if($name == 'bar') 
     return $this->bar; 
    else 
     return null; 
    } 
    public function __set($name, $value) 
    { 
    // ignore, since Foo::bar is read-only 
    } 
} 

$myobj = new Foo(); 
echo $foo->bar; // Output is "0" 
$foo->bar = 5; 
echo $foo->bar; // Output is still "0", since the variable is read-only 

da manual page for overloading in PHP bakınız.

+3

Belirli bir değişkenin ayarlanmasına izin vermiyorsanız, 'set'te bir istisna atmanızı öneririm. Bunun nedeni, birisinin yeni bir şey yapması gerektiğinde oldukça kafa karıştırıcı olabileceği ve işe yaramadığıdır. "Ama bu diziyi bu değişkeni içerecek şekilde ayarladım. Ödev başarılı oluyor, bu yüzden neden # # @ $ çalışmıyor?" ... – ircmaxell

+0

@ircmaxell: iyi nokta ... – Frxstrem

0

: Bir LogicException ...

Ah olsun, ama buna yazmak gerekirse, bütün (nesnenin içinde) yapmak gerektiğini fark edeceksiniz, buna yazma do sınıfta bunu yapmak:

private $array; 

function set_array($value) { 
    $this->array = $value; 
} 

o zaman sadece bu gibi ayarlayın:

$obj->set_array($new_array); 
İlgili konular