Php 类限制:函数可见性
我希望函数explicitSetX($value){}在特定任务中是公共的,否则它应该是私有的。(私人电脑的功能) (我对如何编写通用setter不感兴趣,这个 问题是关于可见性/可接受性)Php 类限制:函数可见性,php,class,oop,restriction,Php,Class,Oop,Restriction,我希望函数explicitSetX($value){}在特定任务中是公共的,否则它应该是私有的。(私人电脑的功能) (我对如何编写通用setter不感兴趣,这个 问题是关于可见性/可接受性) 如果要公开访问属性,为什么要将属性声明为私有?在任何情况下,都可以使用将数据写入私有/受保护变量 public function __set($name, $value){ $this->$name = $value; } 或者,您可以将值传递到构造函数中: public function
如果要公开访问属性,为什么要将属性声明为私有?在任何情况下,都可以使用将数据写入私有/受保护变量
public function __set($name, $value){
$this->$name = $value;
}
或者,您可以将值传递到构造函数中:
public function __construct($A, $B, $C){
$this->A = $A;
$this->B = $B;
$this->C = $C;
}
您可以使用关联数组作为参数,而不是foreach循环:
public function __construct(array $args){
foreach ($args as $key=>$value){
$this->$key = $value;
}
}
构造函数的签名可能应该是_构造(数组$args=null),因此您可以使用new Obj($args)和new Obj(),但如果$args不是空的,您必须在正文中进行检查。这是哈基什式的,不推荐使用,但您可以这样做:
class My_Object{
// Final will disallow ovverriding
public final function genericArrSetter ( $property, $value ){
// Get caller function name
$callers = debug_backtrace();
// If it's not myStart do something more or less nasty
if($callers[1]['function'] !== 'myStart')
{
throw new Exception('This is not allowed');
}
$this->$property = $value;
}
}
例如:
function myStart (){
// set all data in Obj via generic setter
$obj = new Obj();
$obj-> genericArrSetter("x","value for x");
}
function OtherStart (){
// set all data in Obj via explicit setter
$obj = new Obj();
$obj-> explicitSetX ("value for x");
// Below will throw exception
$obj-> genericArrSetter("x","value for x");
}
有关呼叫者名称的更健壮的解决方案,请参见:
免责声明:未测试不推荐唯一可行的方法是使用接口和类型提示 声明两个接口:
interface ExplicitSetter {
public function setExplicitX($value);
}
interface GenericSetter {
public function setGeneric($x, $value);
}
您的类实现了这两者
class MyObject implements ExplicitSetter, GenericSetter {
private $x;
public function setExplicitX($value) {
$this->x = $value;
}
public function setGeneric($x, $value) {
$this->x = $value;
}
public function __toString() {
return $this->x;
}
}
现在,您可以使用类型暗示仅公开您感兴趣的接口。尝试使用接口未声明的方法将导致错误
function useExplicitSetter(ExplicitSetter $setter) {
$setter->setExplicitX('Hello explicit');
}
function useGenericSetter(GenericSetter $setter) {
$setter->setGeneric('x', 'Hello generic');
}
用法:
$obj = new MyObject();
useExplicitSetter($obj);
echo $obj; // Hello explicit
useGenericSetter($obj);
echo $obj; // Hello generic
首先:请使用
$
声明变量<代码>私人x代码>不正确,请使用private$x代码>,,第二:函数myStart
和OtherStart
在类Obj
?现在可能需要更容易理解。因此,您希望在myStart
中使用genericArrSetter
函数public,在OtherStart
中使用private?我希望能够在一个函数I中使用genericArrSetter有。在所有其他情况下,GenericarSetter不应该被访问。这不是我的问题。那么也许你应该澄清一下。如果您想要一个可公开访问的泛型集函数,那么已经有一个内置函数,缺少的到底是什么?如果要将值硬编码到myStart中,为什么不将它们硬编码到类定义中?它们不是硬编码的。我不想把这个问题描述得一团糟,仅此而已。X和X的值是从文件中自动提取的。我更新了问题,现在想你有其他答案了吗?这将允许只从myStart
调用genericArrSetter
(或以任何方式命名)。如你在评论中所写。啊,是的,谢谢!虽然我认为会有一个更合适的OOP来处理这个问题。我考虑的一个解决方案是创建一个新类,该类继承对象并具有泛型setter。那么,至少它是分离的,并且更容易迫使其他开发人员使用正确的设置方式。好吧,作为一个好的实践类,应该不知道也不依赖于谁在调用它。很酷,我将阅读这篇文章。我想这就是我要找的!只有接口或抽象类才能完成您需要的任务。没有奇怪的魔术,只是简单的OOP。
$obj = new MyObject();
useExplicitSetter($obj);
echo $obj; // Hello explicit
useGenericSetter($obj);
echo $obj; // Hello generic