我可以/如何...在PHP中调用类外的受保护函数

Ter*_*ter 13 php function protected call

我有一个在某个类中定义的受保护函数.我希望能够在另一个函数中将该受保护函数调用到类之外.这是可能的,如果是这样,我怎么能实现它

class cExample{

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

   return $someVar
   }//end of function

}//end of class


function outsideFunction(){

//Calls funExample();

}
Run Code Online (Sandbox Code Playgroud)

Pet*_*eer 41

从技术上讲,可以使用反射API调用private和protected方法.然而,99%的时间这样做是一个非常糟糕的主意.如果你可以修改类,那么正确的解决方案可能只是将方法公之于众.毕竟,如果你需要在课外访问它,那就不会标记它受到保护.

这是一个快速反映的例子,如果这是极少数需要它的情况之一:

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

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

  • 对于知道自己在做什么的人来说,这是正确的答案. (7认同)

vik*_*ter 13

这是OOP的要点 - 封装:

私人的

Only can be used inside the class. Not inherited by child classes.
Run Code Online (Sandbox Code Playgroud)

受保护

Only can be used inside the class and child classes. Inherited by child classes.
Run Code Online (Sandbox Code Playgroud)

上市

Can be used anywhere. Inherited by child classes.
Run Code Online (Sandbox Code Playgroud)

如果您仍希望在外部触发该函数,则可以声明一个触发受保护方法的公共方法:

protected function b(){

}

public function a(){
  $this->b() ;
  //etc
}
Run Code Online (Sandbox Code Playgroud)

  • 如果它们都扩展相同的抽象类,则您可以访问另一个实例的受保护成员。[直到我看到它我才相信。](https://gist.github.com/flowl/774c6e6335b6cb205c352ad67af2799c) (3认同)

Luc*_*nte 9

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

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

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

$bar->do_foo(); // "Foo!"
Run Code Online (Sandbox Code Playgroud)

https://www.php.net/manual/en/language.oop5.anonymous.php


kub*_*bio 6

另一种选择(PHP 7.4)

<?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!
Run Code Online (Sandbox Code Playgroud)