I've done a fair bit of PHP over the years but I'm currently learning ColdFusion and have come across the Application.cfc file.
Basically this is a class that's created once (has an expire date). The class handles incoming users and can set session variables and static memory objects, such as queries. For example I can load site wide statistical data for one user in another thread from the Application.cfc. Something that would usually take a few seconds for each page would make the whole site quick and responsive.
Another example (just for clarification).
If I put an incremental variable that's set to 0 in OnApplicationStart this variable can be incremented with each user request (multiple users) or in OnSessionStart without the need to contact the SQL database since it's constantly in the server's memory under this application.
I was wondering if PHP has a similar file or object? Something that can be created once and used to store temporary variables?
The PHP runtime itself initializes the environment from scratch on every HTTP request, so it has no built-in mechanism to do this. Of course you can serialize anything into common storage and then read it back and deserialize on each request, but this is not the same as keeping it in-memory.
This type of functionality in PHP is achieved by outsourcing to other programs; memcached and APC are two of the most commonly used programs that offer such services, and both come with PHP extensions that simplify working with them.
Related
Is there a more contemporary alternative to PHP session or is PHP session still the main choice to store information? I read this: https://pasztor.at/blog/stop-using-php-sessions. I'm still learning PHP and frankly, I'm quite clueless.
Your first assumption is incorrect. PHP Sessions are not where you store data. Databases, files, Document stores, etc. are where you store your data.
Session "data" is simply the variables included in the $_SESSION array in serialized form. You can run serialize() and unserialize() on variables to gain some insight into what these look like.
In your script, once you have started a session using session_start(), when you add change or delete variables in $_SESSION, php serializes this and stores it for you.
Once a session exists, and a user makes another request that is identified as being the same user (having the same session id) which has typically passed to the client via a cookie, then upon issuing session_start(), PHP reads the serialized data in the session file, and unserializes it, and stores it back into $_SESSION.
By default, PHP will store the individual session data as files on the filesystem. For a small or medium size application, this is highly performant.
So to be clear, what people store in PHP sessions is basically variables read out of whatever other persistent storage you might have, so that you can avoid doing things like re-querying a database to get the name and user_id for a user who has already logged into your application.
It is not the master version of that data, nor the place through which you will update that data should it change. That will be the original database or mongodb collection.
The article you posted has a number of stated and unstated assumptions including:
Devops/Sysadmins just decide to reconfigure PHP applications to change the session handlers (misleading/false)
The deployment involves a load balancer (possibly)
The load balancer doesn't support or use sticky sessions
He then goes on into some detail as to several alternatives that allow for shared session handlers to solve the race conditions he describes
As you stated, you aren't clear yet what sessions actually are, or how they work or what they do for you. The important thing to know about PHP scripts is that they are tied to a single request and sessions are a way of not repeating expensive database reads. It's essentially variable cache for PHP to use (or not) when it suits your design.
At the point you have a cluster, as pointed out in the article people often store data into shared resources which can be a relational database, or any of many other backends which each have different properties that match their goals.
Again, in order to change the session handlers, there is typically code changes being made to implement the session handler functions required, and there are ways to code things that mitigate the issues brought up in the article you posted, for just about every persistence product that people use.
Last but not least, the problems described exist to whatever degree with pretty much any clustered serverside process and are not unique to PHP or its session mechanism.
Usually, that will depends on the use case and other requirements of your application and most of the time people will use PHP frameworks to handle sessions.
Take for example, for Yii 2 framework, the framework provides different session classes for implementing the different types of session storage. Take a look at here https://www.yiiframework.com/doc/guide/2.0/en/runtime-sessions-cookies.
Learning the different types of sessions available out there, allows you to be able to make decisions by weighing the pros and cons. You can also read here for more understanding https://www.phparch.com/2018/01/php-sessions-in-depth/
I've been looking into the problems of having persistent data available between pages in PHP. This particularly applies to objects that have been set up in one page that need to be accessed later. It seems this is more difficult than I assumed it would be, but there are several ways this could be done, although they all seem a bit awkward to use especially when the data gets quite complex:
Passing the data via $_GET or $_POST to the next page
Copying the data to a database and retrieving it in the next page
Putting the data in a session or cookie
Serializing the object and recreating it with the same parameters and values
These all seem quite laborious as they mostly rely on having to deconstruct your existing data structure and then rebuild it again on the next page. I assume this is to reduce memory requirements of the PHP server by purging data from one page as soon as its closed and starting with a 'clean slate'.
Is there a more direct way of passing larger data structures between pages in PHP?
Many thanks,
Kw
I assume this is to reduce memory requirements of the PHP server by purging data from one page as soon as its closed
Nope, this is not because of memory efficiency concern. This is because HTTP protocol is stateless. Each request must carry all information that is necessary to fulfill it.
Counter-example to your proposed scenario:
let's suppose Alice visits page A, some objects are created and you want them to be available in page B.
You track a visit to page B.
2.1. But it's not Alice, it's Bob. How do you determine which objects to show and where do you get them from?
2.2. It is Alice again, but the request arrived to another machine from your 1000 server farm. Naturally, you don't have original PHP objects. What do you do now?
If you use $_GET or $_POST you are limited to non-sensitive data and you expose your objects to any user. You don't want that.
Cookies are limited in size
cookies are usually limited to 4096 bytes and you can't store more than 20 cookies per site.
The best way to persist objects between requests (for the same user) is to use Sessions. There are already session save handlers for memcached, redis, mysql etc. You can also write your own if you need something custom.
In an app written in PHP (e.g., a social network), let's say that 10 users (signed-in) are browsing the website.
In PHP code, there is "user" object created to store users data and to pass values to other functions and classes.
Question: When these 10 users go to user.php, which has code to create "user" object, how are these objects stored in memory in PHP? Do they not conflict? Is each one of the "user" objects are uniquely stored in the memory or would one be overwritten by another?
For example, user a visits first so object "user" contains his/her data but when user second visits, the "user" object in memory is overwritten so when first user calls the object, it's the second users data retrieved.
Or, is it unique?
I want to understand object in PHP as a newbie, please explain it simply because none of the web pages I found regarding OOP explains this.
PHP is a CGI application, that means, it's being started and terminated on each request.
a client sends a request to the web server
the server starts PHP and passes the request to it
PHP allocates a chunk of memory for your script
your script is being executed, all objects it creates are stored in that chunk of memory
you script generates some html, this html is sent to the client
the memory is being freed and PHP is stopped
If you have 10 clients requests coming at the same time, 10 copies of php will be started and 10 independent memory chunks will be used. So, no, objects from different requests do not interfere.
(Note: this explanation is deliberately simplified, there are actually different php setups and persistence options).
The best way to learn this is to install php on a local PC or Mac and then create a php info file
<?php
phpinfo();
?>
... then open it in your browser...This will show you all the settings on your server for php and other things.
Regarding the answer to your question, it's a bit more of an advanced topic for a newbee, but php sessions are what do the work of keeping user info. They usually work off a session id which is unique to the user for a small amount of time, and they dynamically allocate memory or disk space/flat files or a database (again see the settings above) to store the relevant data.
Unfortunately for you none of this is "automatic" you have to create the scripts to make it happen and behave in the way you want. Asking questions on this site is a good start...
You need to look at object design patterns in relation to php which is quite a big subject in its own right. There is an excellent Apress book called 'PHP Objects, Patterns and Practice' which explains some of the more common patterns and how you might use them and would be a good place to start learning.
The users information is all stored in a database, the user object will have to retrieve this data each time the page loads.
The object know what user is looking at the page because of their session_id, which in a nut shell is a random id given to you, stored in a cookie.
using the session_id you can retrieve the correct information form the database.
How long does the instance of a class, object, in PHP last. Is it confined to the running script or will it last for a session? If it does last for a session is this regardless of whether the PHP script has start ed the session?
A simple question but this makes a big difference to me because it will mean user data will survive as an on the server and won't need storing in the session variable. Hence affecting some fundamentals of my design.
Thanks
Colin
the question doesn't really belong to OOP but to PHP behavior in general
All PHP data is going nowhere as well as PHP script itself.
PHP scripts execution is atomic. It's not like a desktop application constantly running in your browser, and not even a daemon with persistent connection to your desktop application. It's more like a command line utility - doing it's job and exits.
That's why using external storage, like file or database is required. But of course you can save only strings there, not instances of variables or anything of the kind. Strings only.
It depends on the way PHP is configured. If PHP is configured as CGI, instances would be lost on each invocation. PHP would be invoked for each http request.
If PHP is configured as a module, then there would be multiple processes handling PHP requests. So, the instance would survive in "that particular" process. But subsequent requests might be handled by a different process.
If you need class instance to survive, you will need to serialize it and store it in DB or file.
If this information is transient (or stored somewhere else) you can store (seralize) it in session. One such example is user's full name which might be required for each http request, so it can be read from DB once and then stored in session.
Example of storing class instances in session : http://www.talkphp.com/advanced-php-programming/3407-storing-class-instance-into-session.html
It's nicely explained here :
How long does an instance variable persist? In Rails? In Java? In PHP?
I'm just playing around with some PHP and was wondering what happens when an object from a class is created within another PHP script?
I assume once its created and been processed their is no way of then going back and 'playing' around with it from another script?
The idea is i'm trying to create a kind of deck of cards using a card class, each card has specific data that is added to each individual object to make it unique, suit, value etc. Once its created i need to be able to go back to specific cards to use them. In java i'd have an arraylist of card objects, i'm not sure how to approach the same area in PHP.
Thanks.
There is no problem passing objects around inside a php script, your problem is that php is that the webserver calling the script is essentially "stateless". i.e. every time someone posts the url from a browser a complete fresh copy of the php program is fired up.
To save data between times there are several options:-
One is to use $_SESSION variables which are associated with a user session but $_SESSION itself is an array so it gets really clumsy holding complex structures here, also , it sounds like you want to share the deck between users.
You could serialise your object and store it in a file -- which is OK as long as its not updated very often -- but if its updated by every user they will start overwriting each others changes.
Much better is to store the deck in a database (SQLITE is usually built into php) so that several users can share and update in a controlled manner.
Another good option would be to use one of the popular data caches such as "memcached" which will cache the data between calls to the script.
To reuse an object between page calls seems to be your issue. Maybe you can serialize the object and store it in database and pick it up back?? Check php.net/serialize Let know how it goes.
What you could do to keep the objects available to you is to serialize the objects and store them in a database table. If you link a game ID or something similar to the cards then you can retrieve them later using this game ID.
I don't know if the cardgame you are writing is realtime, using a database might be too much overhead. Another possibility is to use an existing caching solution, like for example Memcache.
So you want to create a serverside coded cardsgame? Good luck!
It is possible to do this, tho I think a script like a javascript you are talking about is much more suitable.
You could make a function that initialises a deck of cards and work with indexes etc. Save your things in cookies / sessions and work with postbacks. It's gonna be a hell of a job tho in my opinion compared to jscript.
Tho when you think about it, you could use ajax to make this game feel better for the user :).
Php scripts are not like Java server apps.
Where your Java server will run for a long time, your php script will just be a one time thing.
Instead of this kind of process : user make a request to Java-run server, server receive the request in one of it's infinite loops, server process it, server send the response, server wait for new request; you have this kind of thing : a webserver (Apache, Nginx, whatever other webserver) receive the user's request, understand it needs to be interpreted by php, starts a php child, this child do what's in the script, send its answer, dies, the server wait for new requests.
So, when a php script ends, nothing (in good case) is left from it.
But, a php script can use persistent storage on the server so another request can read from it. That's why you have files, databases and even shared memories functions.
If the games state is for one user only, you can use sessions (usually files) to store your deck object. If it's meant to be used by multiple players, you should store it after serialization in a database.