【问题标题】:Get called function from parent __construct从父 __construct 获取调用函数
【发布时间】:2019-08-30 02:50:09
【问题描述】:

是否有任何聪明的解决方案可以从父类__construct 中获取被调用的方法?

示例:

call_user_func_array([$childrenController, $indexMethod], array());

我想知道 $indexMethod 被调用了,但我尝试在 $parentController __construct 中获取此信息。

我知道我可以用

获得类名
get_called_class()

或者通过ReflectionClass,但是被调用的方法有什么解决办法吗?

已经试过了

debug_backtrace()

但我只能获得关于另一个方向的任何信息。

编辑:

有人打电话给我的网站: https://example.com/index/firstaction

然后路由器正在搜索控制器:indexcontroller 和方法:firstaction。

索引控制器扩展了 ParentController 类。

现在我想在 indexcontroller 的 parent(ParentController) 中获取被调用方法的名称(firstaction)

class ParentController {

public function __construct() 
{
}

【问题讨论】:

  • 请提供完整的样本以及您何时/何地需要哪些信息,目前还不清楚。
  • I want to know that $indexMethod got called - 为什么这对parent 很重要。您可以设置父母和孩子都拥有indexMethod(){ $this->called = 1;} 的属性,然后检查if($this->called) 等。
  • 我想通过传递文件夹名(称为类)和文件名(称为方法)动态地告诉 smarty 模板的目录。所以我认为最好的解决方案是在任何控制器继承的 ParentController 中执行此操作。
  • ParentController::construct 在对象的任何其他方法之前被调用,因此您无法预测从那里会发生什么。除非我误解了你的意思。

标签: php methods get parent construct


【解决方案1】:

我能想到的唯一方法(不是正确的 OOP 主体)

class ParentController { 
   protected $something;
   public function __construct() 
   {
         ///check if child sets this
         echo $this->something ? "set\n" : "notset\n";
   }
}
//---------------------
class ChildController0 extends ParentController{

   public function __construct() 
   {
         parent::__construct();
    }
}
//---------------------
class ChildController1 extends ParentController {

   public function __construct() 
   {
         $this->indexMethod();
         parent::__construct();
   }

   public function indexMethod(){
      $this->something = 1;
   }
}

new ChildController0();
new ChildController1();

输出

notset
set

这就是我指出从哪里调用它们并不重要的地方。基本上,您只需要设置一些由父级共享的属性来维护是否对该类进行了调用的状态。

另一个明显的问题是这个电话

 call_user_func_array([$childrenController, $indexMethod], array());

你从$childrenController那里得到这个。我假设您只会在孩子的构造函数中使用parent::__construct()。如果是这种情况,那么您将没有“时间”到 call_user_func_array 及其实例(除非来自子的构造函数),因为您没有得到该实例(在类之外)在运行后使用 tell建设完成。例如

 $childrenController = new ChildController0();
  //__construction is finished at this point.

 call_user_func_array([$childrenController, $indexMethod], array());

如果以典型方式使用(在子构造中调用),基本上您必须在构造结束之前调用public function indexMethod 以便在parent::__construct 中访问它。所以你有一个非常小的窗口,你可以在孩子的构造函数中执行此操作。

也就是说其他方法不是这样,construct是一个特例。也许你可以做静态来解决这个问题......等等。我不知道。

最后一点

从 OOP 主体的角度来看,这可能是错误的,因为现在 Parent 类对其中一个子类具有隐藏的依赖关系。我确信它违反了 S.O.L.I.D -

想通过传递文件夹名(称为类)和文件名(称为方法)动态地告诉 smarty 模板的目录。所以我认为最好的解决方案是在任何控制器继承的 ParentController 中执行此操作

为什么不把它通过孩子传递给父母:

class ParentController { 
   protected $foo;
   public function __construct($foo) 
   {
        $this->setFoo($foo);
   }

   public function getFoo(){ return $this->foo; }
   public function setFoo($foo){ $this->foo = $foo; }
}

现在您可以将 foo 设置为您的心满意足了。

class ChildController0 extends ParentController{
   //some piece of data only for child
   protected $bar;

   public function __construct($foo, $bar) 
   {
         parent::__construct($foo);
         $this->bar = $bar;
    }
}

$child = new ChildController0('foo'); //this->foo is 'foo'
$child->setFoo('bar'); //now its bar

如果您只想在父类中注册一条信息,我认为您不需要任何特殊技巧。特别是当您编写该类时,只需像添加任何旧属性一样添加它。

干杯!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-24
    相关资源
    最近更新 更多