Derek Gould
Derek Gould

Reputation: 11

Odd behavior from PHP header()

I'm trying to write a check to redirect users based on their progress through the sign up process for the site. I have this:

if($user = VRComponent::getLogin()) {
    if(VR::exists('vr_user','Signup',"userID={$user->ID}")) {
        $step = VR::select('vr_user','Signup',"userID={$user->ID}");
        $step = intval($step[0]['step']);
        if(!isset($_GET['step']) || $step != intval($_GET['step'])) {
            switch($step) {
                case 1: header("Location: /signup/one"); exit; break;
                case 2: header("Location: /signup/two"); exit; break;
                case 3: header("Location: /signup/three"); exit; break;
                case 4: header("Location: /signup/four"); exit; break;
            }
        }
    } else {
        header("Location: /account");
        exit;
    }
} else {
    header("Location: /");
    exit;
}



The exists and select functions are basically just aliases to mysql functions.

Essentially this checks if the user is logged in. If so, it checks to see if they've completed the sign up process. If not, it checks to see if the "page" get var passed is actually the last page they were on. If not, it redirects them to the correct page.

The logic works, however all external js and css files referenced by the page don't load. The weird thing is they don't throw a 404, instead the only contents of the files are:

Failed to load source for: https://domain.com/path/to/file/style.css

The other odd thing is the files don't load even if the condition for the if statement is false. Commenting out the switch statement (even when the if condition is false) allows the files to load, but of course the logic wouldn't be correct then.

I figure it pretty much has to be something simple, but I'm just not seeing it. I'm at the point where I'm about to put my fist through my monitor because the behavior makes no sense to me.

Thanks in advance
-D

Upvotes: 1

Views: 189

Answers (2)

Derek Gould
Derek Gould

Reputation: 11

Update: I slept on it and when I woke up I figured out the actual problem (it's amazing what a clear mind can do). Turns out PHP was doing exactly what I was telling it to do. Because I've never been satisfied with any 3rd party PHP framework, I decided to build my own a little while back. One of the things it does is automatically cull together all css and js files used in any given page into single files to reduce the number of http requests. It also mirrors the main page's requires in those css/js files and I have apache set up so it'll execute inline PHP. Therefore, the problem code was being required by the js/css files which was then redirecting to one of the signup pages because $_get['step'] was undefined. This kind of stuff really makes me glad I use my own framework, though. Sure, at times it makes me want to go medieval like a man with an axe on some zombies, but the freedom it affords and the ability to evolve it as I go far outweighs the rage. Not only that, but it makes everything so much easier (when I actually code it right) than any other framework I've used. Maybe someday when I feel it's ready for primetime, I'll release it to the public.

Old------------------------------------
After a few more hours of research I fixed it!

The issue was a redirect loop of sorts. For reasons unknown to me, the external files were being run through the block in my OP from the php file which was then changing the location to one of those redirects.

To fix it I checked for '.css' and '.js' in the php_self and disallowed the redirect if found. Here is the modified code:

if($user = VRComponent::getLogin()) {
    if(VR::exists('vr_user','Signup',"userID={$user->ID}")) {
        $step = VR::select('vr_user','Signup',"userID={$user->ID}");
        $step = intval($step[0]['step']);
        $css = stripos($_SERVER['PHP_SELF'],'.css');
        $js = stripos($_SERVER['PHP_SELF'],'.js');
        if(!$css && !$js && (!isset($_GET['step']) || $step != intval($_GET['step']))) {
            switch($step) {
                case 1: header('Location: /signup/one');
                    break;
                case 2: header('Location: /signup/two');
                    break;
                case 3: header('Location: /signup/three');
                    break;
                case 4: header('Location: /signup/four'); 
                    break;
            }
        }
    } else
        header("Location: /account");
} else
    header("Location: /");

Yes, it's crude, and I'll devise a more elegant solution sooner or later, but for now this'll have to do.

Thanks everyone for your help.

Upvotes: 0

Shad
Shad

Reputation: 15451

I imagine you are using a mod-rewrite to handle signup/*? If so, you might need to declare a <base href="APPROPRIATE BASE" /> in the <head> of your HTML so that the browser doesn't LOOK in a putative signup folder for css/js =)

Upvotes: 3

Related Questions