$http = new swoole_http_server("0.0.0.0", 9501);
$http->on('request', function ($request, $response) {
$headers_sent = 'false';
if (headers_sent()) {
$headers_sent = 'true';
}
ob_start();
echo 'headers sent: ';
$result = ob_get_contents();
ob_end_clean();
$response->end($result . $headers_sent);
});
$http->start();
open the browser with address http://127.0.0.1:9501
browser output:
headers sent: false
then refresh the page, the output will always is:
headers sent: true
it means headers already sent. for example session can't start:
session_start(): Cannot send session cookie - headers already sent
it seems ob_start() caused the headers_sent return true, when I remove ob_start,
headers_sent return false (that is right)
is it an issue ? what can I do for session_start with ob_start ?
swoole
swoole support => enabled
Version => 4.0.3
Author => Swoole Group[email: [email protected]]
coroutine => enabled
epoll => enabled
eventfd => enabled
timerfd => enabled
signalfd => enabled
spinlock => enabled
rwlock => enabled
async http/websocket client => enabled
pcre => enabled
zlib => enabled
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled
Directive => Local Value => Master Value
swoole.aio_thread_num => 2 => 2
swoole.display_errors => On => On
swoole.use_namespace => On => On
swoole.use_shortname => On => On
swoole.fast_serialize => Off => Off
swoole.unixsock_buffer_size => 8388608 => 8388608
You can't use headers_sent, it's not PHP-FPM.
You should use swoole_http_request and swoole_http_response
function swoole_http_response->header(string $key, string $value, bool $ucwords = true);
yes I see. but I want to use the php builtin session_start(), and with ob_start(). session_start will check the headers sent.
I can found that the swoole-framework also supported to use the builtin session_start
@xrjxs
swoole-framework is not the framework by swoole, it's just named swoole, you can't use traditional functions such as session_*, headers in swoole.
@twose I tested session_* can use in the swoole and works prefect. but not good with ob_start.
if ($_GET['seesion_cookie']) {
session_id($_GET['session_cookie']);
session_start();
// also can do this below if session_id not working
//$fileName = session_save_path() . "/sess_$sessionId";
//$content = file_get_contents($fileName);
//session_decode($content);
} else {
if (session_status() != PHP_SESSION_ACTIVE) {
session_start();
session_regenerate_id();
swoole_http_response->cookie( ... add session cookie here );
}
}
@xrjxs
Yes you can do these but session_* use PHP file functions, it's synchronous blocking, and when it operates session file, all the server would be blocked.
you can use swoft-session, and you can only use ob_* with swoole ver >= 4.0.2, we just solve the global output controller problem.
@twose, @xrjxs,
The library upscalesoftware/swoole-session implements compatibility of PHP sessions with Swoole.
@sshymko
You make some mistakes, session_* functions is blocked (expect you use Swoole\Runtime::enableCoroutine), and you use global var $SESSION but you have not separated it by coroutine's uid (context processing), this will cause disaster when high concurrency, when a coroutine yield and switch to the other coroutine, the other coroutine will change the global vars, when the previous one resume, it will get the wrong global values.
@twose,
Thanks for the code review and the explanation!
I need to test this, but I think session_start() blocks execution until session_end_write() is called. All the code between session_start() and session_end_write() is synchronous regardless of whether it uses co-routines or not. If I'm wrong then disabling co-routines is a requirement.
@sshymko swoft-cloud/swoft-session Reference for you, or maybe you could just use it.
@huangzhhui,
Yes, upscalesoftware/swoole-session references the Swoft sessions in the README docs ;)