2011-02-07 146 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>