Welcome Guest, Not a member yet? Register   Sign In
Redirect inside Constructor NOT WORKING
#1

Hello All,

I need help with a explanation on WHY a "return redirect->to()" wont work inside a constructor...

This wont work:

PHP Code:
    public function __construct()
    {
        return 
redirect()->to('http://www.google.com');
    }


    public function 
index()
    {
        echo 
'Hello World!!!!!';
    } 
 
This will work:

PHP Code:
    public function __construct()
    {
        
    }


    public function 
index()
    {
        return 
redirect()->to('http://www.google.com');
        
        echo 
'Hello World!!!!!';
    } 

Of course this is only a example and I will have some logic inside the constructor, like: if(NotLogged){ redirect() }

Thank you for the explanation...
Reply
#2

(This post was last modified: 10-06-2019, 09:52 AM by dave friend.)

It doesn't work because there isn't any code that is looking for a return from the constructor. As a rule, PHP __construct() methods should not return anything.
Reply
#3

Redirect now returns a class instead of just setting headers. You cannot return an instance of another class while instantiating a different class in PHP.

Check out Controller Filters
Reply
#4

(10-06-2019, 08:42 PM)kilishan Wrote: Redirect now returns a class instead of just setting headers. You cannot return an instance of another class while instantiating a different class in PHP.

Check out Controller Filters

Thank you Sir !

I am sooo used to use CI3 that I forgot a little bit about the PHP itself...

I am very eager to use Myth Auth in my projects... But, meanwhile, I am using Ben´s Ion Auth 4 ...

The point is that I want to make my code cleaner and I am checking for login in the constructor or in the baseController.

Do you have any tips about the best way of doing it ?

I am doing like this:

PHP Code:
    public function checkLoggedIn()
    {
        
//Checks if user is LOGGED IN 
        
if (!$this->ionAuth->loggedIn()) :

            if (
$this->request->isAJAX()) :

                
$data = [
                    
's' => false//Success = False
                    
'm' => 'Not Logged In' //Message to be returned
                
];

                
header("HTTP/1.1 401 Unauthorized"); //Status Code 401 = Unauthorized
            
                
echo json_encode($data);

                exit;

            endif;

            
header("Location: /auth");

            exit;

        endif;
    } 
Reply
#5

Hi,
I would like to know how to redirect in constructor too for "code cleaniness" as OP said.
Thanks for your help.
Reply
#6

"code cleanness" can mean any number of things. For many of those definitions, Controller Filters, as previously mentioned, will keep it clean for you.

If you absolutely must do it from the constructor, you can do a slightly hacky thing and throw a RedirectException with the URL to redirect to as the message. But I highly encourage looking into controller filters, as they're specifically designed to handle the types of situations you're asking about.
Reply
#7

(12-02-2019, 10:15 AM)kilishan Wrote: "code cleanness" can mean any number of things. For many of those definitions, Controller Filters, as previously mentioned, will keep it clean for you.

If you absolutely must do it from the constructor, you can do a slightly hacky thing and throw a RedirectException with the URL to redirect to as the message. But I highly encourage looking into controller filters, as they're specifically designed to handle the types of situations you're asking about.

You can always redirect using the "vanilla" PHP way: 

 
PHP Code:
        //Redirects to Unauthorized main page
        header("Location: /unauthorized"); 

Or send a JSON message and stop php after:

PHP Code:
            //Return a JSON response with the error
            //Set the header for the response to be identified as a JSON
            header('Content-Type: application/json');
            //Status Code 401 = Unauthorized
            header("HTTP/1.1 401 Unauthorized");

            //Writes the JSON message for the user
            echo $e->getMessage();

            die; //Stops executing the PHP 

Big Grin

That is how I did it inside construct...
Reply
#8

(12-02-2019, 10:15 AM)kilishan Wrote: "code cleanness" can mean any number of things. For many of those definitions, Controller Filters, as previously mentioned, will keep it clean for you.

If you absolutely must do it from the constructor, you can do a slightly hacky thing and throw a RedirectException with the URL to redirect to as the message. But I highly encourage looking into controller filters, as they're specifically designed to handle the types of situations you're asking about.

Thanks a lot Lonnie for this advice/comment and this tutorial (https://www.patreon.com/lonnieezell/posts?tag=filters) it's very helped me when catch similar problem with redirect.
Reply
#9

The correct way of doing it in CI 4 is using Controller Filters.

This is how Lonnie doe's it for Myth/Auth.

PHP Code:
<?php namespace Myth\Auth\Filters;

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

class 
LoginFilter implements FilterInterface
{
    
/**
     * Do whatever processing this filter needs to do.
     * By default it should not return anything during
     * normal execution. However, when an abnormal state
     * is found, it should return an instance of
     * CodeIgniter\HTTP\Response. If it does, script
     * execution will end and that Response will be
     * sent back to the client, allowing for error pages,
     * redirects, etc.
     *
     * @param \CodeIgniter\HTTP\RequestInterface $request
     *
     * @return mixed
     */
    
public function before(RequestInterface $request)
    {
        if (! 
function_exists('logged_in'))
        {
            
helper('auth');
        }

        
$current = (string)current_url(true)
            ->
setHost('')
            ->
setScheme('')
            ->
stripQuery('token');

        
// Make sure this isn't already a login route
        
if (in_array((string)$current, [route_to('login'), route_to('forgot'), route_to('reset-password')]))
        {
            return;
        }

        
// if no user is logged in then send to the login form
        
$authenticate Services::authentication();
        if (! 
$authenticate->check())
        {
            
session()->set('redirect_url'current_url());
            return 
redirect('login');
        }
    }

    
//--------------------------------------------------------------------

    /**
     * Allows After filters to inspect and modify the response
     * object as needed. This method does not allow any way
     * to stop execution of other after filters, short of
     * throwing an Exception or Error.
     *
     * @param \CodeIgniter\HTTP\RequestInterface  $request
     * @param \CodeIgniter\HTTP\ResponseInterface $response
     *
     * @return mixed
     */
    
public function after(RequestInterface $requestResponseInterface $response)
    {

    }

    
//--------------------------------------------------------------------


Would be a good idea to sit down on a weekend and read the CodeIgniter 4 User Guide.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#10

It might interest someone... you can still redirect from the constructor using:

PHP Code:
header('Location: '.base_url());
exit(); 
Reply




Theme © iAndrew 2016 - Forum software by © MyBB