PHP fails to setcookie - php

I'm a PHP virgin (first day), so please type slowly.
I have a number of images, bg_001.jpg, bg_002.jpg, etc., which I want to rotate through each time the page is refreshed. I tried this:
if (isset($_COOKIE["bg1"])) {
$img_no = $_COOKIE["bg1"] + 1;
} else {
$img_no = 1;
}
$filename = 'bg_' . sprintf("%03d", $img_no) . '.jpg';
if (!file_exists("/img/" . $filename)) {
$img_no = 1;
$filename = 'bg_' . sprintf("%03d", $img_no) . '.jpg';
}
setcookie("bg1", $img_no, time() + 86400);
print '<img src="img/' . $filename . '" alt="" height="175" width="800"> ';
Instead of a cookie I get a
Warning: Cannot modify header information - headers already sent by (output
started at /home2/.../about.php:7) in /home2/.../about.php on line 31
Line 31 being the line with the setcookie. I already found pointers about PHP having trouble with Unicode's BOM, but I have no idea how to fix it (if it is the problem here in the first place).
So, to make it official (and avoid a "not a real question" label), how do I fix this? :-)
Constructive criticism on my code is welcome too.
epilogue:
Seemed like a common newbie error: several answers toward the same solution within fifteen minutes. Thanks guyz/galz.
So I moved everything except the print to the start of the file, and indeed: fixed.

cookies can only be sent, if there are no information sent prior. This means that the first thing in your PHP file has to be <?php, and nothing can get before that part (not even the dreaded UTF-8 BOM), because if something is before the first <?php (like <html>), then php will send those data for the browser and after data is sent you can't use setcookie. Refactor your code to look something like this:
<?php
(...)
setcookie(...)
(...)
?>
<HTML>
(...)
</HTML>
And double check that editors like notepad didn't put any UTF-8 BOM signatures before the first <?php in the file.

With HTTP your header (request/response info) and Content (actual textor binary content) are set separately and Header must precede the Content.
Setting a cookie actually adds a command to the header response, so any modifications to the cookie need to happen before you start outputting any content.
Move all your code that references your cookie before the opening html element on your page and you should be ok.

You might also find it easier to use sessions instead of manipulating the cookies themselves. the session_start() still needs to come before any other content but it makes it easier to store data structures, etc.
have a look at http://php.net/session_start

To get around this without major code changes, use Output Buffering like so,--
<?php
ob_start();
// ... my code here
?>
<html></html>
<?php
// ... end of the file
ob_end_flush();
?>

The error/warning you got says it all: headers are already sent
This means that output has been already sent to the browser before the setcookie() method was called.
As you can understand cookies "should be set" before any output is send to the browser.
So check line 7 at about.php. You should have html code there or you might have a call to print or echo.

Related

Why am I getting Warning: Cannot modify header information - headers already sent by (output started at ...)?

I'm reusing a search PHP script, but I get this error:
Warning: Cannot modify header information - headers already sent by
(output started at /Volumes/Work/MAMP/PC
Flag/php_scripts/conection.php:2) in /Volumes/Work/MAMP/PC
Flag/includes/search.php on line 63
line #2 conection.php:
$con = mysqli_connect("localhost", "root", "root", "cms");
line #63 search.php:
header('Location: search-page.php?keywords=' . urlencode($keywords));
What is the problem?
Also I need to mention that the script doesn't redirect me anymore to search-page.php as it should.
When you use header() it shouldn't be any output before, not even a space, you have two solution:
Dirty one
Use ob_clean() before the header to clean the output buffer
ob_clean();
header('Location: search-page.php?keywords=' . urlencode($keywords));
Correct one
Search in your script and your request route for any output, content before <?php, echoes, HTML code, prints or spaces after the ?> are usually the cause of this ;)
Debug
This snippet may help you to find out where is the output in your code:
var_dump(ob_get_contents());die()
Put this before line 63
Javascript workaround
In the case that everything fails, you have another option, use javascript to redirect, although I recommend you to keep trying without get to this point :)
Replace the header(...) with this:
echo '<script>window.location.href="search-page.php?keywords=' . urlencode($keywords)) . '";</script>';
You have send a header already as error states. Please investigate when and how headers are sent.
That usually happens when something is printed before that line to output buffer.
Make sure that you are using UTF-8 without BOM document encoding - BOM sign is invisible in most text editors yet can be interpreted as content which forces sending HTTP headers.
You can debug your output with Output Control function
It's happening because output has been sent already. You can't edit Header Information when you have echo'd anything!
It seems like the error you're getting is because an output have been occured.you can fix it with this code :
if (headers_sent()) {
ob_clean();
}
Just found this detailed answer.

Content-length header not being set correctly

I have a php script (actually https://drupal.org/project/file_force) that is forcing users who click on a link to download that link by adding the correct headers to the response.
This link works fine 90% of the time. Occasionally the incorrect content-length is being passed so users are getting apparently truncated files. The mistake happens consistently on particular files, but if those files are re-uploaded, the error may not appear on the new instance, which makes me think this is not an issue with the files, but instead a cache somewhere. So I ran clearstatcache() every time to no avail. What is odd is that php is passing the correct file size, or says it is when I pass the string it's inserting to a log file.
Here's the relevant code:
clearstatcache();
return array(
'Content-Type: ' . $mimeinfo,
'Content-Disposition: ' . $disposition . '; filename="' . basename($filepath) . '";',
// Content-Length is also a good header to send, as it allows the browser to
// display a progress bar correctly.
// There's a trick for determining the file size for files over 2 GB. Nobody
// should be using this module with files that large, but… the sprintf()
// trickery makes sure the value is correct for files larger than 2GB. See
// note at http://php.net/filesize
'Content-Length: ' . sprintf('%u', filesize($filepath)),
);
A sample output from sprintf('%u', filesize($filepath)) on a file that isn't working is 2682059 which somehow gets translated to 1740048 when the browser gets to see it.
I've tried removing the sprintf function to no avail.
I've also tried not including a Content-Length declaration at all, but someone one is getting attached with the incorrect value anyway. This last piece of evidence perhaps suggests some other code is overriding the content headers I'm setting here, yet it appears to be leaving alone any other headers that I change in the above code to test that theory.
Any thoughts for where to look?
I resolved the issue.
Turns out another module within Drupal was adding its own content-length header and getting the value from a database rather than the file directly (weird), and it was happening down stream. By reversing the order that the modules got their hands on the headers, the issue went away. I have filed a bug report against the offending module.
SOURCES: PHP official documentation - "header" function
There's a function in PHP called header that you would like to use to set headers, before the actual page loads:
Here's the skeleton of the function:
void header ( string $string [, bool $replace = true [, int $http_response_code ]] )
Explanation:
Parameters:
string
The header string.
There are two special-case header calls. The first is a header that
starts with the string "HTTP/" (case is not significant), which will
be used to figure out the HTTP status code to send. For example, if
you have configured Apache to use a PHP script to handle requests for
missing files (using the ErrorDocument directive), you may want to
make sure that your script generates the proper status code.
replace
The optional replace parameter indicates whether the header
should replace a previous similar header, or add a second header of
the same type. By default it will replace, but if you pass in FALSE as
the second argument you can force multiple headers of the same type.
http_response_code
Forces the HTTP response code to the specified value. Note that this
parameter only has an effect if the string is not empty.
===
Return Values:
No value is returned.
Example:
<?php
header('Location: http://www.example.com/'); //redirect to www.example.com
?>
Note: The function must be called before any output is sent, i.e. before any HTML tags or before any echo calls.
in your case:
<?php
header('Content-Length: ' . sprintf('%u', filesize($filepath)));
?>
the replace parameter which is by default - true, will cause your program to overwrite all previously set 'Content-Length' headers..
Hope all the explanation was worth it... :)

$_GET is not working

Creating a rating system and the info is not being transmitted through my $_GET variable. The code is below
if (isset($_GET['item'], $_GET['rating'])){
echo 'Works!';
}
The variable is being entered in this code below
<?php echo number_format(
$article['rating'],1); ?>
<div class = "rate">
Rate:
<?php
for ($x =1; $x<= $maximum_rating; $x++){
?>
<a href="prestige.php?item=<?php echo $article['id']; ?>&rating=<?php echo $x;?>">
<?php echo $x; ?></a>
<?php
}
?>
I am fairly new to programming so any ideas or tips would be greatly appreciated.
There are a couple of things you should do.
1.
Instead of
prestige.php?item=<?php echo $article['id']; ?>&rating=<?php echo $x;?>
Use
prestige.php?<?= http_build_query(array('item' => $article['id'], 'rating' => $x), '&') ?>
This will escape the parameters. Vars $article['id'] and $x could contain characters that break the HTML or URL.
2.
Look at the Net tab in your Firebug/Chrome dev toolbar. Are there any redirects? What headers are sent?
Also look at the address bar to see if prestige.php really is loaded with the GET parameters.
3.
Use a debug tool like XDebug to step through your code. You might have some code that resets the $_GET vars. Personally I use the IDE PHPed, but it's kinda expensive.
The code you posted works. So the snag must be in the code you did not post:
maybe the prestige.php page has a PHP error that prevents it from displaying anything; start with an empty file containing just <?php echo 'OK so far'; ?>.
maybe the page contains code (security checks, frameworks...) that kills $_GET. (reduce the page to a minimum working case, without include/requires)
maybe the page does work, but the output gets snarked by an untimely ob_end_clean() that was meant to "clean the page" before the real output started; (reduce the page to a minimum working case)
maybe the page works, the string 'Works' is there, but you can't see it due to HTML markup, CSS, or other rendering problems (check the page source)
the URL might be broken because the item code contains invalid URL characters (check what appears in the browser address bar)
there might be an URL rewrite scheme that interferes (check .htaccess and the server logs)
I just remembered something like this happening with international characters in the URL. Try with an ASCII-clean item code to see what happens.
Just to be sure: verify there is no auto_prepend'ed file which might interfere.
Then, it might also be more than one of the above acting together. Often when debugging one unintentionally breaks some code, and even after fixing the first bug, the code doesn't start working again - this doesn't mean the fix was invalid.
I'm sorry -- I'm at the end of my options. I really look forward to knowing what the reason was. (Usually the more explanations I amass, the more the real answer tends to be "none of the above". When it happens to me, sometimes I wonder whether to start to believe in gremlins :-( ).

avoid output buffering error in serevr

I am developing w web site. Here I have included a thumnail page. It’s working well in my localhost. But when I uploaded its show me an error see
Warning: Cannot modify header information - headers already sent by (output started at /mydomain/demo1/admin/thumbnail.php:50) in /mydomain/demo1/admin/act-addVehicle.php on line 191
my code
if(move_uploaded_file ($tmpName,$path.$actual_image_name)){
$succ=1;
chmod("$add",0777);
$imgSucc=1;
//strt image thumbnail
include("./thumbnail.php");
// ends
}else{ echo "Failed to upload file Contact Site admin to fix the problem";
exit;}
How I avoid this error
is there any settings in php ini ?
does anyone know ?
please reply
Without seeing thumbnail.php's code its hard to tell exactly what's happening, but basically its outputting something before act-addVehicle.php on line 191 is setting another header.
Most likely a single space at the end of the script. Check after ?> perhaps line 50 if just after.
You could wrap the include('thumbnail.php') into an ob_start() and ob_end_clean() but that will not solve the underlying issue of outputting before setting a new header.
This kind of error typically comes from having a closing php tag in one of your file that is followed by some white space. This white space is sent to the browser when the script is executed BEFORE it executes a "header()" function.
For example, I would not be surprised that your thumbnail.php or act-addverhicule.php ends with a "?>" tag and that there is some white space after it.
As a good practice, it is always better to remove all closing php tag (the "?>") at the end of your files to avoid these kind of problems...
of course. use ob_start funciton somewhere in the beginning of your code

Headers already sent error in CakePHP app [duplicate]

This question already has answers here:
How to fix "Headers already sent" error in PHP
(11 answers)
Closed 9 years ago.
function new_photo()
{
if( !empty($this->data))
{
$this->data['Photo']['showcase_id'] = $this->Session->read('CurrShowcase.id');
$this->data['Photo']['added'] = date("Y-m-d H:i:s");
$this->Showcase->Photo->save($this->data);
$flasher = 'Photo uploaded successfully';
$flasher .= '<br/><img src="' . $this->data['Photo']['thumbnail_url'] . '"/>';
$this->Session->setFlash($flasher);
//$this->redirect(array('action'=>'sc',));
}
}
I have a Showcase Controller in my CakePHP app, and a new photo form to submit new photos. Whenever I uncomment the last line that redirects after the data is saved, I get this error:
Warning (2): Cannot modify header information - headers already
sent by (output started at D:\.....
Even if I get this error, $this->data still gets saved properly in the database. However, if I comment the redirect line as shown above, everything works fine and error-free. I HAVE checked for blank spaces around the tags, so I'm pretty sure it's not that.
Any ideas?
Edit:
commenting out the setFlash statement does not fix the problem.
Change your debug mode to 0 to make sure it's not a notice/warning being generated prior to the redirect. Also, you might want to tighten up your processing section to (be paranoid and) ensure that it's not using invalid indexes, as well as anywhere else throughout the application flow for that action to make sure you're not getting any ouput (if it works when you change debug to 0).
Is there a debug statement somewhere that you're not showing us?
You may be up against an invisible UTF-8 BOM character somewhere. Check your text editor settings whether it saves your files with BOM or without.
I'd check for whitespace in the models. Anyone of them. That was one of the gotchas I hit.
Either this code outputs something to the browser, or you have a whitespace after ?> in the end of the file (or any other included file). The whitespace is sent to the user thus sending http header.
I'm assuming setFlash outputs something to the browser?
If whitespace before or after your <?php ?> tags isn't your issue you might have to try passing 'null' for the 'layout' parameter of setFlash();
i.e.
$this->Session->setFlash($flasher, null);

Categories