22

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

class cExample{

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

   return $someVar
   }//end of function

}//end of class


function outsideFunction(){

//Calls funExample();

}
4

8 回答 8

56

从技术上讲,可以使用反射 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");
于 2013-06-18T16:42:45.550 回答
20

这就是 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
}
于 2013-06-18T16:31:28.960 回答
5

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

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

于 2019-06-11T17:35:39.173 回答
4

你可以用另一个你公开的地方覆盖这个类。

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

(注意这不适用于私人会员)

但是私有和受保护成员的想法是不要从外部调用。

于 2013-06-18T16:32:01.207 回答
2

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

反正

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

这会起作用,但请记住,您不知道您的班级是由这种方式构成的。如果你改变了这个特征,那么你所有使用它的类也会被改变。为您使用的每个特征编写一个接口也是一个好习惯。

于 2013-06-18T16:34:30.480 回答
2

另一种选择(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!
于 2020-09-05T20:10:26.833 回答
1

在这里我可以给你一个例子,如下所示

<?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 中,您可以使用反射来做到这一点。要调用受保护或私有方法,请使用 setAccessible() 方法http://php.net/reflectionmethod.setaccessible (只需将其设置为 TRUE)

于 2013-06-18T16:39:17.293 回答
0

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

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

     return $bookingPriceDetails->quotesPrice($request , selectedFranchisees());

BookingController是我想从中获取方法的类名。是我想在不同的类中访问的方法。protectedquotesPrice( $req , $selectedFranchise)

于 2021-12-23T12:29:46.863 回答