2012-07-01 50 views
1

我試圖找到一個解決方案,以防止靜態變量被複制到擴展類(這不能很好地與晚靜態綁定),這是我認爲可能工作,但給我一個「PHP致命錯誤:在寫入方面」不能使用函數返回值:從__callStatic返回對靜態變量的引用?

<?php 

class Person 
{ 
    protected static $tlsb_names = ['name']; 
    protected static $tlsb_vars = []; 

    public static function & __callStatic($method,$args) 
    { 
     echo "call static " . $method . " on " . get_called_class() . "\n"; 
     if(in_array($method,static::$tlsb_names)) 
     { 
      if(!array_key_exists(get_called_class(),static::$tlsb_vars)) 
      { 
       static::$tlsb_vars[get_called_class()] = []; 
      } 
      if(!array_key_exists($method, static::$tlsb_vars[get_called_class()])) 
      { 
       echo "set var $method for " . get_called_class() . "\n"; 
       static::$tlsb_vars[get_called_class()] = null; 
      } 
      return static::$tlsb_vars[get_called_class()][$method]; 
     } 
    } 

    public static function show_name() 
    { 
     static::name() . "\n"; 
    } 

    public static function call_me_al() 
    { 
     static::name() = "Al"; 
    } 

    public static function call_me_joe() 
    { 
     static::name() = "Joe"; 
    } 
} 

class Al extends Person{} 
class Joe extends Person{} 

Al::call_me_al(); 
Joe::call_me_joe(); 

Al::show_name(); 
Joe::show_name(); 

有問題的部分是用線:

public static function call_me_al() 
{ 
    static::name() = "Al"; 
} 

顯然,這是因爲我的迴音的非編譯時錯誤的運行。

我在這裏做錯了什麼?

+0

'= [];'在PHP afaik中無效? – Wrikken

+2

是的,從PHP 5.4開始我覺得這不是很好嗎? :) – djfm

+0

我有一件事要說的:_「Whooohoooo!升級時間!」_ ...如果你使它2語句('$ name = self :: name(); $ name =' Al':'?) – Wrikken

回答

0

下面的代碼行是錯誤的:

public static function & __callStatic($method,$args) 

你需要匹配the definition of that __callStatic functionDocs,這是沒有回報的參考:

public static function __callStatic($name, $arguments) 

所以你想達到什麼是不可能的。

而你周圍的另一個問題應該可以用late static binding (LSB)Docs來解決。另外請記住,Magic很難調試,所以準備好你的調試程序並逐步瀏覽應用程序,以便更好地理解實際發生的情況。 PHP中的調試器稱爲Xdebug,大多數PHP IDE和編輯器都支持它。

+0

LSB不會解決它:我想要的是讓我的子類擁有自己的靜態變量名稱副本。如果我想用LSB做到這一點,我將不得不在Al和Joe中定義類時手動重新聲明靜態$名稱。這對於一些變量是可以的,但是當有很多變量時你會感到痛苦:你忘記了一個靜態聲明,並且所有的子類都會共享相同的靜態成員,而不是他們自己的... – djfm

+0

哇,所以你抱怨說面向類的編程是有限的?那麼,爲什麼你不放棄靜態,只是做你想做的事情?它看起來非常複雜,你要去(順便說一句,創建你自己的「__callStatic」函數,它可以做你想做的事情,然後調用它,就像'Class :: func('name');' - 你甚至可以通過引用返回然後 – hakre

+0

是的,好的,我可以,並且必須放棄魔術方法,它會更清潔,儘管有點不太實際......但是如果你想編寫乾淨的代碼,使用PHP有什麼意義呢?:) – djfm