Can I share Session variables between multiple clients with php Sessions? - php

what I am trying to find out is, if I can share a Session variable for multiple clients.
Like they can use the exactly same Object. The below example will illustrate what I would like to do.
client1:
start_session();
include('somelcass.php');
//some code...
$someobj = new someclass();
$_SESSION['myobject'] = serialize($someobj);
$id = sha1("somephrase");
set_session_var_for_other_users_by_id('myobject', $id);
client2:
start_session();
include('somelcass.php');
$id = sha1("somephrase");
get_sessionvars_from_other_users($id);
$someobj = unserialize($_SESSION['myobject']);
//now use someobj from class someclass
And my additional question is:
Do you recommand using some session extention like: sessionPsql

Answering your last question first:
The Session PgSQLDocs you linked is the PostgreSQL Session Save Handler. It is a Session Save Handler you can configure to use instead of the default session save handler. The default session save handler in PHP is storing sessions to disk (files). If you use the save handler for PostgreSQL sessions are saved into a PostgreSQL database instead (pgsql).
Saving sessions inside a database can make sense if you want to allow access to the session store from multiple webservers (scaling an application) or in your case (probably) to access all sessions with SQL queries albeit normally a tailored session save handler is defined for that (which could be based on the PgSQL session save handler functions).
To answer your first question then:
Yes you can do so as long as you've got a reference to the object you relate to and you know how to access it. This can be either done by manually accessing the session storage or by sharing a session on it's own and switching sessions to access other session data. It depends on your needs, in your case it's probably more easy to just access serialized data that is stored by the ID in some extra table that has nothing to do with sessions. You should think about how to take care of the data if you don't need it any longer, e.g. remove it after some time of inactivity. In the end you're writing your own session implementation that way which is do-able. PHP before version 4 had no session support out of the box and the session support it has nowadays is very lightweight so if you need to do more specific stuff like you need to do, you normally write your own.
So multiple clients can use the same session (share a session) which is actually as well a way to attack webapps (session hijackingAttack) but as long as the "hijack" is intended inside your application data-flow, I do not see anything technically wrong with it. In PHP that means you need to close the current session, open the other one (sessions are identified by their name and ID), read the value, close the other session and re-open the current one. It technically works in PHP however write solid code when you do this because session problems are quite hard to debug.
This is also often a good reason to write your own object-sharing mechanism between multiple clients instead of re-using PHP's session featureDocs for that.

Multiple clients can't share data in the session object. If you want to share data between clients, you would normally use some other means of server side storage e.g. A database.

I have written a solution for PHP applications to resolve mainly 2 types of problem:
How to share data/variables between PHP Process, hosted on same/differents servers
How to synchronize read/write operations in data/variables
My Project is hosted in GitHub ANYEM Project
First : Start the ANYEM_SERVER using command line
php ANYEM/ANYEM_SERVER/anyem.app.server.impl/ServerImpl.php
Now, in your PHP Application you can do as follow:
<?php
// load server's connection configuration (ANYEM_SERVER IP and Port Number ...)
$clientConnection = ClientConnectionImpl::newClient();
// build a key for your variable that will be stored in server
// the key is composed on 3 Parts : [1] => URL, [2] => Variable Namespace, [3] => Variable Name
$identifier = new ResourceIdentifierImpl("anyem.com", "anyemNameSpace", "a");
$a = 5;
$anyemClient = new AnyemClientImpl($clientConnection, $identifier);
try {
// if $a is reserved by another PHP Process, so this process
// will sleep (1/10) seconds and retry the reservation of the resource
// here, the max number of reservation attempts is 5, if reservation
// fails, an Exception will be thrown
$responseWrapper = $anyemClient->get($a, 5, 100000);
// here we have reserved the variable $a, and we have the unserialized contents
$a = $responseWrapper->getResource()->getData();
// here, we update the contents, send it to ANYEM_SERVER and releasing the lock (we unreserve it)
$anyemClient->put(++$a);
}
catch (Exception $e) {
print $e->getMessage() . "\n";
continue;
}
Hope that can helps someone :)

I think best solution for this problem is using database. Create a table and store in it. When you need just read data from table. it is fast and easy solution to share data between sessions.

Related

PHP - How to share configuration data among sessions

I have a cluster of PHP hosts serving a small PHP script. The script retrieves an array of key/value pairs from the database at the beginning of the script, that are configuration values.
I would like to avoid the retrieving of these configuration data from the database for every request, in order to optimize.
My idea was that the script loads the data from the database only for the first request and it stores these variables into some kind of shared memory that is persistent among all sessions.
I've tried to use PHP global variables but they are all destroyed at the end of the script...
Also, I would like to avoid using a config file because as I said I have more than one host serving the script and I'd like to store the data centralized.
When I need to store small bits of data across scripts, I usually use apc
apc_add('config', array('a' => 'b'));
$config = apc_fetch('config');
...among sessions
rather implies that you are already using sessions - so why not just use a custom session handler?
You load the session data using the session id, and overload the config. Optionally you could set it up so you can call the read method and only return the config data without searching for conventional session data.
Probably the most efficient way to do this would be to run a daemon - that way you can keep the config data in PHP variables. There's a nice single threaded server implementation here.
You can keep this as:-
$_SESSION['_config_data']['index_1'] = 'value_1';
$_SESSION['_config_data']['index_2'] = 'value_2';
$_SESSION['_config_data']['index_3'] = 'value_3';
...
In this way, you will get all the configuration data stored in the session variable "$_SESSION['_config_data']".
But you need to check at the starting of the setting method, whether the session variable "$_SESSION['_config_data']" exists with some pre-filled data or not. If it is, then you don't need to set the configuration data for each page request.
Hope it helps.
Answer is memcached: http://memcached.org/
Its a sort thing that was meant to for this kind of scenarios and there are alot of good tutorials but official php documentation is a good starting point: http://php.net/manual/en/book.memcache.php

How can I achieve this in php?

I would like to make a object, which not need to create all the time....
for example, I have a user object, and the user is created from the db, so, when the user login, I can read the user object information from the db... each user make requests, I need to create a new user object again....Even I make a singleton object...It still can "keep" the object....But I want to save the communication between the php and the db...Is there any way to keep an object instead of query the db all the time? Thank you.
Put it in $_SESSION ? That would make sense, if I read your question right
But I want to save the communication between the php and the db
Use APC or Memcached and cache the queries. Invalidate the cache whenever the User object is changed in a way that requires writing it back to the database.
This will still create a new User object on each request, but it saves you the roundtrip to the database (but not to the cache). There is no way to keep a PHP object in memory between Requests without serializing/persisting it to some other layer. PHP is shared nothing. PHP objects live for the request.
As for storing a users data in an object and storing that within a session,i think would be fine, though I would drag too much data around within the session itself. You need to get a balance however between looking constantly re-querying a data source, or using sessions. It really depends on your application and environment.
You could achieve this in two ways:
1) As Tattat says you could query the db and get the users info and save it as an object into the session $_SESSION['userObj'] = $userObj. You could then pull it back down from the session wherever you needed it e.g $user = $_SESSION['userObj'];
2) Second way is to inherit from a common php page you include on all of your pages (for now calling it common.php). Using the PHP GLOBAL varible to make it available any page that includes the commmon php file. e.g.
global $user;
$admin = db_fetch_object(db_query("SELECT * FROM user u WHERE u.user_id = '%d'", $_SESSION['admin_id']));
The varible $user would be then be accessable by your other php pages as long as you included the common.php file I mentioned before.
Hope this help dude :)

What things should be saved in SESSION and what should not be?

I give one example why this question appears in my head:
Lets say i create class 'PDOstart' which extends PDO class. On class 'PDOstart' all variables needed for PDO is defined on private section (like host, user, password and ect). So it makes very easy to use PDO class like:
$con = new PDOstart();
$con->query("SELECT ... ");
Because on my webpage I use only one DB I begin thinking why not add PDOstart object into SESSION? like: $_SESSION['db'] = $con; ? So i don't need on every page do "new PODstart". But I'm not sure that will be good idea...
Is there anything what i should avoid add to $_SESSION (for security or performance reason)?
user id so that every time the page loads you know what use is browsing, meta data such as timespan from page changes (Bot Detect), Local information, User template selection. anything that's required for that session really.
As you stated $con let me explain something.
There are several variable types in php and the main ones are:
strings
boolean's
integer's
objects
arrays
resources
Now you can store all of them into the sessions apart from resources, as there such things as file handles, connections to external entities there only open for the time it takes the page to be processed by PHP, then there closed.
the others are ok as there stored in the memory and are static as such, they will not change unless you programmatically change them.
The main entites you should store in the session are
GUID: So that you can track what user is logged in.
Flash Data: So if your doing a redirect you will be able to show a error message on the other page.
Browser Data, so that you can compare that the browser that is currently browsing is the same as the last, this way you can kill the session fro security.
Things like Database Data such as User Rows should not be stored in the session and you should create a separate cache mechanism to do this for you.
You can store your PDOstart class in the session, as long as you keep this in mind:
When you do $_SESSION['key'] = $obj, you actually serialize the object (assuming default php session handler, that happens when the data is flushed).
When you do this to a 'resource', such as a database connection, there is every likelihood the connection will not persist.
To workaround such cases, php has the __sleep and __wakeup magic methods
I would assume your PDOstart class will ensure connection to PDO on both __construct and __wakeup, doubling the complexity.
However, there's another reason for not doing it that way: the session might go away at any moment, so you shouldn't really rely on any information being there. Surely you can place safeguards, which would re-initialize everything, but that again is adding unneeded complexity.
There's no golden rule (at least that I'm aware of) that explicitly states you should keep as little info as possible in your sessions, but it seems to be a fairly common approach. I'd keep a user id and probably an access token. There's not much stopping you to do it otherwise tho.
As for security, this kind of use shouldn't really matter, as long as the session as a whole is secure. They never truly are, but it's a whole different topic.
Short answer: good things to store - user id, bad things to store - everything else.
Some complement to the good response of RobertPitt you should really add an autoloader if you start storing objects in the session.If the class of your object is not available you'll get a standard broken objet if you do not have an autoload mecanism for class loading.
Then, depending on how your session are stored you should be careful of the size they take. let's say you store it on a very fast drive or on a memcached service, you do not need to worry too much about the fact that this file will be read for every request of your user. If you have slow IO on your drive be careful. Now if you store your session in a database you may care about the insert/update/delete rythm on the session table, some databases (think about MySQL) are not very god at handling an high write load on one table.
In term of security you do not have to worry too much about session storage as it is on the server. At least if you (the admin) use disk storage you should ensure that all handled application are not using the same directory for session storage, if not the weaker application will define you security level for sessions.

JSP/Servlets Sessions + PHP : Keeping track of sessions - JSON / Database or HttpSessionListener?

I have implemented a Servlet, and a PHP site is accessing that Servlet to retrieve data. I'm wondering what is the best method to store a session variable, or whether I should store it at all.
Variables which need to be stored include an ArrayList, and other objects.
I've thought through about 3 possibilities:
(1) Implement the HttpSessionListener, and store each session (when it's created) into a static SessionMap. Then delete the session once it is destroyed.
(2) Store everything in JSON. So I'll have to serialize/deserialize each Object and pass it back and forth. (I have a list of items in each ArrayList/Object I want to keep track of between user clicks.)
(3) Store the information in MongoDB (just to pick one), using the SessionID as the primary key.
What do you guys think?
I rather like a combination of all three.
Has the advantage of simplicity - no need to go to a database if there's a session available.
JSON is lightweight, and it's the language of the browser.
Storing items in a database and retrieving them using session ID allows the possibility of users starting a session, leaving it in an incomplete state, and coming back later to pick up where they left off. The database might be a nice way to store information if the memory requirements become large and cumbersome.
I don't believe it has to be an exclusive choice.
The HttpSessionListener is unnecessary here. All you basically need to do in the servlet is:
List<String> links = (List<String>) request.getSession().getAttribute("links");
if (links == null) {
links = new ArrayList<String>();
request.getSession().setAttribute("links", links);
}
links.add(request.getParameter("link"));
The attributes will be garbaged anyway when the session get destroyed.
JSON only adds unnecessary overhead and a database is only beneficial when there's not much memory space in webserver (however, DB's in turn also eats memory to a certain degree).
I only wonder how you think to maintain the same servlet session from PHP on. This would involve invoking the servlet using JSESSIONID attribute in URL (bad idea) or a PHP script with curl acting as a proxy (why not just doing it all in PHP?). Or is it running on the same domain? Or are you using Quercus to run PHP on a Java servletcontainer?

Best practice for storing global data in PHP?

I'm running a web application that allows a user to log in. The user can add/remove content to his/her 'library' which is displayed on a page called "library.php". Instead of querying the database for the contents of the users library everytime they load "library.php", I want to store it globally for PHP when the user logs in, so that the query is only run once. Is there a best practice for doing this? fx. storing their library in an array in a session?
Thanks for your time
If you store each user's library in a $_SESSION as an array, as you suggested (which is definitely possible) you will have to make sure that any updates the user makes to the library are instantly reflected to that session variable.
Honestly, unless there is some seriously heavy querying going on to fetch a library, or you have tons of traffic, I would just stick to 'execute query whenever the user hits library.php'.
Consider the size of the data. Multiply that by the maximum number of concurrent users.
Then compare that the to memory avaiable on your server. Also consider whether or not this is a shared server; other sites needs resources too.
Based on this, it is probably best to either create a file that can be used (as per Remi's comment), or remain in the default stateless form and read every time. I doubt that reading the data each time is creating much of an overhead.
When the user login you can generate a xml file (USER_ID.xml for instance) that you display with xslt.
http://php.net/manual/en/book.xslt.php
Each PHP script dies when it completes, so data can not be kept permanentely live in a web application as you would do in a PC application.
One way could be sessions, but it depends on the amount of data you want to save. According to your example you are talking about a library, so it sounds to me like big quantity of data need to be saved, in such case the DB is the way to go, and yes you have to query it each time.
Another way could be to save them in an array inside a php file, but in the same way you have to query the DB each time, you would have to include such php file each time.
Since this is a db performance optimization, I would suggest that you take a look at memcached which matches your problem perfectly:
memcached is [..] intended for use in speeding
up dynamic web applications by
alleviating database load.
I think it would be best to store it in a Session.
It the user logs in, the Session is being created and you can save data in it using the superglobal:
$_SESSION['key'] = "value";
You can also store Arrays or everything else there and it can be cleared if the user logs out.
you care for performance; Please note:
Session may use database or file to store data.
database is here to be used instead of files, for it's performance and abilities.
use database, it is designed to be used exactly in such situations!

Categories