# Solved: set cookie and redirect



## JiminSA (Dec 15, 2011)

Can anyone explain to me why the following php does not a) create a cookie b) redirect?

```
if(isset($_POST['submit']) && $_POST['submit'] == 'Validate Key')
	{
		$_SESSION['Qkey'] = $_POST['key'];
		checkKey($result);
		$row = mysql_fetch_array($result);
		$id = $_SESSION['rec_id'] = $row['id'];
		if(mysql_num_rows($result) > 0)	
		{
			[COLOR="Red"]header('refresh: 5; url=quiz.php?recno=yes');
			setcookie('rec_id',$_SESSION['rec_id'],time() + (86400 * 366));[/COLOR]
			exit;
		}
		else
		{
			header('Location: quiz.php?recno=none');
			exit;
		}

	}
```
i.e. conditions are such that the code in red should be executed. What happens, is that the script disappears into cyberspace - performing neither the redirect(refresh) or the setcookie, but simply dying


----------



## colinsp (Sep 5, 2007)

Surely your second $POST in your isset should be within brackets?

Put some breakpoints in and print the variables to ensure they are being set also where is $result coming from?


----------



## JiminSA (Dec 15, 2011)

Thanks for the suggestions Colin


> Surely your second $POST in your isset should be within brackets?


I've never had problems omitting brackets for the second test. - This is how I get $result

```
function checkKey($result)
	{
		Global $result;
		
		$qkey = $_SESSION['Qkey'];

		$result = mysql_query("SELECT * FROM quest WHERE Qkey='$qkey'") or die(mysql_error());
	}
```
My problem appears to be in the header process (which apparently includes setcookie)


----------



## Ent (Apr 11, 2009)

I'm sure you know this, but be very careful about including anything in your SQL statement that has come at any point from user input, even if the place you're immediately getting it from is a session variable on the server. 

On the actual question:
Does the server think setCookie worked? 
(You can find out if you echo the return value)


----------



## JiminSA (Dec 15, 2011)

> I'm sure you know this, but be very careful about including anything in your SQL statement that has come at any point from user input, even if the place you're immediately getting it from is a session variable on the server.


Thanks for your input Josiah
I tend to leave all my security until after my testing is complete and the site is functional. Then I fine tooth-comb security.


> Does the server think setCookie worked?


In short No.
As I mentioned the page goes into limbo when I attempt to send the headers.
However, I have done a workaround, inasmuch as I have separated the setcookie and the redirect (setting the cookie on the redirect page), which has solved the limbo state, but I still don't understand how a dual header send doesn't work


----------



## Ent (Apr 11, 2009)

The dual headers certainly should work, and if seperating concerns works (at least as a workaround) it seems the refresh is probably the issue. 
Let me have a quick play around.

Edit:

So, this code works for me:

```
<?php
header('refresh: 5; url=result.php?test=Working');
setcookie('refreshtest','chaos',time() + (86400 * 366));
exit;
?>
```
Inspecting the headers in firebug (with the obvious change to give me a bit of time) I get this:
...
Set-Cookierefreshtest=chaos; expires=Fri, 27-Nov-2015 12:21:13 GMT; Max-Age=31622400X-Powered-ByPHP/5.5.12refresh50; url=result.php?test=Working...

Assuming that there is no problem with quiz.php and that our test systems are basically equivalent, the most likely cause of trouble is that the Set-Cookie header (which the server puts in front of the non-standard refresh header whatever order you have the actual php lines in) is corrupt and is somehow breaking the rest of the headers. 
This raises the question of what precisely is in $_SESSION['rec_id']?

Another edit:
checkKey() seems very peculiar, as it's just asking for a confusion using both local and global copies of $result. 
The better way to do it would be to pass a reference to result.
In either case, make sure you have the global version of result defined elsewhere. 

```
function checkKey(&$result)
    {
        $qkey = $_SESSION['Qkey'];
        $result = mysql_query("SELECT * FROM quest WHERE Qkey='$qkey'") or die(mysql_error());
    }
```


----------



## JiminSA (Dec 15, 2011)

Thank you Josiah - I reverted to the original code (both header sends together) and it worked fine! I can only assume that I was somehow corrupting the setCookie via $_SESSION['rec_id'] which itself was corrupt. (I cleared the db and set it up anew, which may have cured the corruption ...)
As regards the Global declaration - I am guilty of inheriting that usage from a piece of copied code in my early days of using php and had never questioned it! - My bad!:down:
Once again thanks for your input:up:
Incidentaly, for any of our members who may be wondering what securing user input (sanitizing) is all about, please check out this article which explains it quite nicely ...


----------



## JiminSA (Dec 15, 2011)

Well I now feel better about having marked this thread solved
The actual reason for the header not working was because I had a blank line after the php close line (?>) in a php file included just before the headers, so the server thought that output (the blank line) had been rendered and failed to execute the header


----------

