How to diagnose error : Unable to add cookies, header already sent - php

Error : Unable to add cookies, header already sent.
I would like to know if there is any way I can diagnose above error efficiently.
I understand the cause of this error - when cookies are being sent after something else has been sent to the browser such as headers, html etc.
There are hundreds of files with thousands of lines of codes. If anyone knows a method (even if 3rd party, it doesn't matter) that will help me to find which contents are sent to the browser before cookies so I can manipulate that part of code easily. I'm having trouble locating actual place or code patch causing this error.
Generally this happens to many vBulletin users out there and vB staff tells you to disable mods/plugins etc. But i would like to know any efficient way to find problem location. There is no problem with <?php etc. etc.

Refer to header_sent() function at point of cookie setting. php function header_sent() can help you.
bool headers_sent ([ string &$file [, int &$line ]] )
If the optional file and line parameters are set, headers_sent() will put the PHP source file name and line number where output started in the file and line variables.

Related

How can i import a file with php and keep its indentations?

so I am currently writing a script in php. Therefore i need to import a file into the script. The file contains many indentations which are very important.
When i import it as a string or as an array the indentations are lost.
What can I do or how should I import the file ?
greetings
edit:
$file_content = file_get_contents( 'D:/XAMPP/htdocs/158400.log' );
Inside this log file are various unnecessary warnings and erros and only a few i need. The plan is to extract the errors i need and send them via email to myself. The whole email script is already done, i only need the content for the email body.
The error log looks like this: (example)
ERROR: in process 345 (C::/example/ex/..) in thread 454 at 12.5.2022 8:20:03
important error log
important error log
important error log
unnecessary next logs
....
So my Idea is to detect the key words (such as ERROR) and send all the lines with the email that are in indented under the ERROR word.
There begins the problem. When i input the file with file get contents all indentations get lost, wheather its a string or an array.
So what can i do about that ?
I hope this time my question is better formulated, sorry guys :)

Find the root cause of already sent headers in php when entire class is referenced

fellow members and visitors.
Please imbue me of your knowledge and allow me to be enlightened by your expertise by answering this question or providing me a path of exploration.
My simple mind cannot has exhausted the possibilities it was aware and would really like to begin to understand what to do in such a situation should it arise again.
Everything begins with a :
Warning: session_start(): Cannot send session cache limiter - headers
already sent (output started at
/path/to/site/wp-content/themes/theme_name/inc/general/class-Upbootwp_Walker_Nav_Menu.php:125)
in
/path/to/site/wp-content/plugins/wp-php-console/includes/class-wp-php-console.php
on line 142
Here is the exact ubootwp_Walker_Nav_menu.php class for reference.
I am used to having a precise line number in these kind of error but this time, I get no such indicator (I just get the last line, but there's nothing there except the end of the class.
From my understanding, something in that class instantiate a session and when the Worpdress php console plugin try to do it, it crashes as headers were already sent by that class.
I did add the following
error_reporting(E_ALL);
ini_set('display_errors', 'On');
to get the error statement, as I would previously only get a 'error 500'.
I cannot see anything wrong with that class (no obvious echo, print, ob_start).
Does some of you have any clue on how I would go in trying to find the root cause of it ?
Any insight will be appreciated.
edit:
ubootwp_Walker_Nav_menu.php is a UTF-8 file (No BOM)
No hidden characters or anything before php opening tag.
No php closing tag at the end of the file
No echo,ob_start,print or anything obvious that I can see that would initiate a session.
Thoughts:
The error message explicitly states that the error occurs in the php console plugin (which effectively wants to start a session) because the ubootwp_Walker_Nav_menu.php has created the session. Is it possible that the error message is not accurate or does that unequivocaly means that this class is the error ?
Edit 2:
Actually, I thought it was not relevant but I had another notice before the header sent which was:
Strict Standards: Declaration of Upbootwp_Walker_Nav_Menu::start_lvl() should be compatible with Walker_Nav_Menu::start_lvl(&$output, $depth = 0, $args = Array) in /home3/i8h1o2r7/public_html/dev/wp-content/themes/axial/inc/general/class-Upbootwp_Walker_Nav_Menu.php on line 130
This was very relevant to the problem as this was the cause of the "header sent". I fixed the declaration from the class which was not causing an issue before and it fixed the PHP console plugin "session already created" issue from the initial message.
The session has to start before ANY html has been sent to the browser. You can turn on output buffering but, it's going to cause problems if run on a server without output buffering enabled ... Doesn't WP start a session anyway?
I found the solution to this problem from Magnus comment reference to another similar question. In my particular case, the header were sent by another notice that was caused by a signature mismatch and outputting headers early.
Strict Standards: Declaration of Upbootwp_Walker_Nav_Menu::start_lvl()
should be compatible with Walker_Nav_Menu::start_lvl(&$output, $depth
= 0, $args = Array) in /home3/i8h1o2r7/public_html/dev/wp-content/themes/axial/inc/general/class-Upbootwp_Walker_Nav_Menu.php
on line 130
Once that specific error was fixed, headers were not outputted anymore and the second error (initial question) vanished completely.

How does get_headers work in the background

I tryied searching for this and I belive I alredy know the answer but it's crusal that I'm not wrong, so here I go..
When calling get_headers, will I retrieve the whole file even though the function only returns the headers or will it retrieve, as expected, only the headers and nothing else?
I'm guessing the last but if I'm wrong this will cause some serious problems..
Also I noticed that there is a global setting I can change to send a HEAD request instead of the default GET request, witch is why I'm asking my self whats really going on.
Edit
Maybe this function is a better alternative? stream_get_meta_data or do they actually do the same thing?
You could also take a look at the source code, if you are familiar with C.
The function is defined here. I quickly looked over this, and it seems it is a header-only request, see line 715:
STREAM_ONLY_GET_HEADERS
GET
Requests a representation of the specified resource. Requests using
GET should only retrieve data and should have no other effect. (This
is also true of some other HTTP methods.) The W3C has published
guidance principles on this distinction, saying, "Web application
design should be informed by the above principles, but also by the
relevant limitations."
HEAD
Asks for the response identical to the one that would correspond to a
GET request, but without the response body. This is useful for
retrieving meta-information written in response headers, without
having to transport the entire content.
Wikipedia/Hypertext_Transfer_Protocol
The PHP-docs clearly states that normal get_headers() uses a GET-request, but you can force it to use HEAD instead, like this:
<?php
// By default get_headers uses a GET request to fetch the headers. If you
// want to send a HEAD request instead, you can do so using a stream context:
stream_context_set_default(
array(
'http' => array(
'method' => 'HEAD'
)
)
);
$headers = get_headers('http://example.com');
?>
Unfortunaley you're right, just read the PHP manual:
get_headers() returns an array with the headers sent by the server in response to a HTTP request.
Also take a look at the examples.
Okay, next time I should spend more attention to the question formulation.
Yeh, if the request type is set to GET (standard) you will get the whole content. You could change it to HEAD, but this is not what you want.

The user receives a truncated message (max 19109 chars) from a PHP script when calling to mysqli_real_connect

I have a problem with 1 of our PHP scripts, it sometime returns truncated message.
The flow:
User call to search.php
The script process the request:
a Connect to the DB
b Build XML using the SimpleXML class
c typeCast the SimpleXML to a string.
d print that string to the client.
The user receive (output to the browser) only part of the message in some cases
after examining this issue, those are the facts I've found:
The maximum length is 19109 chars -> more then that, it getting truncated.
I logged the 2.c typeCast XML string and found out that the log contains the full XML (not truncated!).
other scripts that return shorter/longer response are working fine.
The problem is related somehow to the DB connection:
In order to check if the problem is related to SimpleXML or something with the XML-String, I've printed (output to the browser) a diffrent-hardcoded-XML on #2.d -> it got truncated as well.
Then I tried finding what can cause it (while the diffrent-hardcoded-XML is still there), so I debugged the script using "die;". Then Iv'e found out that only if mysqli_real_connect or mysql_real_connect are called, the return value it truncated.
Any idea on how to solve/debug this issue?
Maybe message #2 give you an answer? In short, PHP manual refuses that such a function barely exists in PHP.
If this is the case, you might see that truncated output because you have implicit flush enabled, so the response is flushed to the browser immidiately during script execution. Than, at some moment script calls mysql_real_connect, which does not exists. This cause script to stop execution, so you see partially formed output. If you have display_errors disabled - you will not see the error message.
So, try enabling error output in your PHP installation (diplay_errors config directive). Another good way to resolve this is checking, if mysql_real_connect really exists with function_exists

Ajax issues, Invalid JSON

I'am building simple Ajax application (via jquery). I have strange issue. I found where the problem is, but I don't know how to solve it.
This is simple server-side php code:
<?php
require('some.php');
$return['pageContent'] = 'test';
echo(json_encode($return));
?>
On the client side, the error "Invalid JSON" is thrown.
I have discovered that if I delete require function, everything work fine.
Just for information, the "some.php" is an empty php file. There is no error when I open direct php files.
So, conclusion: I cant use require or include function if I want to use ajax?
Use Firebug to see what you're actually getting back during the AJAX call. My guess is that there's a PHP error somewhere, so you're getting more than just JSON back from the call (Firebug will show you that). As for your conclusion: using include/require by itself has absolutely no effect on the AJAX call (assuming there are no errors).
Try changing:
<?php
require('some.php');
$return['pageContent'] = 'test';
echo(json_encode($return));
?>
To:
<?php
$return = array(
'pageContent' => 'test'
);
echo json_encode($return);
?>
The problem might have to do with $return not being declared as an array prior to use.
Edit: Alright, so that might not be the problem at all. But! What might be happening is you might be echoing out something in the response. For example, if you have an error echoing out prior to the JSON, you'd be unable to parse it on the client.
if the "some.php" is an empty php file, why do you require it at all?!
require function throws a fatal error if it could't require the file. try using include function instead and see what happens, if it works then you probably have a problem with require 'some.php';
A require call won't have any effect. You need to check your returned output in Firebug. If using Chrome there is a plugin called Simple REST Client. https://chrome.google.com/extensions/detail/fhjcajmcbmldlhcimfajhfbgofnpcjmb through which you can quickly query for stuff.
Also, it's always good to send back proper HTTP headers with your response showing the response type.
It's most likely the BOM as has been discussed above. I had the same problem multiple times and used Fiddler to check the file in hex and noticed an extra 3 bytes that didn't exist in a prior backup and in new files I created. Somehow my original files were getting modified by Textpad (both in Windows). Although when I created them in Notepad++ I was fine.
So make sure that you have your encoding and codepages set up properly when you create, edit, and save your files in addition to keeping that consistent across OSes if you're developing on windows let's say and publishing to a linux environment at your hosting provider.

Categories