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 :)
Related
I am used to use Java and Spring Framework. But not so long ago I started learning PHP , to get familiar with another kind of language.
I am trying to write a simple thing for drawing using html canvas, so more then 1 user can use that at the same time to draw.
In Java i would use a class variable in controller to store the picture draw by users. And every 1-2 seconds users send the request with the new data they have drawn, so i can add the changes to the global variable. and then send the changes to every user. When a new user enters, the server sends the whole picture to him.
So, my question is, how can i store an application global variable in PHP? like in this example with picture...
As i see, after finishing, the PHP halts and all the variables die with it, right? So is there any way to make a variable application global? So i can get access to it from different parts of application?
I can save it to text file before finishing the script. and every time new request happens, read it again from text file, make changes and then write back to text file... but it's so crazy... isn't there any way just like in Spring Framework and Java that i used before?
You need a form of persistent storage. By persistent, I mean storage that is not based on an individual user's session like the $GLOBALS array is. PHP Sessions are useful for storage for a single user, but one user cannot access the session data of another user.
Persistent storage can be achieved a few ways. Some options: checking a row in a database table or storing a value in a file like you mentioned.
Database storage
Check out php's mysqli_query() for more information on doing this via a database. This will require knowledge of MySQL syntax.
File storage
Check out php's file_get_contents() and file_put_contents() for examples on how to easily interact with retrieving data from files and setting data in files.
As DevZer0 answered - you want to use sessions. More information about session you will find in the php manual: http://www.php.net/manual/en/intro.session.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.
OK Ive written this neat javascript 'thing' using jquery and ajax. Its all based on the idea that a div has an attribute that lets you write inside the div. (contenteditable=true). I thought it would be cool to make a chatroom type thing out of it, and holy cow its doing some cool stuff(*), but I have an issue.
Using ajax I post to a php page that takes the posted data (x,y, text, id) and stuffs it into a JSON-like object. Without writing to a database (overkill I think), how can I make this data persist? See the problem? : The variables in a php page are essentially vapor after the page has ran, so my javascript ajax call to retrieveNewJSON() would find nothing.
*using jquery effects and setting colors I have variably placed text that scrolls and evaporates, matrix style, for example. Also, a cursor is placed in the div where the user clicks.
You have to store the data somewhere. If you don't want to use a full blown database you can store them in flat files (ie: txt) and use PHP's file functions to handle the files.
Of course this is not very scalable, and I'd strongly recommend using a database if you are going to be using this a lot.
You could use cookies (client-side) or session variables (server-side), or you could write to a file for longer-term storage.
You could use a the $_SESSION variable to persist data.
// Call at start of PHP script
session_start()
//....
// Store object
$_SESSION['obj'] = json_encode(obj);
in your pull script:
// Call at start of PHP script
session_start()
// Retrieve object
echo $_SESSION['obj'];
Note that when using sessions you have to make sure that you call session_start() at the top of every php script that uses the session.
I would not recommend trying to store this in a file unless you are supporting a very low number of users and have taken proper data sanitation steps to physically write files to the server. If you need this to persist past the length of a session you should be using a database.
It is worth noting that you can't update a users session without some other form of centralized storage. Unless you have some sort of long-polling / comet type setup you will have to have some sort of central storage place. Something I would take a look at would be memcache.
If you want to avoid using a database engine (which would have a lot of overhead for a multiple-read, multiple-write app like a chat room anyway), you might look at a simple object store like memcache, couch, or mongo. Files are also a valid option, provided you store them outside of the Web root with proper permissions. Bottom line is, you'll have to use some sort of storage engine on the back end in order to make the data shareable across multiple user sessions.
If this is simply a tech demo or a proof of concept, I wouldn't worry too much about overhead right away.
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!
In general, I have the following scenario:
Fetch product and its related data from database
Convert fetched data to php 'product' object
cache product object in session
The cache is readonly, i.e customers viewing products on the site.
But there are calls like getProductIdsByCategory($categoryId) and the productIds from these results are cached too, per user, not using the global cache that I've read about.
A problem is that if someone on the admin side adds a new product and relates it to a category, then customers will not have the new productId come up in their cached getProductIdsByCategory until a new session is started.
Is there a way to clear e.g $_SESSION['x'] from ALL sessions on the server when a new product is added? I don't want to destroy all sessions because customers will then lose their logins etc.
Or should I move these cached productId searches to the global cache?
p.s am using a custom built cache, not memcached or similar.
Thanks
By default, the session data is just serialized files somewhere in your filesystem, and it is possible to go modify all of them to remove the information in question (respecting locking so that you don't step on any currently open sessions).
I don't really recommend it, though. What I would recommend is making a method of signalling that this cached data should be refreshed, like a database-stored timestamp that gets looked at when session_start() happens, and if the cached data is older than the timestamp, the cache is flushed.
Sounds to be like you could do with real shared state through a caching system like memcache.
The only other way that prints to mind is have the application check for flags for dirty cache data and delete it itself, or if your cache is in a database in a parsable serialized form write an expensive script to read them all, but that will create nasty lag with requests that have already read the data.
I would go with real shared state than checking for object copies.
Unless you store sessions in a database, clearing any specific bit of data will be tricky.
I would suggest caching in files rather than user sessions. This way you achieve the same benefits, but you get total control over what is cached and when it gets cleared.
To disable all existing sessions for a particular application, simply modify your application to change the name of the session using PHP's session_name('new_session_name'). This function needs to be called before each call to session_start().
This won't actually clear the current sessions, but it renders them no longer useful for this application.
Yes, you should move it to a global cache. Sessions are not meant to be accessed globally, I hardly think it's possible.
<?php session_destroy(); ?> // To delete whole session
// OR
<?php unset($_SESSION['myVar']); ?> // To delete a session myVar
to clear a session value use:
unset($_SESSION['x']);
you may loop on sessions for that