我能/怎样……在PHP中调用类之外的受保护函数


Can I/How to... call a protected function outside of a class in PHP

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

class cExample{
   protected function funExample(){
   //functional code goes here
   return $someVar
   }//end of function
}//end of class

function outsideFunction(){
//Calls funExample();
}

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

这里有一个快速反射的例子,以防这是少数真正需要的情况之一:

<?php
class foo { 
    protected function bar($param){
        echo $param;
    }
}
$r = new ReflectionMethod('foo', 'bar');
$r->setAccessible(true);
$r->invoke(new foo(), "Hello World");

这就是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 Foo {
    protected function do_foo() {
        return 'Foo!';
    }
}
$bar = new class extends Foo {
    public function do_foo() {
      return parent::do_foo();
    }
}
$bar->do_foo(); // "Foo!"
https://www.php.net/manual/en/language.oop5.anonymous.php

你可以用另一个类来覆盖这个类,并将其设置为public。

class cExample2 extends cExample {
  public function funExample(){
    return parent::funExample()
  }
}

(注意这对私有成员无效)

但是private和protected成员的思想是不能从外部调用

另一个选项(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!

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

反正

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();

这将工作,但要记住,你不知道你的类是由这种方式组成的。如果你改变了这个特性,那么你所有使用它的类也会被改变。

为你使用的每个trait都写一个接口也是一个很好的实践。

我可以给你一个像下面这样的例子

<?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();
?>

或其他方式使用最新的php

在PHP中,您可以使用Reflections来完成此操作。要调用受保护或私有方法,请使用setAccessible()方法http://php.net/reflectionmethod.setaccessible(只需将其设置为TRUE)

我正在使用Laravel。在之外访问受保护的方法时遇到问题。

   $bookingPriceDetails = new class extends BookingController {
        public function quotesPrice( $req , $selectedFranchise) {
           return parent::quotesPrice($req , $selectedFranchise);
        }
    };
     return $bookingPriceDetails->quotesPrice($request , selectedFranchisees());

这里的BookingController名称,我想从中获得protected方法。quotesPrice( $req , $selectedFranchise)是方法,我想在不同的类访问