How are PHP objects attached to a user in a web app - php

My question is if a user comes along and uses an Object Oriented PHP application, how are those objects tied to the user and what happens to them once the user leaves?
I understand how OO

PHP is a shared-nothing architecture, which means that for every HTTP request the browser makes, the application starts with an empty sheet (so far as PHP internals such as variables and loaded classes are concerned). Every PHP object disappears at the end of the request. Permanent data needs to be stored elsewhere (typically a database plus possibly a key-value based cache such as memcached). How user-related data is handled in those outside storages depends entirely on the application.

Objects are not really ever tied to a user... It sounds like you are talking about sessions variables. You can store some information for an individual user by adding it to the php $_SESSION variable like this for example: $_SESSION['user_id'] = 5. Once the user leaves, that information will still be accessible until it expires (You can set the expiration date, or typically it will expire when the user closes their browser). For most web applications dealing with users, the user will be asked to log in and when they do, information about that user gets stored in the session. This allows a user to stay signed in across multiple pages of the pages application. Then if the user decides to log out, this is when you unset or destroy that session data.

When an HTTP request is received, PHP is fired up, sets up the runtime environment for your code and runs it. Afterwards all of this is torn down, to be re-created from scratch on the next request.
So unless you take explicit steps to persist your objects (or any other type of variable, really) to e.g. disk and then read them back on a subsequent request, there will be no trace of objects created in the past at all.

Related

Can I store my users in array on PHP then access the full list in another page?

I have a question about php and how it works on server side.
Im thinking about creating array of users in PHP than access it. When user access the website, my script will push the username to array. Can I access this array in another page without using the database to store the usernames?
Without database- use sessions. Add session_start() on every page you want to access your users array, and then $_SESSION["session_variable_name"] = $users_array to assign your array to session variable. Then if you want to use it, just access it like a usual variable: echo $_SESSION["session_variable_name"][0].
But using database would be much more appropriate. Session variables are accessible only on that session, so if there's new user added to the array, only client who added it will see it. Each user will have his own session, where user array may be completely different from what others will see.
What I'd do- after successful login to the system, assign username to session variable, and then if I want to perform a task for that user, say, get his email address from database, I'd make sql query, selecting email from users, where username equals to username stored in session.
No. This won't work as you described. You can either use a database (typical with PHP is MySQL but there are many other options) or a file (JSON or any of a number of other formats). But the key is understanding why it won't work:
I think you are looking at PHP on the server as one system serving many users. However, from the perspective of PHP, each user is seeing a fresh and separate instance of the PHP system. Depending on how the server is actually configured, there may or may not be multiple PHP processes running at the operating system level. But at the application level, each instance (run) of a PHP program is totally independent, with its own copy of all local (RAM) data storage - including arrays. That is NOT necessarily the case in all languages, but for practical purposes you can treat a PHP server process as if it were a separate server brought online to serve the one current user, then rebooted to serve the next user. With that setup, it should be clear that the only way for the server process serving the 2nd user to see what the 1st user did is if the process serving the 1st user stored the information in non-volatile storage - e.g., MySQL or a file on disk. The advantages of a database over a simple file are that it allows fast & easy queries of the information and hides most of the little details of cooperation between the different server processes - e.g., if there are 10 users all accessing the server at basically the same time, the individual PHP server processes don't have to worry about who can write the file "now".
In addition to the problem of each server process seeing (or not seeing) the data collected from other users, even within a single user the data is not available. Each PHP page request, including regular POST or GET and AJAX calls too, starts a fresh PHP instance (again, this is logically speaking - the server code may actually be resident and not reloaded, but it runs "fresh" each time), so with the exception of session data (as others have rightly suggested) there is no data carried over between pages even for an individual user. Session data is normally limited in size and often is just used as a reference into server-side data stored in files or a database.
first you need to prepare user details array as per below
$userDetailArr = array(
'username' => 'foobar',
'id' => 1,
'email' => 'foobar#foo.com'
);
now add session_start(); function and store above array into $_SESSION variable
$_SESSION['userdetail'] = $userDetailArr;
$_SESSION['userdetail'] you can use anywhere you want. but make sure to add session_start() function at top of page before use session variable.

Passing class Instances and other data between pages in PHP

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.

store authorization object to session?

I've built a class that provides some basic "can I do this?" authorization functions for my site, stuff like "can this user view this resource?" or "can this user add an image?"
So the class object is instantiated in quite a few pages (potentially, every page that has a user interaction) using $authorize = new myAuthorizationClass();
The myAuthorizationClass class then looks up the user's ID and check their access level.
I can then say something like
if ($authorize->canAddImage()){
// do image add stuff
}
Is it possible, secure and "best practice" to store this $authorize object into the session? Is there another way to avoid the overhead of building this auth object on every page, and doing the DB interactions etc?
I don't think it can be as simple as just saying "set the user's auth level to A, B, or C, and set that in their session!" since their access to a particular resource depends on who owns the resource, what role the user has in the site, etc. and we have to check a few different things depending on what type of resource is being accessed.
Thanks
Storing user data within a session (not cookie) is acceptable, as this data is stored on the server side and randomly generated for every user, and as long as your session handling storage is protected, will not be accessible to other users.
If you want to reduce database load by not having to look up the users role/access for every page request, you may want to consider pulling the information upon successful login then storing the (in serialized format) into a session variable. Then, for protected resources, you can unserialize the data stored within the variable, do your check, and proceed accordingly.
I believe it is considered bad practice to store authorization data within sessions.
The reason is quite simple, while the data itself is stored on the server side, where it's safe, the weaker link is actually still (like always) on the client.
The server must identify the client who owns the data somehow, that is usually done in a form of a session_id cookie sent to the user. That cookie will be sent to the server in each request, and the server will be able to figure out who you are by the (very random) ID.
However, over an unsecured WiFi (or a computer), that cookie can be rather easily stolen by an attacker, which will cause the server to identify him as you.
There is no simple way around this, other then SSL and user education. If your site requires very high security (such as money transactions or critical database operations), inform the users about it and advise them to confirm their local security measures.
Also, if your site deals with critical database operations, don't allow anything critical (deletion, table drops etc) done from the web application. Only via the root user.

How does PHP track created objects?

This may be a bit of daft question, but I don't come from an OOP background and although I'm reading and learning as I go I'm still struggling with a few concepts.
Right now I'm working with PHP 5.3 and desiging a fairly simple login using a few different object classes: User which defines the user. Session which starts and maintains session data and if someone is logged in, and Database which does the queries.
So when my script is run, my session object is instantiated, etc... here's my problem though. When I move from one page to the next how is that object tracked? Or perhaps rather my question is how does PHP know the objects that relate to my login are mine and not someone else who logged into the site?
I know if I'm doing this in a non OOP way, I'd simply check the session cookie on each page and check my data that way, which is fine my brain can handle that. But, where and how is object data tracked.
EG:
On each page I want to check if someone is logged in I reference $session->is_logged_in() etc is_logged_in checks the a private variable name is true or false.
There's no checking of cookies at this point which means this object still exists, and, as it keeps asking for a stored variable the instance must persist to be useful... but how does PHP, the server, whatever tie that instance of that object to that user? If all of these objects float around on the server till I destroy them won't there be lots of memory used by objects?
As I said at the start it's probably a really basic, fundatmental question but I'm yet to have my eureka moment with this, I might go back to simpler PHP.
Session data (that is all the data in $_SESSION) is by default serialized and stored to file between requests. The data gets unserialized automatically when session_start() is called.
From the PHP manual on Session Handling (emphasis mine):
The session support allows you to register arbitrary numbers of variables to be preserved across requests. When a visitor accesses your site, PHP will check automatically (if session.auto_start is set to 1) or on your request (explicitly through session_start() or implicitly through session_register()) whether a specific session id has been sent with the request. If this is the case, the prior saved environment is recreated.
Nothing is persisted in memory between requests. PHP has a shared nothing architecture, meaning all objects are recreated on each request anew, unless you are using dedicated cache mechanisms.
So when my script is run, my session object is instantiated, etc... here's my problem
though. When I move from one page to the next how is that object tracked? Or perhaps rather
my question is how does PHP know the objects that relate to my login are mine and not
someone else who logged into the site?
When you start a session, an id is generated. All the session data is associated with that id and it is given to the browser to store in a cookie. Subsequent requests include that id in the cookie, and PHP pulls the data out from where it has stored it.
If all of these objects float around on the server till I destroy them won't there be lots of memory used by objects?
The objects are serialized to files rather than being held in RAM, and are cleaned up with the session expires.
I find that sometimes, when I start to lose perspective as to whats really "happening", a quick trip to a page with phpinfo();,or just logging some ENV variables often clears things up, and puts me back on track…
Globals let you see exactly what "exists" in your environment, and allow you to take a mental restocking of what you're "working with", and how to best attack the challenge.. You'll find a wealth of information, and as to your specific "issues" there are such entries as…
$_SERVER["HTTP_COOKIE"]
$_SERVER["QUERY_STRING"]
$_SERVER["argv | c"]
$include_path
etc…
also, it never hurts to read through your /etc/php.ini (wherever the case may be) for a little one-on-one-time with PHP's internals - to remind you "what its all about".

Caching variables in the $_SESSION variable?

I'm making a php web application which stores user specific information that is not shared with other users.
Would it be a good idea to store some of this information in the $_SESSION variable for caching? For example: cache a list of categories the user has created for their account.
This would be an appropriate use of the session mechanism as long as you keep this in mind:
Session does not persist for an indefinite amount of time.
When pulling from session, ensure you actually got a result (ASP.NET will return NULL if the Session has expired/cleared)
Server restarts may wipe the session cache.
Do this for convenience, not performance. For high-performance caching, choose an appropriate mechanism (i.e. memcached)
A good usage pattern would be like this (ether cookies or session):
User logs in
Store preferences (background color, last 10 records looked at, categories) in session/cookie.
On rendering of a page, refer to the Session/Cookie values (ensuring they are valid values and not null).
Things not to do in a cookie
Don't store anything sensitive (use session).
A cookie value should not grant/deny you access to anything (use session).
Trap errors, assume flags and strings may not be what you expect, may be missing, may be changed in transit.
I'm sure there is other things to consider too, but this is just off the top of my head here.
That could work well for relatively small amounts of data but you'll have to take some things into consideration:
$_SESSION is stored somewhere between requests, file on disk or database or something else depending on what you choose to use (default to file)
$_SESSION is local to a single user on a single machine.
sessions have a TTL (time to live), they dissapear after a set amount of time (which you control)
Under certain circumstances, sessions can block (rarely an issue, but i've run into it streaming flash)
If the data you mean to cache is to be accessed by multiple users you're quickly better off caching it seperately.
If you only want this data available during their session, then yes. If you want it available tomorrow, or 4 hours from now, you need to save it to a database.
Technically you can modify the sessions to have a very long lifespan, but realize if they use a different computer, a different browser or flush their cookies they will loose the link to their session, therefore anything serious you should create a type of user account in your application, link the session to their account and save the data in a permeate place.

Categories