如何在PHP中完成_构造函数后自动调用方法?
我编写了一个称为Task的小抽象类。我喜欢让每个任务逻辑的类来扩展它 在我的抽象类“Task”中,我喜欢调用在每个类中定义的已使用的已定义方法“execute” 我尝试使用神奇的方法如何在PHP中完成_构造函数后自动调用方法?,php,class,call,magic-methods,Php,Class,Call,Magic Methods,我编写了一个称为Task的小抽象类。我喜欢让每个任务逻辑的类来扩展它 在我的抽象类“Task”中,我喜欢调用在每个类中定义的已使用的已定义方法“execute” 我尝试使用神奇的方法\u call,但它不起作用 如果你注意到在我的方法中,我在回显一条从未在屏幕上打印过的消息 这是我的抽象任务类 <?php namespace App\Modules\Surveys\Tasks; use App\Modules\Surveys\Tasks\Support\Traits\HtmlHelpe
\u call
,但它不起作用
如果你注意到在我的方法中,我在回显一条从未在屏幕上打印过的消息
这是我的抽象任务类
<?php
namespace App\Modules\Surveys\Tasks;
use App\Modules\Surveys\Tasks\Support\Traits\HtmlHelper;
abstract class Task
{
/*
|
| This task base class provides a central location to place any logic that
| is shared across all of your tasks.
|
*/
use HtmlHelper;
/**
* checks wether a get method execute exists and calls it
*
* @param string $name
* @param array $args optional
* @return mixed
*/
public function __call($name, $args = [])
{
echo 'Attempt to execute task';
if (method_exists($this, 'execute')) {
return call_user_func_array('execute', $args);
} else {
throw new \Exception('execute method does does not exists in your task! ' . get_class($this) );
}
}
}
?>
这是一个逻辑类
<?php
namespace App\Modules\Surveys\Tasks\Interviews;
use App\Modules\Surveys\Tasks\Task;
use App\Modules\Surveys\Models\SurveyInterview;
use Exception;
class ResumeInterview extends Task
{
protected $surveyId;
protected $callId;
protected $myInterview;
/**
* Create a new task instance.
*
* @return void
*/
public function __construct($surveyId, $callId)
{
$this->surveyId = intval($surveyId);
$this->callId = intval($callId);
}
/**
* Resume existing interview if one exists using the giving $surveyId and $callId
*
* @return void
*/
protected function execute()
{
//find the current interview if one exits
$myInterview = SurveyInterview::surveyAndCall($this->surveyId, $this->callId)->first();
$this->setInterview($myInterview);
if( $this->wasResumed() ){
//At this point existing interview was found
if($myInterview->status != 'Pending'){
//At this point the interview is completed and should not be conducted
throw new Exception('This interview can not not be retaken. It\'s current status is "' . $myInterview->status . '"');
}
}
}
/**
* Return the current interview
*
* @return App\Models\Survey\SurveyInterview
*/
public function getInterview()
{
return $this->myInterview;
}
/**
* It checks whether ot the the interview was resumed
*
* @return boolean
*/
public function wasResumed()
{
return $this->getInterview() ? true : false;
}
/**
* It sets the interview
*
* @param Illuminate\Support\Collection $myInterview
* @param void
*/
protected function setInterview($myInterview)
{
$this->myInterview = $myInterview;
}
}
我会这样说:
abstract class Task {
[...]
public function __construct() {
$this->execute();
}
protected function execute() {
throw new Exception('NOT IMPLEMENTED');
}
[...]
}
class ResumeInterview extends Task {
protected $surveyId;
protected $callId;
protected $myInterview;
public function __construct($surveyId, $callId) {
$this->surveyId = intval($surveyId);
$this->callId = intval($callId);
parent::__construct();
}
protected function execute() { [...] }
}
只需在基类构造函数中调用execute()
EDIT:注意对parent::\uu construct()的调用只有在子类实现了自己的构造函数时才需要code>,否则就不需要了。为了避免必须在子类中调用父::\u construct
,一些框架将定义一个单独的init
方法供子类重写,该方法将从父类调用
abstract class Task
{
public function __construct($name, $args = [])
{
$this->init();
}
public function init()
{
// Throwing this exception is optional and can be removed to make init optional.
throw new \Exception('init method must be overridden by child class.');
}
}
class ResumeInterview extends Task
{
public function init()
{
echo "My awesome init method that does not need to use parent::!";
}
}
要做到这一点,您必须在子类中根本不使用\u构造函数。为什么不在父类构造函数中这样做,然后在子类中使用父::\u构造函数()代码>?比我快。那么,如果我也可以在扩展类构造函数中执行$this->execute(),为什么我还需要这些代码呢?我希望避免在每个任务类中写入$this->execute(),这样你就可以在基类构造函数中添加更多的逻辑并一次调用它。因此,没有办法避免使用parent::\u construct?@Mike A使用我的很棒的init方法进行验证,它不需要使用parent::进行任何操作!仅当父类未实现自己的\uu构造()
时。。或者它仍然必须调用parent::\uu construct()
,最终,这个解决方案与我自己的差不多。@MatteoTassinari-um,不,因为它有一个不同的名称。LOL,是的,但总体效果是一样的。@MatteoTassinari差不多。就我个人而言,我会使用您答案中常见的家长::
解决方案,只是添加了一种替代方法。