为什么每当我通过Codeigniter 4控制器的构造函数重定向某个东西时都不起作用?
<?php namespace AppControllersWebAuth;
class Register extends AppControllersBaseController
{
function __construct()
{
if(session('username')){
return redirect()->to('/dashboard');
}
}
public function index()
{
// return view('welcome_message');
}
}
但如果我把它放在索引中,它会像预期的那样工作。
public function index()
{
if(session('username')){
return redirect()->to('/dashboard');
}
}
问题是,我不想直接在索引中使用它,因为我需要在同一文件的其他方法上使用它。
根据Codeigniter论坛,您不能再使用构造函数中的redirect
方法重定向到任何控制器。
有关更多信息,请参阅以下链接
https://forum.codeigniter.com/thread-74537.html
它清楚地指出,redirect()
将返回一个类实例,而不是设置头,并且在PHP中实例化不同的类时不能返回另一个类的实例。
所以这就是为什么不能在构造函数中使用redirect
方法的原因。
相反,我可以建议您使用header
方法并重定向到您想要的控制器。
<?php namespace AppControllersWebAuth;
class Register extends AppControllersBaseController
{
function __construct()
{
if(session('username')){
header('Location: /dashboard');
}
}
}
如果这不可行或难以实现,您可以遵循以下代码
<?php namespace AppControllersWebAuth;
class Register extends AppControllersBaseController
{
function __construct()
{
//call to session exists method
$this->is_session_available();
}
private function is_session_available(){
if(session('username')){
return redirect()->to('/dashboard');
}else{
return redirect()->to('/login');
}
}
}
第二个解决方案将比第一个更具互动性。并确保该方法是私有的。这样就不应该从其他类实例调用它。
社区团队还提供了一个研究controller filter
的解决方案。
https://codeigniter4.github.io/CodeIgniter4/incoming/filters.html
请参阅螺纹。我希望它能帮助你找到更好的解决方案。
在这种情况下,您甚至不应该在控制器中执行这种逻辑。这应该在过滤器中完成,而不是在控制器中。
所以你有你的控制器注册。
你应该在你的应用程序/过滤器文件夹中创建一个过滤器,比如checkLogin.php
该过滤器应具有以下结构:
<?php
namespace AppFilters;
use CodeIgniterFiltersFilterInterface;
use CodeIgniterHTTPRequestInterface;
use CodeIgniterHTTPResponseInterface;
class CheckLogin implements FilterInterface
{
/**
* Check loggedIn to redirect page
*/
public function before(RequestInterface $request, $arguments = null)
{
$session = ConfigServices::session();
if (session('username')) {
return redirect()->to('/dashboard');
}
}
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
// Do something here
}
}
然后在你的app/config/Filters.php中,你应该将过滤器添加到所需的控制器中。
public $aliases = [
'csrf' => CodeIgniterFiltersCSRF::class,
'toolbar' => CodeIgniterFiltersDebugToolbar::class,
'honeypot' => CodeIgniterFiltersHoneypot::class,
'checkLogin' => AppFiltersCheckLogin::class,
];
// List filter aliases and any before/after uri patterns
public $filters = [
'checkLogin' => ['before' => ['Register']],
];
有关过滤器和如何使用的更多信息,请查看文档。
https://codeigniter.com/user_guide/incoming/filters.html?highlight=filters
然后,你甚至可以创建过滤器到你的其他控制器,在用户没有登录的情况下重定向到这个控制器
Codeigniter 4使用initController()
创建构造函数。
不能在__construct()
或initController()
函数中使用redirect()
。
但在调用控制器中的另一个函数之前,可以使用$response
参数或$this->response
在initController()
中调用重定向;
<?php namespace AppControllersWebAuth;
class Register extends AppControllersBaseController
{
public function initController(CodeIgniterHTTPRequestInterface $request, CodeIgniterHTTPResponseInterface $response, PsrLogLoggerInterface $logger)
{
// Do Not Edit This Line
parent::initController($request, $response, $logger);
if(session('username')){
$response->redirect(base_url('dashboard')); // or use $this->response->redirect(base_url('dashboard'));
}
}
public function index()
{
// return view('welcome_message');
}
}
我刚进入CI 4,遇到了与您相同的问题,因为我一直在使用CI 3的登录系统。
所以这里有正确的方法。享受
Codeigniter 4在Constructor上没有任何返回,但您可以像这样使用
public function __construct()
{
if (!session()->has('user_id')) {
header('location:/home');
exit();
}
}
不要忘记使用exit((
但是,您最好使用过滤器