【问题标题】:Laravel Controller's constructor doesn't runLaravel Controller 的构造函数不运行
【发布时间】:2018-04-05 08:00:43
【问题描述】:

我有一个 Laravel 网络应用程序,其中我的每个其他控制器都有一个“父”控制器。我以这种方式构建逻辑是因为数据库由在线 SOAP 服务提供支持。

我的父控制器的构造函数如下所示:

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Lang;
use SoapClient;
use Session;

class SoapCtrl extends Controller
{
    public $client;
    public function __construct(Request $request) {
        // SoapClient
        $wsdl = '******';
        $args = [
            'trace' => true,
            'exceptions' => true,
            'soap_version' => SOAP_1_2,
            'cache_wsdl' => WSDL_CACHE_NONE,
        ];
        $this->client = new SoapClient($wsdl, $args);
    }
}

我还有很多其他控制器扩展了这个 SoapCtrl,例如这个:

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Lang;
use SoapClient;
use Session;

class MagistralCtrl extends SoapCtrl {

    public function __construct(Request $request) {
        parent::__construct($request);
        if(!parent::loggedin()) {
            return '';
        }
        if(!parent::have_right('magisztralis')) {
            return view('nopermission', $this->args);
        }
    }
}

他们都可以在视图函数中使用$this-&gt;client-&gt;anySoapMethod,所以看起来client 是被继承的并且可以工作。但是__construct 函数不运行。我用die('hello') 尝试过,仍然没有发生任何事情。我在扩展控制器中的构造函数不起作用。

请帮忙,我做错了什么?

【问题讨论】:

  • 你在哪里试过die()??
  • 在我的第二个控制器构造函数中,像这样:public function __construct(Request $request) { die('hello'); }

标签: php laravel constructor


【解决方案1】:

感谢 shivanshu,我找到了解决方案。默认情况下,Laravel 使用 Controller 类作为控制器,通常情况下你总是用你的扩展这个类。

但是,如果您想扩展另一个控制器,您仍然需要这个控制器来正确执行您的构造函数(可能还有其他东西)。我需要始终use 这个默认控制器每隔一个。

所以解决方案很简单,将use App\Http\Controllers\Controller; 放在文件顶部:

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Lang;
use SoapClient;
use Session;
use App\Http\Controllers\Controller; // You need to add this line to get it work

class MagistralCtrl extends SoapCtrl {

    public function __construct(Request $request) {
        parent::__construct($request);
        die('hello'); // Now prints hello
    }
}

【讨论】:

  • 您可以尝试存储库模式方法
【解决方案2】:

事情是在 Laravel 控制器构造函数在任何中间件之前执行,所以还没有用户。

另一件事是扩展控制器是不好的做法,你正在创建上帝的对象。在我看来,您应该为 SOAP 请求创建服务,而不是添加到父控制器并对其进行扩展。

<?php

class SoapCtrl
{
    /**
     * @var SoapClient
     */
    private $client;

    public function __construct()
    {
        $wsdl = '******';
        $args = [
            'trace' => true,
            'exceptions' => true,
            'soap_version' => SOAP_1_2,
            'cache_wsdl' => WSDL_CACHE_NONE,
        ];
        $this->client = new SoapClient($wsdl, $args);
    }

    /**
     * @return SoapClient
     */
    public function getClient()
    {
        return $this->client;
    }
}



class MagistralCtrl extends Controller
{
    public function myMethod(SoapCtrl $soapCtrl)
    {
        $soapClient = $soapCtrl->getClient();

    }
}

【讨论】:

  • controller constructor executes before any middleware 在我看来,它似乎根本没有被执行。
  • 尝试将 die 放入父构造函数中
  • 父构造函数工作,但我想知道为什么扩展不起作用,以及如何在不重写整个事情的情况下修复它。
  • 不,似乎我的构造函数被简单地跳过了。我的控制器中的任何其他方法都按预期工作。
  • 找到了一个相对简单的解决方案(不需要对整个代码进行折射),也感谢您的指导。把它放在答案中,这样也许我可以用这种简单的方法帮助未来的读者。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-02
  • 1970-01-01
  • 1970-01-01
  • 2020-05-29
相关资源
最近更新 更多