无法从 CodeIgniter 4 中的子文件夹初始化父控制器
Can't Initialize Parent Controller from Subfolder in CodeIgniter 4
我在CI4项目中有如下结构:
app
pages
Front.php
Member.php
manage
Courses.php
路由规则如下:
$routes->group('pages', ['namespace' => 'App\Pages'], function ($routes) {
$routes->resource('member', ['only' => ['index', 'show']]);
$routes->group('manage', ['namespace' => 'App\Pages\Manage'], function ($routes) {
$routes->resource('courses', ['only' => ['index', 'update']]);
});
});
Front.php为主控制器
namespace App\Pages;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
class Front extends \CodeIgniter\Controller
{
protected $me;
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) {
parent::initController($request, $response, $logger);
$this->me = $this->run();
log_message('info', 'My id: ' . $this->me);
}
private function run() {
return 10;
}
protected function showVal($val) {
log_message('info', 'Value is: ' . $val);
}
}
Member.php 扩展 Front.php.
namespace App\Pages;
class Member extends Front
{
protected $model;
public function __construct()
{
log_message('info', 'My id in Member: ' . $this->me);
helper('utils');
$this->model = model('App\Models\MemberModel');
}
public function index() {}
public function show($mid) {}
}
访问 URL 网站。com/pages/member 产生以下日志消息:
My id: 10
My id in Member: 10
说明前端控制器初始化正确
但是,我无法从子文件夹控制器初始化前端控制器。
namespace App\Pages\Manage;
use App\Pages\Front;
class Courses extends Front
{
public function __construct()
{
log_message('info', 'My id in Courses: ' . ($this->me ?? 'Not available'));
}
public function index() {}
public function update($cid) {
$this->showVal(100);
}
}
访问网站。com/pages/manage/courses 给出以下日志:
My id in Courses is: not available
但是,对课程执行 PUT 请求会给出日志:
My id in Courses is: not available
Value is: 100
因此课程控制器能够包含前端控制器但无法对其进行初始化。
我错过了什么?
我应该让它以与成员控制器相同的方式初始化。
我是否需要通过在课程 class 构造函数中调用 parent::initController(...) 来手动初始化它?
感谢您的帮助。
In php __construct() 不会自动调用 parent::__construct()。 initController() 也不会被任何扩展 class 自动调用。
然而,从当前实例调用(几乎)任何函数都会调用 initController()。您确实在 Member.php 的构造函数中实例化了一个模型,这强制了共享实例。
一种确保初始化安全的方法是在扩展构造函数中调用 initController()。
我在CI4项目中有如下结构:
app
pages
Front.php
Member.php
manage
Courses.php
路由规则如下:
$routes->group('pages', ['namespace' => 'App\Pages'], function ($routes) {
$routes->resource('member', ['only' => ['index', 'show']]);
$routes->group('manage', ['namespace' => 'App\Pages\Manage'], function ($routes) {
$routes->resource('courses', ['only' => ['index', 'update']]);
});
});
Front.php为主控制器
namespace App\Pages;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
class Front extends \CodeIgniter\Controller
{
protected $me;
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) {
parent::initController($request, $response, $logger);
$this->me = $this->run();
log_message('info', 'My id: ' . $this->me);
}
private function run() {
return 10;
}
protected function showVal($val) {
log_message('info', 'Value is: ' . $val);
}
}
Member.php 扩展 Front.php.
namespace App\Pages;
class Member extends Front
{
protected $model;
public function __construct()
{
log_message('info', 'My id in Member: ' . $this->me);
helper('utils');
$this->model = model('App\Models\MemberModel');
}
public function index() {}
public function show($mid) {}
}
访问 URL 网站。com/pages/member 产生以下日志消息:
My id: 10
My id in Member: 10
说明前端控制器初始化正确
但是,我无法从子文件夹控制器初始化前端控制器。
namespace App\Pages\Manage;
use App\Pages\Front;
class Courses extends Front
{
public function __construct()
{
log_message('info', 'My id in Courses: ' . ($this->me ?? 'Not available'));
}
public function index() {}
public function update($cid) {
$this->showVal(100);
}
}
访问网站。com/pages/manage/courses 给出以下日志:
My id in Courses is: not available
但是,对课程执行 PUT 请求会给出日志:
My id in Courses is: not available
Value is: 100
因此课程控制器能够包含前端控制器但无法对其进行初始化。
我错过了什么?
我应该让它以与成员控制器相同的方式初始化。
我是否需要通过在课程 class 构造函数中调用 parent::initController(...) 来手动初始化它?
感谢您的帮助。
In php __construct() 不会自动调用 parent::__construct()。 initController() 也不会被任何扩展 class 自动调用。
然而,从当前实例调用(几乎)任何函数都会调用 initController()。您确实在 Member.php 的构造函数中实例化了一个模型,这强制了共享实例。
一种确保初始化安全的方法是在扩展构造函数中调用 initController()。