Codeigniter 4 redirect issue

15 views Asked by At

I am stuck in redirect after user verification from database. Here is the error which i am getting

App\Controllers\Login::index(): Return value must be of type string, CodeIgniter\HTTP\RedirectResponse returned

Here is my code

namespace App\Controllers;
class Login extends BaseController
{
    public function index(): string
    {
        
        $request = \Config\Services::request();
        $session = \Config\Services::session();
        $db = \Config\Database::connect();
        //$redirectResponse = \config\Services::redirectresponse();
        
        if($request->getPost('email') !=""){
        $query = $db->table('users')->getWhere(['email' => $request->getPost('email'), 'password' => md5($request->getPost('password'))]);
        
        if($query->getNumRows() > 0){
            
            $user = $db->table('users')->getWhere(['email' => $request->getPost('email'), 'password' => md5($request->getPost('password'))])->getRow();
            $session->set('userid', $user->uid);
        
                return redirect('products');
             
             
        }else{
                $session->setFlashdata('error', 'Account Not Found or Password Incorrect');
            }
        }
        
        return view('login');
    }
}

I tried this too

return redirect()->route('products');

1

There are 1 answers

0
b126 On

You have incorrectly indicated that the return type of your index() method is a string.

The general principle of the methods contained in a Controller is to work on Request and Response properties. Most of the time, your methods will therefore receive Requests and return Responses or render Views. There is no reason for your index() to return a string.

By the way, you correctly extend the BaseController class. You therefore inherit its $request property and you don't need to instantiate it yourself with $request = \Config\Services::request();. You can simply use $this->request instead.

Try this code:

namespace App\Controllers;
class Login extends BaseController
{
    public function index()
    {
        $request = $this->request;
        $session = \Config\Services::session();
        $db = \Config\Database::connect();

        if ($request->getPost('email') != "") {
            $query = $db->table('users')->getWhere(['email' => $request->getPost('email'), 'password' => md5($request->getPost('password'))]);

            if ($query->getNumRows() > 0) {
                $user = $db->table('users')->getWhere(['email' => $request->getPost('email'), 'password' => md5($request->getPost('password'))])->getRow();
                $session->set('userid', $user->uid);
                return redirect('products');
            } else {
                $session->setFlashdata('error', 'Account Not Found or Password Incorrect');
            }
        }
        return view('login');
    }
}

General note: you should in theory move your common logic (session check for example) into the initController method of the BaseController class. Every Controller will then share it automatically as they inherint from BaseController. Or you can see Filters feature for this specific case. In the same type of question, it's also annoying that you have to connect to your DB in each of your controllers. See if you can centralize that or not depending on your own logic and needs.

Finally, be careful, since you are passing passwords (encrypted, admittedly) via the querystring, which can really quick become tricky.