2010-02-26 12 views

Odpowiedz

19

Przypuszczam rozwiązanie, dla właściwości klasy, byłoby:

  • nie określają właściwość o nazwie, która Cię interesuje
  • korzystania z magiczną __get sposób aby uzyskać dostęp do nieruchomości, używając "fałszywa" nazwa
  • definiuje metodę __set, więc zgłasza wyjątek podczas próby ustawienia tej właściwości.
  • Aby uzyskać więcej informacji na temat metod magicznych, patrz: Overloading.

Dla zmiennych, nie sądzę, że możliwe jest, aby mieć zmienną tylko do odczytu, dla której PHP będzie zgłaszać wyjątek, gdy próbujesz pisać do niego.


Na przykład, rozważmy tę małą klasę:

class MyClass { 
    protected $_data = array(
     'myVar' => 'test' 
    ); 

    public function __get($name) { 
     if (isset($this->_data[$name])) { 
      return $this->_data[$name]; 
     } else { 
      // non-existant property 
      // => up to you to decide what to do 
     } 
    } 

    public function __set($name, $value) { 
     if ($name === 'myVar') { 
      throw new Exception("not allowed : $name"); 
     } else { 
      // => up to you to decide what to do 
     } 
    } 
} 

Instanciating klasę i próbuje odczytać właściwość:

$a = new MyClass(); 
echo $a->myVar . '<br />'; 

będzie Ci oczekiwany wynik:

test 

Podczas próby zapisu do właściwego ty:

$a->myVar = 10; 

będzie Ci wyjątek:

Exception: not allowed : myVar in /.../temp.php on line 19 
+0

Dobra odpowiedź! BTW, do czego służy "__call"? – user198729

+0

'__call' jest wywoływany, gdy próbujesz wywołać metodę, która nie kończy się na klasie (jak' __get' jest wywoływana, gdy próbujesz odczytać właściwość, która nie istnieje w klasie) - zobacz http://fr2.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods –

+0

@Pascal MARTIN, dzięki! Wiem też, że jesteś doświadczonym użytkownikiem symfony/doktryny , możesz rzucić okiem na ten post: http: //stackoverflow.com/questions/2339800/how-can-i-fetch-the-entire-tree-in-a-ingle-query-with-doctrine? – user198729

13
class test { 
    const CANT_CHANGE_ME = 1; 
} 

i przekazać ją jako test::CANT_CHANGE_ME

+0

Jak rzucisz niestandardowy wyjątek? – user198729

+0

nie wygeneruje wyjątku, ale błąd analizy składni ... –

+3

@ user198729 Dlaczego chcesz * chcesz * dodać niestandardowy wyjątek? – meagar

0

wiem, że to jest stare pytanie, ale odpowiedź Pascala naprawdę pomógł mi i chciałem dodać do niej trochę.

__get() uruchamia nie tylko nieistniejące właściwości, ale także "niedostępne", np. chronione. Ułatwia to tworzenie właściwości tylko do odczytu!

class MyClass { 
    protected $this; 
    protected $that; 
    protected $theOther; 

    public function __get($name) { 
     if (isset($this->$name)) { 
      return $this->$name; 
     } else { 
      throw new Exception("Call to nonexistent '$name' property of MyClass class"); 
      return false; 
     } 
    } 

    public function __set($name) { 
     if (isset($this->$name)) { 
      throw new Exception("Tried to set nonexistent '$name' property of MyClass class"); 
      return false; 
     } else { 
      throw new Exception("Tried to set read-only '$name' property of MyClass class"); 
      return false; 
     } 
    } 
}