Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我能/怎么。。。在PHP中调用类外的受保护函数_Php_Function_Call_Protected - Fatal编程技术网

我能/怎么。。。在PHP中调用类外的受保护函数

我能/怎么。。。在PHP中调用类外的受保护函数,php,function,call,protected,Php,Function,Call,Protected,我有一个在特定类中定义的受保护函数。我希望能够在另一个函数的类之外调用此受保护的函数。这是否可能?如果可能,我如何实现 class cExample{ protected function funExample(){ //functional code goes here return $someVar }//end of function }//end of class function outsideFunction(){ //Calls funExamp

我有一个在特定类中定义的受保护函数。我希望能够在另一个函数的类之外调用此受保护的函数。这是否可能?如果可能,我如何实现

class cExample{

   protected function funExample(){
   //functional code goes here

   return $someVar
   }//end of function

}//end of class


function outsideFunction(){

//Calls funExample();

}

这就是OOP封装的要点:

私人

Only can be used inside the class. Not inherited by child classes.
受保护

Only can be used inside the class and child classes. Inherited by child classes.
公开

Can be used anywhere. Inherited by child classes.
如果仍要在外部触发该函数,可以声明一个公共方法来触发受保护的方法:

protected function b(){

}

public function a(){
  $this->b() ;
  //etc
}

您可以使用另一个将该类公开的类重写该类

class cExample2 extends cExample {
  public function funExample(){
    return parent::funExample()
  }
}
(注意这不适用于私人成员)


但是私有和受保护成员的概念是不能从外部调用。

如果你想在类之间共享代码,你可以使用traits,但这取决于你想如何使用你的函数/方法

反正

trait cTrait{
   public function myFunction() {
      $this->funExample();
   }
}

class cExample{
   use cTrait;

   protected function funExample() {
   //functional code goes here

   return $someVar
   }//end of function

}//end of class

$object = new cExample();
$object->myFunction();

这是可行的,但请记住,你不知道你的班级是用这种方式组成的。如果你改变了这个特性,那么你所有使用它的类也会改变。为您使用的每个特性编写一个接口也是一种很好的做法。

这里我可以给您举一个如下示例

<?php
    class dog {
        public $Name;
        private function getName() {
            return $this->Name;
        }
    }

    class poodle extends dog {
        public function bark() {
            print "'Woof', says " . $this->getName();
        }
    }

    $poppy = new poodle;
    $poppy->Name = "Poppy";
    $poppy->bark();
?>

从技术上讲,可以使用反射API调用私有和受保护的方法。然而,99%的时间这样做是一个非常糟糕的主意。如果您可以修改该类,那么正确的解决方案可能是将该方法公开。毕竟,如果您需要在类之外访问它,那么就无法将其标记为protected

下面是一个快速反射示例,如果这是极少数情况下确实需要的情况之一:

<?php
class foo { 
    protected function bar($param){
        echo $param;
    }
}

$r = new ReflectionMethod('foo', 'bar');
$r->setAccessible(true);
$r->invoke(new foo(), "Hello World");

如果父方法受保护,则可以使用匿名类:

class Foo {
    protected function do_foo() {
        return 'Foo!';
    }
}

$bar = new class extends Foo {
    public function do_foo() {
        parent::do_foo();
    }
}

$bar->do_foo(); // "Foo!"
另一个选项(PHP 7.4)


你不能。这将首先破坏具有受保护功能的目的。你可以有一个公共方法来代表你调用受保护的方法,但是为什么一开始就有一个受保护的方法呢?对于知道自己在做什么的人来说,这是正确的答案。旁注:这在PHP 5.4+中可用(是的!)2018年有任何变化/新的可能性吗?这是纯金的(以及问题的实际答案)如果另一个实例的受保护成员都扩展了相同的抽象类,则可以访问它们。
<?php
class cExample {
   protected function funExample(){
       return 'it works!';
   }
}

$example = new cExample();

$result = Closure::bind(
    fn ($class) => $class->funExample(), null, get_class($example)
)($example);

echo $result; // it works!