Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/226.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP中完成_构造函数后自动调用方法?_Php_Class_Call_Magic Methods - Fatal编程技术网

如何在PHP中完成_构造函数后自动调用方法?

如何在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

我编写了一个称为Task的小抽象类。我喜欢让每个任务逻辑的类来扩展它

在我的抽象类“Task”中,我喜欢调用在每个类中定义的已使用的已定义方法“execute”

我尝试使用神奇的方法
\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()的调用,否则就不需要了。

为了避免必须在子类中调用
父::\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差不多。就我个人而言,我会使用您答案中常见的
家长::
解决方案,只是添加了一种替代方法。