2011-02-07 151 views
1

其他語言的便捷功能之一是可以爲屬性創建get和set方法。在試圖找到複製的PHP此功能的好方法,我偶然發現了這一點:http://www.php.net/manual/en/language.oop5.magic.php#98442具有get/set函數的PHP屬性

這裏是我的那個類的故障:

<?php 

class ObjectWithGetSetProperties { 

    public function __get($varName) { 
     if (method_exists($this,$MethodName='get_'.$varName)) { 
      return $this->$MethodName(); 
     } else { 
      trigger_error($varName.' is not avaliable .',E_USER_ERROR); 
     } 
    } 

    public function __set($varName,$value) { 
     if (method_exists($this,$MethodName='set_'.$varName)) { 
      return $this->$MethodName($value); 
     } else { 
      trigger_error($varName.' is not avaliable .',E_USER_ERROR); 
     } 
    } 

} 

?> 

我的計劃是擴展這個類,並定義適當的get_someproperty()set_someproperty()這個擴展類。

<?php 
class SomeNewClass extends ObjectWithGetSetProperties { 
    protected $_someproperty; 
    public function get_someproperty() { 
     return $this->_someproperty; 
    } 
} 
?> 

麻煩的是,基類的ObjectWithGetSetProperties是無法看到我的方法get_someproperty()SomeNewClass。我總是得到錯誤,「鑰匙不可用」。

有沒有什麼辦法解決這個問題,允許基類ObjectWithGetSetProperties工作,或者我將不得不在每個類中創建這些__get()__set()魔法方法?

+0

類似什麼,我試圖完成,但並不完全:http://stackoverflow.com/questions/ 3479036/emulate-public-private-properties-with-get-and-set – Brad 2011-02-07 17:06:14

+1

不要詆譭你的問題(這是一個明智的API目標),但請考慮[爲什麼getter和setter方法是邪惡的](http://www.javaworld .com/javaworld/jw-09-2003/jw-0905-toolbox.html)。 (有趣的閱讀,即使不適用) – mario 2011-02-07 17:14:16

+0

@mario,我會在另一天更深入地閱讀它,但我不認爲這篇文章中的論點適用於我正在建造的那類課程。我正在建立一個類來表示數據。事實上,它會做的很少。它的主要目的是在現實世界中用一系列屬性來表示某些東西。無論如何,我稍後會更詳細地閱讀該文章,也許在SO上發佈一個新的問題。 – Brad 2011-02-07 17:20:51

回答

5

嘗試is_callable。示例代碼片段:

<?php 
date_default_timezone_set("America/Edmonton"); 
class A { 
    protected $_two="goodbye"; 
    protected $_three="bye"; 
    protected $_four="adios"; 
    public function __get($name) { 
     if (is_callable(array($this,$m="get_$name"))) { 
      return $this->$m(); 
     } 
     trigger_error("Doh $name not found."); 
    } 
    public function get_two() { 
     return $this->_two; 
    } 
} 
class B extends A { 
    protected $_one="hello"; 
    protected $_two="hi"; 
    protected $_three="hola"; 
    public function get_one() { 
     return $this->_one; 
    } 
    public function get_two() { 
     return $this->_two; 
    } 
    public function get_three() { 
     return $this->_three; 
    } 
    public function get_four() { 
     return $this->_four; 
    } 
} 

$a=new a(); 
echo $a->one."<br />";//Doh one not found. 
echo $a->two."<br />";//goodbye 
echo $a->three."<br />";//Doh three not found. 
echo $a->four."<br />";//Doh four not found. 
$b=new b(); 
echo $b->one."<br />";//hello 
echo $b->two."<br />";//hi 
echo $b->three."<br />";//hola 
echo $b->four."<br />";//adios 
?> 

(更新以顯示其中B覆蓋A

0

在你的榜樣,你需要申報$_someproperty屬性,這樣

class SomeNewClass extends ObjectWithGetSetProperties { 
    protected $_someproperty; 
    public function get_someproperty() { 
     return $this->_someproperty; 
    } 
} 
3

這不是(有些在comments提到),但method_exists()真的只檢查當前類的方法存在。

但是您可以使用is_callable()代替。同時也驗證了該方法不僅存在,而且確實允許調用:

if ( is_callable(array($this, $varName)) ) { 
    ... 
0
<form id="fname" method="post"> 
    <textarea name="sms" id="messageText"></textarea> 
    <input type="submit" name="smsbut" value="sms"/> 
</form> 
<script> 
    $(document).ready(function() { 
     $("#fname").submit(function() 
     { 
      var sms = $('#messageText').val(); 
      $.ajax(
        { 
         type: "POST", 
         url: "sms.php/?id=<?php echo $_SESSION['id']; ?>", 
         data: {userSms: sms}, 
         dataType: "json", 
         success: function(result) 
         { 
          if (result["error"] != undefined) 
          { 

          } 
          else if (result["success"] != undefined) 
          { 
           $('#messageText').val(""); 
           location.reload(); 
          } 
         } 
        }); 
      return false; 
     }); 
    }); 
</script>