Before marking this question as a duplicate to php session_id algorithm without session?, I need to ask this...
currently I use session_id() to retrieve a value that is assigned to a user and store it in a database.
This link has more info on session_id(): http://php.net/manual/en/function.session-id.php
Later I found out that I can create my own configuration into a single cookie of smaller size than the size of a standard PHP session cookie when I check the HTTP header response from the pages in both cases.
I also found out to use session_id(), sessions need to be started (can be called via session_start()), but every time one is started, PHP creates a session cookie along with other cookies I send, making the HTTP header response bigger.
In order to keep things consistent with the data in the database, how does PHP calculate the value returned from session_id()? I want to write my own function to replace it.
You can find the entire source for that function here. It's the latest version though, so be wary of any differences from your PHP version.
Related
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.
I'm working on a demo tool (PHP, jQuery, XHTML), so far so well, except that I have an issue, I need to save certain information temporarily and I'm doing it through cookies, however the cookies' limit in Apache is 4Kb and I have no longer space within the cookie, so I'm wondering how can I keep saving inside the cookie without a problem if I still don't want to send any information to databases nor text files.
I don't know if maybe by using path or other domain I might be able to work things out.
I would really appreciate any help you can provide me :).
Sessions are like Cookies but they just give the client a unique ID ("session ID") and keep the rest of the data on the server.
Of course this is stored within a database or file but that's totally transparent to you, there's no messing about with SQL queries or file reads or anything.
You just need to replace all $_COOKIE with $_SESSION and put session_start(); at the top of your code: http://www.tizag.com/phpT/phpsessions.php
One downside though: PHP sets all session cookies with no timeout, which the browser usually treats as "delete this cookie whenever the browser is closed". See this question for workarounds: How do I expire a PHP session after 30 minutes?
First you should consider if saving that much data in a cookie is really needed. Maybe you can compress your information or just dont need all of it?
The reason is: the cookie is send at every request to the server (this might more then 1). If you serve images from the same domain, you may get over 20 requests each is sending this large cookie. Assuming your cookie holds 5kb of data, you have 100kb just to loop your information through.
see: http://developer.yahoo.com/performance/rules.html#cookie_size
if you need your information just for the current session, why not saving it into a session var (or memcache etc.pp.)?
Maybe its okay if you just save an id in the cookie and if nothing to this id is in your session, you load it from database and save it in the session. so you have a one-time access per session.
Maybe its better if you provide some more background information.
You could create multiple cookies, but it's a bad idea. The cookies will go across the wire with every request. Consider putting your session information in a database or cache tier.
I guess you could store non-sensitive information with a DOM element. If you are using jQuery you can use .data() - http://api.jquery.com/data/
However, after the page does a full reload its gone.
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.
I understand the $_SESSION thing and I use it, but what session_id really is and what does it give? I don't get it, can you give me a hand? Thank you.
Well you need a small lesson on web technology in general.
Protocol we are using, named HTTP, is stateless. Means it never keep track on requests. Even if you click several links on the site, each request would be fresh new, as though there was no previous ones. There is no way to distinguish requests from the same client.
Thus, if we want to distinguish clients, we have to "mark" them somehow. Assign some unique identifier and make them send it with each request. So your session id is that mark. When you start a session for the first time, a cookie is sent along with server's response. Good client always send all cookies back with every consecutive request. So, we can recognize that client.
Throw in a file on the server side, named after this session id, to store session data - and now you've got a session mechanism!
session_id() returns the value of the session cookie by the name returned from session_name(). session_id() is normally a very long hash that is unique to the client.
PHP could internally implement the setting of the client's cookie this way:
setcookie( session_name(), session_id() );
I recommend that you read the Session reference on php.net. You can get the session ID with session_id(). It's value is generated by PHP.
I am attempting to integrate an existing payment platform into my webshop. After making a succesful transaction, the payment platform sends a request to an URL in my application with the transaction ID included in the query parameters.
However, I need to do some post-processing like sending an order confirmation, etc. In order to do this, I'd need access to the user's session, since a lot of order-related information is stored there. To do this, I include the session_id in the intial request XML and do the following after the transaction is complete:
$sessionId = 'foo'; // the sessionId is succesfully retrieved from the XML response
session_id($sessionId);
session_start();
The above code works fine, but $_SESSION is still empty. Am I overlooking something or this simply not possible?
EDIT:
Thanks for all the answers. The problem has not been solved yet. As said, the strange thing is that I can succesfully start a new session using the session_id that belongs to the user that placed the order. Any other ideas?
Not really what you ask for, but don't you need to persist the order into database before you send the customer to the payment-service? It's better to rely on persisted data in your post-processing of the order when you receive the confirmation of the payment.
Relying on sessions is not reliable since you will have no idea on how long this confirmation will take (usually it's instant, but in rare cases this will have a delay).
Also, in the event of your webserver restarting during this time span, will make you lose relevant data.
A third issue is if you have a load-balancing solution, with individual session-managment (very common) then you will have no guarantee that the payment-server and your client will reach the same webserver (since stickiness is usually source-ip based).
I will venture to guess that since domains are different from where the session is set to where you are trying to read it, php is playing it safe and not retrieving session data set by a different domain. It does so in an effort to preserve security in case somebody were to guess session ID and hijack the data.
Workaround for this, assuming the exchange happens on the same physical disk, is to temporary write order data to a serialized (and possibly encrypted depending on wether or not full credit card number is being tracked, which is a whole another story) file that once read by the receiving end is promptly removed.
In essence all that does is duplicates the functionality that you are trying to get out of sessions without annoying security side-effects.
Many thanks for all the replies.
Smazurov's answer got me thinking and made me overlook my PHP configuration once more.
PHP's default behaviour is not to encrypt the session-related data, which should make it possible to read out the session data after restarting an old session from another client. However, I use Suhosin to patch and prevent some security issues. Suhosin's default behaviour is to encrypt session data based on the User Agent, making it a lot harder to read out other people's sessions.
This was also the cause of my problems; disabling this behaviour has solved the issue.
Make sure you're closing the current session before you attempt to start the new one. So you should be doing:
$id = 'abc123';
session_write_close();
session_id($id);
session_start();
Dirty, but has worked for me:
Tell the payment gateway to use
http://yourdomain.com/callbackurl.php?PHPSESSID=SESSIONIDHERE
PHP uses that method of passing a session around itself if you set certain config vars (session.use_trans_sid), and it seems to work even if PHP has been told not to do that. Its certainly always worked for me.
Edit:
Your problem may be that you have session.auto_start set to true - so the session is starting automatically using whatever ID it generates, before your code runs.
How about do it in another PHP page, and you do a iframe include / redirect user to the second page?
I'm not sure the exact length of time between your transaction and your check; but it certainly seems that your session cookie has expired. Sessions expire usually after 45 minutes or so by default. This is to free up more uniqid's for php to use and prevent potential session hijacking.
I'm not sure if you have a custom session handler and whether it's stored in the database but guessing from your posts and comments on this page I would assume it is stored in server side cookies.
Now the solution to your problem, would be to bite the bullet and store the necessary data in the database and access it via the session id, even if it means creating another table to sit along side your orders table.
If however you are doing the action immediately then the other explanation is that either the user logged out or committed an action which destroyed their session (removing the server side cookie).
You will see these cookies in your servers /tmp folder, try have a look for your cookie, it should be named 'sess' + $session_id.