I have the following setup:
Some files are dynamically generated dependent on some (only a few) session parameters. Since they have not a great diversity, i allow caching in proxys/browsers. The files get an etag on their way, and the reaction of the whole web application at first glance seems correct: Files served in correct dependence from session situations, traffic saved.
And then this erroneous behavior:
But at closer inspection, i found that in his answer in case of a 304 for those dynamically generated files, apache wrongly sends a "Connection: close" Header instead of the normally sent "Connection: KeepAlive". What he should do is: Simply do not manipulate anything concerning "connection".
I cannot find any point where to pinpoint the cause of this behavior: Nowhere in the apache config files is anything written except one single line in one single file where it is instructed to send a keepalive - which it does - as long as it does not send a 304 response for a dynamically generated file. Nowhere in PHP do i instruct that guy to send anything other than keepalives (and the latter only to try to counter the connection:close).
The apache does not do this when it serves "normal" (non-dynamic) files (with 304 answers). So in some way i assume that maybe the PHP kernel is the one who interferes here without permission or being asked. But then, an added "Header set Connection 'Keep-Alive'" in the apache config, which i too added to counter the closing of the connection, does not work, too. Normally, when you put such a header set rule (not of "early" type) in the apache config, this rules takes action AFTER finalization of any subordered work on the requested document (thus AFTER finalization of the PHP output). But in my case, nothing happens - well: in case of a 304 response. In all other cases, everything works normal and correct.
Since there do some other files go over the line at a page request, i would appreciate to get the apache rid of those connection-closures.
Is there anybody who has an idea what to do with this behavior?
P.S.: One day (and a good sleep) later, things are clearing:
The culprit in this case was a shortsightedly (on my behalf) copied example snippet, which had "HTTP/1.>>>0<<< 304" (the Null!) in it.
This protocol version number gets (correctly) post-processed by apache (after everything otherwise - including any apache modules work - got finalized), in that it decides not to send a "Connection: Keep-Alive" over the wire, since that feature didn't exist in version HTTP/1.0.
The problem in this case was to get the focus on the fact that everything inside php and apache modules worked correctly and something in the outer environment of them must have been wrong, and thereafter to shift the view to anything in the code that could possibly influence that outer environment (e.g. the protocol version).
I know this has been asked tons of times here and all over the internet however solutions I found are not working and this has been driving me crazy for several months now.
I have a very simple PHP page:
<?php session_start(); ?>
I'm getting the nightmare errors headers already sent and cache limiter in my error_log. Although it doesn't affect the function of any of the scripts but it's filling the error_log so much. There is no error when running from browser.
I have tried the TextWrangler editor for Mac and choosing Unicode UTF-16 with no BOM option when saving. However, after creating the file using Textwrangler, making sure that the extension is PHP, and uploading the file to server. I tried running the file directly and I got the following in browser:
<�?php session_start(); ?>
So the file is not encoded properly. I don't know why. With regular encoding of UTF-8 from either TextEdit or TextWrangler, the header error would appear in cron job as stated before.
I write all the text myself without copying so that no BOM characters in the file. Is there any REAL solution for this error? Should I use an ANSI editor? Isn't the save as utf-16 with no bom option used to avoid this errors? Or this errors must appear if there is session in cron?
Lastly I use the following cron job in cpanel: php -q /path/to/file.php
Calling your php script from cron will invoke PHP-CLI environment, which is not the same as calling the same script from the browser.
For example there are no cookies and obviously there is no session by default.
However if you still want to enjoy the sessions , there is a way. You can try this:
<?php
session_id ("temp");
session_start();
print_r ($_SESSION);
?>
If you give us information about the final goal or the use case behind this script we can help you more!
I'have just started to learn PHP, I'm using a free host to test my code but nothing happens and also my php code passed in source of page, does it show that server don't interpret it?
Yes, that shows that the server isn't interpreting it properly. The user should never receive PHP code, just the html/javascript/whatever that your PHP script outputs.
As for why this is happening, here are a few basic things to check:
Your PHP code should begin with the <?php tag and end with the ?> tag (the ending tag isn't strictly necessary, but any code you put after it won't be interpreted).
The document's name should end with .php (not always necessary, but some server setups may require it).
If you haven't checked already, make sure that the host you're using supports PHP in the first place.
Is php code passed in source to the client?
No.
Your PHP interpreter isn't being invoked.
This block of code shown below using a php header redirect works locally, but not on my Bluehost server:
if ($_POST['submit']=='No')
{
$url ='Location: index.php?id='.$id.'&page='.$page;
header($url);
exit;
}
When the server gets to this block of code, absolutely nothing happens. No error, no warning, just a blank page. The page that my form submit redirects to isn't supposed to do anything except reroute the user to the relevant page.
I'm pretty dang positive it has nothing to do with the common problem of including HTML before the redirect (since it works locally). Therefore I suspect it has something to do with differences between my php.ini files. I've pulled up PHPinfo() for both servers, and my local server has a module named mod_headers while my Bluehost server has none. I think this potentially could be the problem, although normally my Bluehost has no problems using header redirects, except in this one instance.
So I suspect the problem has something to do with my ini file, but I don't know exactly what.
What makes this problem even stranger is that there are other blocks of code which work just fine, for instance
if(!empty($_POST['id']))
{
$id = htmlentities(strip_tags($_POST['id']));
$sql = "UPDATE entries SET title=?, entry=? WHERE id=? LIMIT 1";
$stmt = $db->prepare($sql);
$stmt->execute(array($title,$entry,$id));
$stmt->closeCursor();
$url= 'Location: ../index.php?id='.$id.'&page='.$page;
header($url);
exit;
}
works just great.
I had the same problem that it works fine on XAMPP but not on bluehost or 1&1.
PHP documentation says there should be no output before calling the header function.
http://php.net/manual/en/function.header.php
In my case there was a space before the opening <?PHP which made the header function not work.
This should help to solve the problem.
The quesiton remains though: why does it work on XAMPP and not on the servers of bluehost, 1&1, etc?
(since I use firefox for both tests - it is definitely not a browser issue)
I just had this problem. I realized that I was using an editor that was inserting a BOM at the beginning of the file. This BOM character is virtually invisible to most editors but will stop PHP's header from firing because it does count as ouput. Here is more information on the BOM character:
http://en.wikipedia.org/wiki/Byte_order_mark
I was using notepad++ and was able to disable this BOM by using these directions:
Go to Settings > Preferences > New Document/Default Directory
Changed Encoding to UTF-8 without BOM
The HTTP standard requires that the URL in the Location: directive is an absolute URL. You can't just use index.php for that redirect. You'll need to use:
header("Location: http://example.com/index.php");
Some browsers ignore the standard and allow relative URLs.
I faced the same problem when running moving my Wordpress blog to Bluehost.
The solution was to change output_buffering option in php.ini
Look what at my config along with the explanation of this option:
; Output buffering allows you to send header lines (including cookies) even
; after you send body content, at the price of slowing PHP's output layer a
; bit. You can enable output buffering during runtime by calling the output
; buffering functions. You can also enable output buffering for all files by
; setting this directive to On. If you wish to limit the size of the buffer
; to a certain size - you can use a maximum number of bytes instead of 'On', as
; a value for this directive (e.g., output_buffering=4096).
output_buffering = 4096
since a few hours our server hangs every time you do a session_start.
For testing purposes i created a script which looks like this:
<?php
session_start();
?>
Calling it from the console hangs and it can't even be stopped with ctrl-c, only kill -9 works. The same for calling it via Apache. /var/lib/php/session/ stays empty but permissions are absolutely fine, www can write and also has read permissions for all parent folders.
According to the admins there were no changes made on the server and there is no special code registered for sessions. The Server is CentOS 4 or 5 and yesterday everything was working perfectly. We rebooted the server and updated PHP, but nothing changed.
I've ran out of ideas, any suggestions?
UPDATE
We solved this problem by moving the project to another server, so while the problem still exists on one server there is no immediate need for a solution anymore.
I will keep the question open in case someone has an idea for others having a similar problem in the future, though.
There are many reasons for that, here are a few of them:
A. The session file could be opened exclusively.
When the file lock is not released properly for whatever reason, it is causing session_start() to hang infinitely on any future script executions.
Workaround: use session_set_save_handler() and make sure the write function uses fopen($file, 'w') instead of fopen($file, 'x')
B. Never use the following in your php.ini file (entropie file to "/dev/random"), this will cause your session_start() to hang:
<?php
ini_set("session.entropy_file", "/dev/random");
ini_set("session.entropy_length", "512");
?>
C.
session_start() needs a directory to write to.
You can get Apache plus PHP running in a normal user account. Apache will then of course have to listen to an other port than 80 (for instance, 8080).
Be sure to do the following things:
- create a temporary directory PREFIX/tmp
- put php.ini in PREFIX/lib
- edit php.ini and set session.save_path to the directory you just created
Otherwise, your scripts will seem to 'hang' on session_start().
If this helps:
In my scenario, session_start() was hanging at the same time I was using the XDebug debugger within PHPStorm, the IDE, on Windows. I found that there was a clear cause: Whenever I killed the debug session from within PHPStorm, the next time I tried to run a debug session, session_start() would hang.
The solution, if this is your scenario, is to make sure to restart Apache every time you kill an XDebug session within your IDE.
I had a weird issue with this myself.
I am using CentOS 5.5x64, PHP 5.2.10-1. A clean ANSI file in the root with nothing other than session_start() was hanging. The session was being written to disk and no errors were being thrown. It just hung.
I tried everything suggested by Thariama, and checked PHP compile settings etc.
My Fix:
yum reinstall php; /etc/init.d/httpd restart
Hope this helps someone.
To everyone complaining about the 30 seconds of downtime being unacceptable, this was an inexplicable issue on a brand new, clean OS install, NOT a running production machine. This solution should NOT be used in a production environment.
Ok I face the same problem on 2 PC, 1 is MAC mini XAMPP, 1 is Windows 10 Xampp.
Both is php spent infinity to run session_start(). Both PHP version is 7.x.x
I found that session files is lock to read and write. So that I added code to make PHP read session files and immediately unlock when done with
<?php
session_start([
'read_and_close' => true,
]);
?>
or
<?php
//For PHP 5.x
session_start();
session_write_close();
?>
After this PHP unlock session file => Problems solve
The problem: -
Iv experienced (and fixed) the problem where file based sessions hang the request, and database based sessions get out of sync by storing out of date session data (like storing each session save in the wrong order).
This is caused by any subsequent request that loads a session (simultaneous requests), like ajax, video embed where the video file is delivered via php script, dynamic resource file (like script or css) delivered via php script, etc.
In file based sessions file locking prevents session writing thus causing a deadlock between the simultaneous request threads.
In database based session the last request thread to complete becomes the most recent save, so for example a video delivery script will complete long after the page request and overwrite the since updated session with old session data.
The fix: -
If your ajax or resource delivery script doesnt need to use sessions then easiest to just remove session usage from it.
Otherwise you'd best make yourself a coffee and do the following: -
Write or employ a session handler (if not already doing so) as per http://www.php.net//manual/en/class.sessionhandler.php (many other examples available via google search).
In your session handler function write() prepend the code ...
// processes may declare their session as read only ...
if(!empty($_SESSION['no_session_write'])) {
unset($_SESSION['no_session_write']);
return true;
}
In your ajax or resource delivery php script add the code (after the session is started) ...
$_SESSION['no_session_write'] = true;
I realise this seems like a lot of stuffing around for what should be a tiny fix, but unfortunately if you need to have simultaneous requests each loading a session then it is required.
NOTE if your ajax or resource delivery script does actually need to write/save data, then you need to do it somewhere other than in the session, like database.
Just put session_write_close(); befor Session_start();
as below:
<?php
session_write_close();
session_start();
.....
?>
I don't know why, but changing this value in /etc/php/7.4/apache2/php.ini worked for me:
;session.save_path = "/var/lib/php/sessions"
session.save_path = "/tmp"
To throw another answer into the mix for those going bananas, I had a session_start() dying only in particular cases and scripts. The reason my session was dying was ultimately because I was storing a lot of data in them after a particularly intensive script, and ultimately the call to session_start() was exhausting the 'memory_limit' setting in php.ini.
After increasing 'memory_limit', those session_start() calls no longer killed my script.
For me, the problem seemed to originate from SeLinux. The needed command was chcon -R -t httpd_sys_content_t [www directory] to give access to the right directory.
See https://askubuntu.com/questions/451922/apache-access-denied-because-search-permissions-are-missing
If you use pgAdmin 4 this can happen as well.
If you have File > Preferences > SQL Editor > Options > "Auto Commit" disabled, and you just ran a query using the query tool but didn't manually commit, then session_start() will freeze.
Enable auto commit, or manually commit, or just close pgAdmin, and it will no longer freeze.
In my case it seems like it was the NFS Share that was locking the session , after restarting the NFS server and only enabled 1 node of web clients the sessions worked normally .
Yet another few cents that might help someone. In my case I was storing in $_SESSION complex data with several different class objects in them and session_start() couldn't handle the whole unserialization as not every class was loaded on session_start. The solution is my case was to serialize/jsonify data before saving it into the $_SESSION and reversing the process after I got the data out of session.