tags:

views:

327

answers:

5

I am creating a multipage form in PHP, using a session. The $stage variable tracks the user's progress in filling out the form, (UPDATE) and is normally set in $_POST at each stage of the form.

On the second page (stage 2), the form's submit button gets its value like this:

echo '<input type="hidden" name="stage" value="';
echo $stage + 1;
echo '" />;

That works fine - $stage + 1 evaluates to 3 if I'm on page 2. But since I'm doing this more than once, I decided to pull this code out into a function, which I defined at the top of my code, before $stage is mentioned.

In the same spot where I previously used the code above, I call the function. I have verified that the function's code is the same, but now $stage + 1 evaluates to 1.

Is PHP evaluating my variable when the function is defined, rather than when it's called? If so, how can I prevent this?

Update 1

To test this theory, I set $stage = 2 before defining my function, but it still evaluates to 1 when I call the function. What's going on?

Problem Solved

Thanks to everyone who suggested variable scope as the culprit - I'm slapping my forehead now. $stage was a global variable, and I didn't call it $GLOBAL_stage, like I usually do, to prevent this sort of problem.

I added global $stage; to the function definition and it works fine. Thanks!

+2  A: 

This is really hard to answer without more code. One thing to check is that you are saving stage back into the session before the next page loads. If stage is null, empty, or a string, stage + 1 will be 1.

To debug the session, put print_r($_SESSION); die; at the top of each page.

tkotitan
+1  A: 

The source code would come in handy when debugging your code.

How is $stage defined or initialized? Functions have their own variable scope – what's defined in the function, stays in the function. Unless you define a variable as global in the beginning of the function, that is (global $foo;).

Henrik Paul
+5  A: 

No, PHP will evaluate your variable when the function is called. But your function has a local variable scope, i.e. without seeing your function I'd guess that you are operating on a local variable. You can import global variables into you function although this is discouraged:

function myfunction() {
    global $stage;
    ...
}

It's really hard to say without knowledge of your code, but I'd go on to guess that you are using 'register globals' to inject your form parameters into global PHP variables ($state, in this case). You might want to consider turning register_globals off because it really is a security risk and using the so-called superglobal variables instead.


edit

Ok, so you're seeing your stage in the $_POST array. Still wildly guessing about your function, you might try the following:

function my_insert_stage_param() {
    global $stage;
    echo '<input type="hidden" name="stage" value="';
    echo $_POST['stage'] + 1;
    echo '" />';
}

Suberglobals like the $_POST array don't need to be declared with global.

cg
the global scope works between request, once the page finished to load, your global variable will be undefined. in this case, you should use sessions
Gabriel Sosa
Well, yes. But please note my latest addition to my answer. Since nerdposeur claims that "echo $stage + 1;" is working accross pages, I assume he is using 'register globals'.
cg
+1  A: 

It sounds as though you're hitting a scope problem.

Try putting:

global $stage;

As the first line in the function.

Chad Birch
+1  A: 

You really should pass the stage value as a param to the function instead of relying on global or superglobal ($_POST).

function formNextStage($stage) {
    return formHidden('stage', $stage + 1);
}

function formHidden($name, $value = '') {
    return sprintf('<input type="hidden" name="%s" value="%s" />', $name, $value);
}
echo formNextStage($stage);

I recommend you dump the formStage function completely and use the formHidden like

echo formHidden('stage', $stage + 1);

You can build on that function with optional attributes as array, escapeing names/values, etc when needed.

function formHidden($name, $value = '', $attributes = array(), $escape = true)
OIS
I wish I could vote up more than once. While all the other comments saying "use globals" are factually correct, they're encouraging bad programming.
Sean McSomething