Problem with sending "SetCookie" first in php code - php

According to this manual: http://us2.php.net/setcookie I have to set the cookie before anything else.
Here is my cookie code:
if (isset($_COOKIE['watched_ads'])){
$expir = time()+1728000; //20 days
$ad_arr = unserialize($_COOKIE['watched_ads']);
$arr_elem = count($ad_arr);
if (in_array($ad_id, $ad_arr) == FALSE){
if ($arr_elem>10){
array_shift($ad_arr);
}
$ad_arr[]=$ad_id;
setcookie('watched_ads', serialize($ad_arr), $expir, '/');
}
}
else {
$expir = time()+1728000; //20 days
$ad_arr[] = $ad_id;
setcookie('watched_ads', serialize($ad_arr), $expir, '/');
}
As you can see I am using variables in setting the cookie.
The variables comes from a mysql_query and I have to do the query first.
But then, if I do, I will get an error message:
Cannot modify header information - headers already sent by ...
The error points to the line where I set the cookie above.
What should I do?
UPDATE:
I do this before the setCookie part:
$ad_id=$_GET['ad_id'];
$query2 = "SELECT * FROM classified WHERE classified.ad_id = '$ad_id'";
$results2 = mysql_query($query2) or die(mysql_error());
$row2 = mysql_fetch_array($results2);
$cat = $row2['category'];
$action=$row2['action'];
$sql_table='';
$num_rows = mysql_num_rows($query_results);
if ($num_rows != 0){
HERE COMES THE SETCOOKIE PART

As others have suggested, make sure, you are not outputting any html or whitespace before you set your cookie.
This will fail because you are printing html before you set your cookie.
<p>
<?php
// your cookie code - note <p> tag before <?php tag
// ...
?>
This will also fail, because you are printing whitespace before you set your cookie.
 
<?php
// your cookie code - note the extra linebreak before <?php tag
// ...
?>
Also
<?php
// your cookie code - note the extra space before <?php tag
// ...
?>
If you use an UTF encoding for your php script (and if you are not in one of the english speaking countries, chances are that you do), make sure your editor is set that it does not include byte order mark (BOM) at the begining of every file. See http://en.wikipedia.org/wiki/Byte_order_mark for more detail on BOM.

The restriction is not that you must not do anything before setting your cookies, merely that you must no output anything before setting your cookies.
For example, let's say we want to get some data from the database, output it to the user and set it to the cookie.
<?php
$data = getDbData();
echo $data['field'];
setcookie('field', $data['field'], time()+86400, '/');
This will fail because we've output the data before setting the cookie. We can fix it by moving the output to after we set the cookie.
<?php
$data = getDbData();
setcookie('field', $data['field'], time()+86400, '/');
echo $data['field'];

Make sure that you do not print anything prior to adding header-based information (as cookies are).

I can't see any problems with the code, unless mysql outputs an error, which could cause this.
This is a shot in the dark, but make sure you don't have any whitespace (or anything else for that matter) before the opening php tags. Also make sure you don't have any trailing whitespaces after the closing php tags in the files you include.

The error message you showed us says that the headers were sent on the setcookie() line. Thus, you may be setting headers or cookies later in the code, which is causing the error. (Or so I believe, since I can't recall the error word for word and you cut it off at the critical point)

Related

php cookies error - http setcookie over request only [duplicate]

Thought this was super easy, but I've spent the last half hour trying to figure it out to no avail.
$unique_id = uniqid(microtime(),1);
if (is_null($_COOKIE['client_id']))
{
setcookie("client_id", $unique_id);
}
But when I go to check the cookie through $_COOKIE['client_id'], I get a null value. Any ideas whats going on?
Cookies have to be set before ANYTHING is outputted. also I've had many problems with cookies before.
Also, see Can't set cookies in PHP? for explanation why you cant check its existence at the same time as setting it.
The _COOKIE array is created when the script initializes, and is then left alone by PHP. Setting a cookie within the script will not magically add it to $_COOKIE. It will only show up on the next script request, or you manually assign it into $_COOKIE.
You should set cookie with
$_COOKIE['key'] = 'value';
Yeah FallingBullets has right. Be affraid when you use UTF8 file encoding - the first chars with is sent to client is UTF8 file head ( 0xEF 0xBB 0xBF). In this case is ob-start http://php.net/manual/en/function.ob-start.php not work (UTF8 file head is sent before ob-start).
What I describe is probably characteristic of the web server. Try save jour script in ascii encoding.

Header Location in php

<?php
require ('db_connect.php');
$Name = $_POST["name"]; $Email = $_POST["email"]; $Message = $_POST["message"];
if( isset($_POST["submit2"]) ) {
$insertString2 = "INSERT INTO Messages(Name,Email,Message)
VALUES('$Name','$Email','$Message')";
mysql_query($insertString2);
header("Location:register.php?msg=Successfully Send Message! You will get reply soon...");
}
?>
This is my code. The MySQL part is working. But this does not redirect to register.php. Why?
You may put a header call in an if-conditional preceded by other code, as long as you follow what the Manual recommends:
You can use output buffering ... by calling ob_start() and ob_end_flush() in your
script, or setting the output_buffering configuration directive on in your php.ini
or server configuration files.
If you wish to alter your PHP.INI file, you may turn output buffering on, as follows:
output_buffering = On
With output buffering turned on, this code structure should work:
Try this for your header call:
// setting variables here, then:
if (condition) {
// other code here, then:
$location = "http://yourdomain.whatever/register.php";
$encoded = urlencode("Successfully Send Message! You will get reply soon...");
header("Location: $location?msg=$encoded");
exit;
}
Note: when you use header() if you have any concern with maintaining backwards compatibility with http1.0, then you should provide a full url, including the protocol whether that is 'http', 'https' or something else. Also your query string contains characters that need to be urlencoded. After passing the value to be encoded to urlencode(), the string looks like this:
Successfully+Send+Message%21+You+will+get+reply+soon...
Part of the joy of using PHP is that it does nice things like automatically decoding the encoded url. So all you need do to display a message to the user is write something similar to the following code at register.php:
<?php echo htmlentities($_GET['msg']);
if you wish to decode the $_GET variable with JavaScript, just be aware that PHP and JavaScript do not urlencode spaces the same way, so you need to manually decode the $_GET variable's value yourself rather than fully relying on JavaScript's decodeURIComponent(). The following JavaScript will urldecode the value of "msg", including converting any '+' characters into spaces:
var str=location.search.substring(5);
str = decodeURIComponent( str );
str=str.replace(/\+/g, ' ');
alert(str); //Successfully Send Message! You will get reply soon...
"It is important that header() must
be called before any actual output is sent"--you may miss this point.

Jquery POST and AJAX prepend double space to returned data

I am still struggling with this problem after about 2 weeks with no sign of a solution.
Any data that is returned by PHP using $.ajax or $.post always has two spaces added onto the returned data. I have trimmed the data being echoed in PHP to confirm it's not an issue with the server or my scripts.
e.g.
echo '{"id": "'.$myId.'"}';
Becomes:
' {"id": "'.$myId.'"}'
When viewing the returned data in inspector. This causes problems for my js scripts because they expect nothing returned when there is no error. Double space is returned which causes errors when there are actually none, which in turn stops other events from firing.
I am using Jquery 1.8.3.
Does anyone have any idea what is causing this extremely strange and annoying issue?
I am using NetBeans
I recall that this only started happening since I moved my app to a new server, but I don't see how that would have effected it in this way.
This may be helpful,
I think there is a whitespace in your script (may be from included files, but not sure). You can overcome this by clearing the output buffer, before you send the data to browser. The following code will demonstrate the idea.
<?php
ob_start();
echo ' '; // Possible whitespace (may be from included files)
----------
----------
if (YOUR_CHECK_FOR_AJAX_REQUEST) {
ob_end_clean();
$myId = 1;
echo '{"id": "'.$myId.'"}';
exit;
}
?>
There is chance that you've got whitespaces at the end of your included php files (to prevent it, skip ending ?> tag).
Also you should check if there is nothing in front of <?php and disable BOM in your UTF-8 files.
The data which is returned from the file would have spaces or you would have html tags. Remove all the tags, lines, spaces and at the end remove ?>
If you are returning data from test.php the file should look like as below
<?php
$myId = '1';
echo '{"id": "'.$myId.'"}';

Cookies with extensions

I've seen cookies set by web pages with the "." character in them. I'm trying to maximize the dynamic use of a $_GET['url'] to set my cookies, and then include it in a next page as a conditional where it checks to make sure the cookie was set before it allows users to perform an action. Basically I'm using cookies and IP addresses in an anonymous voting action to make sure anyone who votes only gets one per day. IPs are reset through a cron job once a day, and the cookies are set to expire after 17 hours. I have no issues setting a cookie named with the .php extension, however after many hours of trial and error, I can't get it to accept it in an if(isset). No matter what I try, it will not recognize that the cookie is set. Without the extension everything works fine. I've tried a dozen configurations, but here's basically what I have trying to debug.
<?php
$cookie = "test.php";
setcookie("$cookie", "workdamnyou");
if (isset($_COOKIE[$cookie])) {
echo "is set";
}
else {
echo "not set";
}
?>
I've tried isset($_COOKIE["$cookie"]) and isset($COOKIE['$cookie']) as well. That said, I really wish you could run PHP without uploading it each time to your server.. --
setcookie doesn't change $_COOKIE immediately. It sets the headers to change the cookie in the browser, so the script won't see the test value until you refresh the page.
You CAN run PHP without uploading to a server; the easiest option is to install a xAMP stack (LAMP/MAMP/WAMP depending on if you're developing on Linux/Mac/Windows).
Well, I found the solution I guess... PHP doesn't like dots in variable names (http://www.php.net/manual/en/language.variables.basics.php). Now, since Register Globals could be on, it might be possible that a $_COOKIE["name.ext"] could turn into a $name.ext which would be invalid. Thus, "Dots and spaces in variable names are converted to underscores. For example becomes $_REQUEST["a_b"]." (http://www.php.net/manual/en/language.variables.external.php). Does a check for isset("name_php") work?
You cannot set and access a cookie in the same instance! You have to do a redirect, refresh or something, but you cannot both set and access at the same time. Also make sure your other parameters are set like hostname, expiry time. . e.t.c
Eg.
setcookie("TestCookie", $value, time()+3600, "/", "/", 1);
For debugging, just do a var_dump($_COOKIE)
Note that cookies only become available on the next pageload (when they have traversed from server to client and back).
Try setting the cookie directly with $_COOKIES["test.php"] = "test"; and see what happens with
var_dump($_COOKIE);
Also don't use the quotes around the $cookie variable. Thus make it
setcookie($cookie, "work");
instead of
setcookie("$cookie", "work");
Last, you can run PHP locally with your own server. The easiest way on Windows is the WAMPP stack. I find this one very easy to install and run: http://www.apachefriends.org/en/xampp.html
Good luck!
Why would you have a .php extension in the cookie name? It should be:
$cookie = 'test';
See http://www.ietf.org/rfc/rfc2109.txt point 4.1:
The two state management headers, Set-Cookie and Cookie, have common
syntactic properties involving attribute-value pairs. The
following grammar uses the notation, and tokens DIGIT (decimal
digits) and token (informally, a sequence of non-special, non-white
space characters) from the HTTP/1.1 specification [RFC 2068] to
describe their syntax.
av-pairs = av-pair *(";" av-pair)
av-pair = attr ["=" value] ; optional value
attr = token
value = word
word = token | quoted-string
Attributes (names) (attr) are case-insensitive. White space is
permitted between tokens. Note that while the above syntax
description shows value as optional, most attrs require them.
NOTE: The syntax above allows whitespace between the attribute and
the = sign.

PHP Header redirect not working [duplicate]

This question already has answers here:
How to fix "Headers already sent" error in PHP
(11 answers)
Closed 8 years ago.
include('header.php');
$name = $_POST['name'];
$score = $_POST['score'];
$dept = $_POST['dept'];
$MyDB->prep("INSERT INTO demo (`id`,`name`,`score`,`dept`, `date`) VALUES ('','$name','$score','$dept','$date')");
// Bind a value to our :id hook
// Produces: SELECT * FROM demo_table WHERE id = '23'
$MyDB->bind(':date', $date);
// Run the query
$MyDB->run();
header('Location:index.php');
exit;
The above code keeps giving me an issue with the redirect. The error is the following:
Warning: Cannot modify header information - headers already sent by (output
started at /Applications/MAMP/htdocs/testygubbins/OO/test/header.php:15) in
/Applications/MAMP/htdocs/testygubbins/OO/test/form.php on line 16.
I am totally flummoxed by this. Does anyone know what I should be doing to make it work?
EDIT
header.php code:
<?php
include('class.user.php');
include('class.Connection.php');
$date = date('Y-m-j');
?>
<html>
<head>
<link rel=StyleSheet href="css/style.css" type="text/css" media=screen>
<title>Test</title>
</head>
<body>
<div id="page">
Look carefully at your includes - perhaps you have a blank line after a closing ?> ?
This will cause some literal whitespace to be sent as output, preventing you from making subsequent header calls.
Note that it is legal to leave the close ?> off the include file, which is a useful idiom for avoiding this problem.
(EDIT: looking at your header, you need to avoid doing any HTML output if you want to output headers, or use output buffering to capture it).
Finally, as the PHP manual page for header points out, you should really use full URLs to redirect:
Note: HTTP/1.1 requires an absolute
URI as argument to Location:
including the scheme, hostname and
absolute path, but some clients accept
relative URIs. You can usually use
$_SERVER['HTTP_HOST'],
$_SERVER['PHP_SELF'] and dirname() to
make an absolute URI from a relative
one yourself:
COMMON PROBLEMS:
1) There should be NO output (i.e. echo... or HTML parts) before the header(...); command.
2) After header(...); you must use exit();
3) Remove any white-space(or newline) before <?php and after ?> tags.
4) Check that php file (and also other .php files, that are included) -
they should have UTF8 without BOM encoding (and not just UTF-8). Because default UTF8 adds invisible character in the start of file (called "BOM"), so you should avoid that !!!!!!!!!!!
5) Use 301 or 302 reference:
header("location: http://example.com", true, 301 ); exit;
6) Turn on error reporting. And tell the error.
7) If none of above helps, use JAVASCRIPT redirection (however, discouraged method), may be the last chance in custom cases...:
echo "<script type='text/javascript'>window.top.location='http://website.com/';</script>"; exit;
Alternatively, not to think about a newline or space somewhere in the file, you can buffer the output. Basically, you call ob_start() at the very beginning of the file and ob_end_flush() at the end. You can find more details at php.net ob-start function description.
Edit:
If you use buffering, you can output HTML before and after header() function - buffering will then ignore the output and return only the redirection header.
Try This :
**ob_start();**
include('header.php');
$name = $_POST['name'];
$score = $_POST['score'];
$dept = $_POST['dept'];
$MyDB->prep("INSERT INTO demo (`id`,`name`,`score`,`dept`, `date`) VALUES ('','$name','$score','$dept','$date')");
// Bind a value to our :id hook
// Produces: SELECT * FROM demo_table WHERE id = '23'
$MyDB->bind(':date', $date);
// Run the query
$MyDB->run();
header('Location:index.php');
**ob_end_flush();**
exit;
Look at /Applications/MAMP/htdocs/testygubbins/OO/test/header.php line 15.
At that position, it makes some output. Fix it. :)
If I understand correctly, something has already sent out from header.php (maybe some HTML) so the headers have been set. You may need to recheck your header.php file for any part that may output HTML or spaces before your first
EDIT: I am now sure that it is caused from header.php since you have those HTML output. You can fix this by remove the "include('header.php');" line and copy the following code to your file instead.
include('class.user.php');
include('class.Connection.php');
$date = date('Y-m-j');
You may have some "plain text" somewhere in php files that is interpreted as script output. It may be even a newline before or after the php script tag specifier (less-than + question mark + "php").
Besides, if I remember correctly, according to http specification, the "Location" header accepts only full URLs, not relative locations. Have that in mind too.
Don't include header.php. You should not output HTML when you are going to redirect.
Make a new file, eg. "pre.php". Put this in it:
<?php
include('class.user.php');
include('class.Connection.php');
?>
Then in header.php, include that, in stead of including the two other files.
In form.php, include pre.php in stead of header.php.
Your include produces output, thereby making it impossible to send a http header later. Two option:
Move the output somewhere after the include.
Use output buffering, i.e. at the very start of your script, put ob_start(), and at the end, put ob_flush(). This enables PHP to first wait for all the output to be gathered, determine in what order to render it, and outputs it.
I would recommend you learn the second option, as it makes you far more flexible.
also try include_once() instead of include() that can also work
Also see your php file text encoding. Mine was UTF-8 with BOM and it prevented the script to work. But now works flawlessly after removing the BOM...
Try redirection with JavaScript:
<script type="text/javascript">
window.location.href='index.php';
</script>

Categories