未重定向到 Codeigniter 4 中的特定 URL

Not redirected to specific URL in Codeigniter 4

为什么每当我通过 Codeigniter 4 控制器的构造函数重定向某些内容时都不起作用?

<?php namespace App\Controllers\Web\Auth;

class Register extends \App\Controllers\BaseController
{
    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 方法重定向到任何控制器。

更多信息请参考以下link

https://forum.codeigniter.com/thread-74537.html

它明确指出 redirect() 将 return 一个 class 实例而不是设置一个 header 并且你不能 return 另一个 class 在 PHP.

中实例化不同的 class

所以这就是为什么你不能在构造函数中使用 redirect 方法。

相反,我可以建议您使用 header 方法并重定向到您想要的控制器。

<?php namespace App\Controllers\Web\Auth;

class Register extends \App\Controllers\BaseController
{
    function __construct()
    {
        if(session('username')){
            header('Location: /dashboard');
        }
    }
}

如果这不可行或难以实现,您可以按照以下代码

<?php namespace App\Controllers\Web\Auth;

class Register extends \App\Controllers\BaseController
{
    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');
        }
    }
}

第二个解决方案将比第一个解决方案更具交互性。并确保该方法是私有的。因此不应从其他 class 个实例调用它。

社区团队也给出了一个解决方案来研究controller filter

https://codeigniter4.github.io/CodeIgniter4/incoming/filters.html

请参考主题。我希望它可以帮助您找到更好的解决方案。

Codeigniter 4 在 Constructor 上没有任何 return,但你可以这样使用

public function __construct()
{
    if (!session()->has('user_id')) {
        header('location:/home');
        exit();
    }
}

不要忘记使用 exit()

但是,你最好使用Filters

在这种情况下,您甚至不应该在控制器中执行这种逻辑。这应该在过滤器而不是你的控制器中完成。

所以你有你的控制器注册。

您应该在 app/filters 文件夹中创建一个过滤器,类似于 checkLogin.php

该过滤器应具有以下结构:

<?php

namespace App\Filters;

use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;

class CheckLogin implements FilterInterface
{

    /**
     * Check loggedIn to redirect page
     */
    public function before(RequestInterface $request, $arguments = null)
    {
        $session = \Config\Services::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' => \CodeIgniter\Filters\CSRF::class,
    'toolbar' => \CodeIgniter\Filters\DebugToolbar::class,
    'honeypot' => \CodeIgniter\Filters\Honeypot::class,
    'checkLogin' => \App\Filters\CheckLogin::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->responseinitController()中调用重定向,然后再调用控制器中的另一个函数;

<?php namespace App\Controllers\Web\Auth;

class Register extends \App\Controllers\BaseController
{
    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $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.

所以here是正确的做法。享受。