百科狗-知识改变命运!
--

session_write_close() - 写入会话数据并结束会话 - php 会话函数session

是丫丫呀1年前 (2023-11-21)阅读数 14#技术干货
文章标签数据

session_write_close()

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

session_write_close() - 写入会话数据并结束会话 - php 会话函数session

写入会话数据并结束会话

说明

session_write_close(void): bool

结束当前会话并存储会话数据。会话数据通常在脚本终止后存储,而无需调用session_write_close(),但是由于会话数据被锁定以防止并发写入,因此任何时候任何会话都只能对一个脚本进行操作。将框架集与会话一起使用时,由于此锁定,您将体验到框架逐一加载的情况。完成对会话变量的所有更改后,您可以通过结束会话来减少加载所有帧所需的时间。

返回值

成功时返回TRUE,或者在失败时返回FALSE

更新日志

版本说明
7.2.0该函数的返回类型现在为bool。以前,它是 void。

参见

  • Thesession_register_shutdown()关闭会话
You can have interesting fun debugging anything with sleep() in it if you have a session still active. For example, a page that makes an ajax request, where the ajax request polls a server-side event (and may not return immediately).
If the ajax function doesn't do session_write_close(), then your outer page will appear to hang, and opening other pages in new tabs will also stall.
An easy gotcha here - the $_SESSIONS superglobal does not vanish because you call session_write_close. If subsequent to the write_close call if you manipulate the superglobal the changes will not be saved when the script exists. Likewise a call to session_regenrate_id will fail.
Closing the session and then manipulating session variables is not something many would do by intent. However, if your sessions suddenly start misbehaving, failing to record changes etc it is well worth checking that the cause is not this one!
If You apply session_write_close() to allow concurrent requests from a client (for example simultaneous AJAX calls) this may not resolve the problem, if You have enabled output buffering (default in PHP 7+). You have to set output_buffering = Off in php.ini, otherwise session won't be closed immediately.
Why this function is highly important? I explain.
In a nutshell, how session works:
Client side: php is sending back to the client, a cookie with the id of the session. So, the session ends when the server ends to process the script and not when session_write_close() is executed. So, using session_write_close() for fast saving the session in the client side is useless unless you are ob_flush() and flush() to the customer.
Server side: It could be changed but the normal behavior is to save the session information in a file. For example:
sess_b2dbfc9ddd789d66da84bf57a62e2000 file
**This file is usually locked**, so if two sessions are trying open at the same time, then one is freezed until the file is unlocked. session_write_close() ends the lock.
For example:

If we run this code in two processes (using the same session, such as two tabs), then one will return 3 seconds while the other will return 6 seconds.
Its caused because the first process lock the session file.
However, changing to:

both files runs at 3 seconds.
For PHP 7.0 and higher, we could use session_start(true); for auto close after the first read.
This operation is highly important for AJAX when we used to do many operations in parallel by using the the same session
i have been using a mysql database custom session handler (not using cookies) and was having problems getting the session data to be saved consistantly on my database driven website
clients also have to navigate across domains for website management at times so i have some special code to make all this happen relatively seamlessly and to ensure that each person's data is secure.
i added session_write_close() at the very end of the last script that set session data and solved the problem.
i am not sure why, but it seems the calls to write and close were not always being made (i was not smart enough to figure it out)
now that the session_write_close() call is being made, my problems seemed to have disappeared - hopefully for good.
hope this helps someone.
Workaround if session_write_close() still doesn't write sessions fast enough:
I found with one PHP login system that even session_write_close() was not setting the session variables before I transferred pages with a Location: header. So the user would log in, I would create the $_SESSION variables, call session_write_close() and then transfer to the secure page using header(Location:...). The secure page would check for the session vars, not find them, and force the user to log in again. After the second login the session would be found and they could continue.
My workaround was to create the $_SESSION variables with 0 values before writing the initial login page. Then I updated the session vars with the login results and used the header() function to switch to the secure location. Once the session vars have already been created, updated values are assigned quickly. Problem solved. Just be sure the secure page checks both that the $_SESSION var exists AND that it's not 0.
You can easily make a cool chatbox without using frames and subdomains in combination with SSE (server side events), using for example a 'while(true){sleep($x)}' loop..
Using session_write_close() prevents the session being locked (because the request 'never' ends (maybe after a minute or two.. but otherwise the page would hang).
So you can make a chatbox without shell access on shared hosting, you just need to make a 'output all clients the new messages' function for the SSE stream and code a few lines of javascript. Read up on SSE.
Obviously need a good caching or fast database with a lot of clients, because everyone will spawn a new stream connection. (in contrast to push mechanisms which will require at least a cron job on shared hosting).
Cheap chatbox.
If you're saving data to a session but finding it's not actually being saved, check and ensure that you're not assigning any arrays with a key containing the pipe character (|). This will prevent the session data from being serialized and saved.
Beware, if you overwrite the default PHP Session handling and use debugging code inside the write() function, the debugging code is not executed until you run session_write_close().
I tried everything, file logging directly from the write() function, global debugging variable increments, static class properties. The only things written were the session open() and read() calls. My debugging code looks like this:

where getDebugInfo simply returns self::$debug_Info. Without session_write_close() the sessions.log would only contain the open() and read() calls.
Maybe intuitive to many, it took days to realize. hope it helps!
As we all know, if an object is serialised, then the class definition must be included _before_ it is unserialised.
My framework has an enormous number of class files, and including them all at the beginning of the script was really taking it's toll on my system (memory and execution time) so I switched to including required classes at the top of each class file that used them using require_once.
This caused problems because I start my session at the very beginning of my script's execution, but all my class files aren't there at the beginning!!
So no in my special 'require' function, I do the following:
if(!class_exists($to_require))
{
  session_write_close();
  require_once('path/to/classes/'.$to_require.'.php');
  session_start();
}
This is a considerably smaller performance hit that including every class that the application uses at the very beginning of the application.
Further to the comment by nakanishi at mailstyle dot com, it appears that calling session_write_close() followed by session_start() causes issues if you have more than one browser window/tab open in the session, and have a large session data array. I have an intermitent (and hard to replicate reliably) issue with session_start() never being called or not returning - the script hangs before the session headers are written. I'm puting this down to trying to be too clever rather than to a bug per se.
I had a problem with realizing the restore password form. First a user entered his login or e-mail in the system.
Then the script searched the database, got the session data, and sended link with SID to registered e-mail. The link was configured so, that it restored session data and logged user in the secure interface to the change password form.
Then was displayed a page with the message about sended message.
The problem was that ID was not unique in three pages, the SID sended to e-mail anyone could see in cookie.
I tryed to start new session before generating and after sending link with the code:

The trouble was that SID was the same even after session_unlink() and session_write_close(). The session_start() function just restored the previous session data!!! So the script was not safe. 
Then I added session_regenerate_id() call after each session_start().

 And now it works as needed! The SID sending to user we cannot see in cookies nor before neither after generated link, but the data is saved in session with this id. So only the owner of account can get it!
Beware of session_write_close when calling PHP scripts from an Ajax page: this does not "finalize" the session data writing, but in fact it resets it!
My sessions were screwing up because I had 2 different session IDs going at once:
- 1 PHPSESSID cookie for domain.com
- 1 PHPSESSID cookie for www.domain.com
This fixed it:
//At the beginning of each page...
session_set_cookie_params (1800,"/","domain.com");
session_start();
Along the same lines as what cenaculo at netcabo dot pt, bkatz at usefulengineering dot com, and editorial at literati dot ca said about making sure you session_write_close(), don't forget to ob_end_flush() if you're using output buffering.
I've been having some weird hanging issues when I tried to navigate away from a page with content streaming in an Iframe or a separate window.
Instead of:

Do: 
Make sure that you call session_start() again after session_write_close() if you rely on the SID rewriting. Otherwise it will not be rewritten.
Remember: objects with private and/or protected data members cannot be serialized properly by PHP. If you ever find that you are missing some objects from your $_SESSION, make sure you are accounting for this shortcoming in your application.
I was having the same problem as many here regarding setting session data just before a header location redirect and having the session data just not be there. I tried everything people here said, and none of their combinations worked. What did finally work for me was to fire off a session_regenerate_id(true) call just prior to the header() and die() calls.
session_regenerate_id(true);
header('location: blah blah');
die();
Without the regenerate id call, the write close did not seem to do anything. session_write_close() doesn't seem to matter at all. It certainly didn't fix anything on its own for me.
This is a rather annoying issue with php sessions that I've never run into before. I store my sessions to /dev/shm (which is RAM) so file IO blocking can't be the problem. Now I'm nervous that some other session data might not be getting updated prior to a header() location change, which is extremely important and common in any web app.
For the session problem when using header("Location:..."), I found session_write_close() not to help me on the my IIS server using PHP in CGI mode. The problem was the PHPSESSID cookie was never being set, so I did it the manual way:
header("Set-Cookie: PHPSESSID=" . session_id() . "; path=/");
Worked for me this way!
When trying to use exec on Windows 2003 Server together with WAMP you probably will experience that the server stops to answer your requests.
Through calling session_write_close before -every- exec this will solve your problem.
Hope this will help someone!
if you are trying to work with a larger code base meant for a specific application... and it implements some custom session save handlers, it appears there is no way to reset those save handlers back to the default php state if they are getting in your way. my workaround:
session_write_close(); // close the session at the top of the page :)
This function is useful for forcing serialization of session data but it can introduce difficult-to-track bugs if it's called more than once per session_start() call. Since it doesn't have a return value or raise an exception there won't be any indication that the serialization failed and the code will continue normally. Only when a user visits a page that depends on unsaved session data will there be any indication of the failure.
As far as I can tell this affects both the default and custom session handling functions.

Solution, session_start() before echo 

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)