Does session_start in PHP prevent session expiration? - php

I'm somewhat bewildered about using session_start in PHP. Should I use it in my scripts both when user initially creates session and when resumes it on consequent queries - or only when creating?
Currently I do not call it when session already exists but I have found that session sometimes expires unexpectedly fast:
For example, from public log of my site I see:
srinivasvarma678 09:14:34 27-Jun-14
I've just logged in...
...
srinivasvarma678 08:59:38 27-Jun-14
I'm proud to tell I've just solved Vowel Count!
I.e. user's last interaction with site was at 8:59 and then in 15 minutes he needs to log in again (though session.gc_maxlifetime=1440)
Could this behavior be explained by the fact I am not calling session_start every time?

Short answer: Yes
As stated here in the PHP docs:
session_start() creates a session or resumes the current one based on a
session identifier passed via a GET or POST request, or passed via a cookie.
So if you want to continue the session, you should always use session_start() on every page...

session_start() allows you to use sessions in your script.
You should use it both when creating new sessions or reusing existent one.
It also updates the session, to it won't be garbage collected and removed.

Related

What additional value does session_destroy bring when I am using session_regenerate_id(true) in PHP?

I've been reading the manual and various pages on the web including lot's of questions here on SO. However, I've still not been able to get my head around the concept of session_destroy() in PHP in conjunction with other means of unsetting session data.
Consider this for a site that never registers session variables outside the $_SESSION superglobal array.
session_start();
$_SESSION = array();
session_regenerate_id(true); // New cookie + old session file on server deleted
session_destroy(); // What does PHP do here that was not done above?
Please note that I have built working login-logout scripts for years. This question is not about getting things to work, but I want to understand exactly what is happening.
(A lot of answers here on SO also use session_unset() which unsets registered variables. However, I never use session_register(), so that seems really redundant.)
The session_regenerate_id() function is meant to copy or move the session data based on its corresponding identifier; it's typically used when a user logs in to prevent session fixation. Afterwards, the session is still active and it can be accessed with $_SESSION.
The session_destroy() removes the current session data. Afterwards, the session is gone and you can only start a new session using session_start().
If a user signs out of your site, the most appropriate action is to destroy the session altogether; i.e. use session_destroy().
Btw, session_register() and session_unset() are deprecated and shouldn't be used.
Let's go to the source. Literally.
session_destroy() and session_regenerate_id() are both implemented in ext/session/session.c in the PHP source. It's obvious from a quick reading that if you pass true to session_regenerate_id, it calls s_destroy on the underlying session save handler, which is the exact same call as the one made by session_destroy. This behaviour has remained the same since at least 2005, according to an svn blame.
session_destroy does make two additional calls to php_rshutdown_session_globals and php_rinit_session_globals. Among other things, this causes session_destroy() to call the close function in the save handler, but this is done automatically when the request has completed, anyway (see PHP_RSHUTDOWN_FUNCTION). It also resets the session to the inactive state (like before calling session_start), which can be seen by calling session_status() (introduced in php 5.4).
The take away from all of this is that you never have to call session_destroy before calling session_regenerate_id(true). However, if you want to reset the session, you still have to call it after, because otherwise the session will still be active, and the current contents of $_SESSION will be written to storage by the save handler when the request has finished.

How does php know to start a new session

PHP will start a new session if a browser is closed and reopened.
The old session file is still kept in the session save directory, but a new session is started.
What does php look for in the browser to know that it must start a new session?
I guess what i am really asking is, what exactly does session_start() do under the hood
To simply answer your question, it looks for a cookie called PHPSESSID and if no cookie is supplied in the request, a call to session_regenerate_id is made to initialize the cookie value.
The cookie is then persistently used throughout the lifetime of the browser.
Unless other settings apply, this is a stripped down version of the default behavior.
The cookie containing the session id is set without an expiry by default. This means it will expire when the browser is closed. So the session will be lost at that point since the client won't have the old session ID anymore.
All you want to know is already written here: http://www.php.net/manual/en/function.session-start.php
session_start() creates a session or resumes the current one based on
a session identifier passed via a GET or POST request, or passed via a
cookie.
When session_start() is called or when a session auto starts, PHP will
call the open and read session save handlers. These will either be a
built-in save handler provided by default or by PHP extensions (such
as SQLite or Memcached); or can be custom handler as defined by
session_set_save_handler(). The read callback will retrieve any
existing session data (stored in a special serialized format) and will
be unserialized and used to automatically populate the $_SESSION
superglobal when the read callback returns the saved session data back
to PHP session handling.
Basically, PHP writes a special file in the file system (usually in the /tmp directory) and gets the data from there.
The session ID (PHPSESSID) is saved in a cookie in the users browser. If none is found/one is invalid it creates one. The image below may be of some help in understanding what you want to know (it's from Chrome).
Once PHP gets this session ID, it looks for the corrisponding session which is stored in the session save_path (normally /tmp on unix machines). It then gives you the ability to access the information stored in that session file using the $_SESSION superglobal.
The cookies are stored only if there is nothing outputted on the PHP page prior to the session_start() call. If there is something being outputted, the cookie is not stored and you need another method(as mentioned, SQLite or MySQL) to store those UNIQUE values and recognize and separate each user.

SESSION variable reset when changing page [duplicate]

Why I can use setcookie without any preparation while need a session_start() before using $_SESSION?And I think works they do are similar.
Because setcookie() defines a cookie to be sent along with the rest of the HTTP headers. That's a completely different thing than what session_start() does, e.g. creating a session or resuming the current one based on a session identifier passed via a GET or POST request, or passed via a cookie.
The first just adds something to the header and sends it to the browser, while the other gets the Session ID from $_COOKIEs or $_GET or $_POST and then tries finding the session file in the session_save_path and when found unserializing the values of it into $_SESSION and if not, create a new session, probably using setcookie in the process to set the Session Id.
See the chapter on Sessions in the PHP Manual.
Edit Like #Felix correctly points out below, the session is not necessarily saved in a file. It's not that important though, because the argument stays the same: session_start will find and (re-) initialize your session data, while setcookie just does what the name implies.
For explanation see the reply before mine.
If you just don't want to call the start_session() function have a look at this setting in the php.ini:
session.auto_start
The session data is not necessarily stored in a file as Gordon says. With session_set_save_handler() you can define your own backend that should store the values, e.g. in a database.
All this data retrieving is handled with session_start(). This way you can easily change you backend without breaking your application.
Note: This is only one reason for session_start(), and again it does lot more then just setting cookies.
The session data is not necessarily stored in a file as Gordon says. With session_set_save_handler() you can define your own back end that should store the values, e.g. in a database.
All this data retrieving is handled with session_start(). This way you can easily change you back end without breaking your application.
Note: This is only one reason for session_start(), and again it does lot more then just setting cookies.

Does closing tab or leaving site call session __destruct in PHP?

I have a web app that stores some objects in the user session so it doesn't have to keep calling to the database every time there's an AJAX hit to the server.
I want to write some cleanup/save functions that are triggered when the user closes the browser tab or navigates away from the page.
Is the session "destroyed" (i.e. calls __destruct for any objects it contains) if a user navigates away from the page - or is it better to handle this client side with a javascript that sends an AJAX request when the user navigates away?
PHP sessions are a server-side thing. The client's browser navigating away from a page won't trigger anything server-side without you explicitly making an AJAX call or similar.
The session is in PHP is not defined as a class. Instead, we have a set of session functions to manipulate the session. To make sure that you have destroyed the session, you need to explicitly call :
session_destroy();
If you have not destroyed the session, the session will do garbage collection after the session timeout. The garbage collection depends on the following parameters - session.gc_maxlifetime, session.gc_divisor and session.gc_probability. To make sure that the garbage collection runs on every session, you will have to add session.gc_probability to 100%. But it definitely add an overhead to the server, especially if yours is a high traffic server.
If you do not explicitly keep track of the sessions and destroy it after use, you are leaving some part of the session management to the OS. See the note from PHP.net:
Note: If you are using the default file-based session handler, your
filesystem must keep track of access times (atime). Windows FAT does
not so you will have to come up with another way to handle garbage
collecting your session if you are stuck with a FAT filesystem or any
other filesystem where atime tracking is not available. Since PHP
4.2.3 it has used mtime (modified date) instead of atime. So, you won't have problems with filesystems where atime tracking is not
available.
The best way is to send a flag via Ajax call when the browser or tab is closed. You can detect it via : window.onunload event of javascript.
Short in short: no. You have to end your session with session_destroy()
If you put any objects into $_SESSION, their destructors are NOT called when the script ends, but if it exists, the magic function __sleep() is calles when PHP serializes $_SESSION. When the next scripts starts the session again, any object that is stored and whose source code is known (e.g. by requiring it before calling session_start(), or using autoloading) will have the __wakeup() method called.
If PHP detects that a session was inactive for a certain time, it simply deletes the serializes file.
See the docs: http://php.net/manual/en/language.oop5.magic.php

can session variables survive from php -> html -> php?

the question is really simple, but i searched it many different ways and the results were not related to my question.
so if i have a session variable in a php file if i open an html page after that and then a php file again, will i be able to retrieve the data ? or do they all have to be adjacent?
I tried php->html->php but i couldn't get the variables on the other side. maybe Im doing something wrong.
Thanks in advance
Not 100% sure what you mean, but if by "open" you mean in the browser, the calls do not need to be adjacent. You just need to do a session_start() in every PHP script in which you want to use session data.
Adjacency is not something that is really relevant for this question.
in PHP way of things, sessions are essentially files that contain serialized data on the server. The browser that called a script containing session_start() call receives a special token that identifies the session on the server, and it is normally (though not necessarily) stored as a cookie.
This effectively means that any php script that uses session_start() and receives a session id (via cookie or otherwise) will read and could use session data, unless it was removed from the server file system between the calls, or the session has expired (frankly, I'm not sure whether PHP removes the expired sessions on the server side).
Accessing anything outside of this model with the browser (html page, or even other sites) will not affect it in any way, unless these actions change or remove session id.
yes...session variable can survive php->html->php.
But on every php page ...very first line should be session_start()
This easy way (I guess): Set a cookie storing the session ID on the first php page. This way, every other php page can access the session ID and use it to restore the stored data, not matter how many (even foreign) pages were in between.

Categories