PHP global variable visible by different clients - php

Long time with C - new to PHP.
Please excuse me if I use the word/term in my question.
I have a function that is called multiple times within a page execution. The function's result depends on the previous sub-result held in variables. I have written the function using a global variables for those "sub-results" so they are saved and used again in the next function call.
My concern is when multiple clients hit the server requesting the same page that those "sub-result" variables would be corrupted by multiple pages being executed at the same time.
Is this a concern?
If so, can I have the "sub-result" variables local to a function that is called within page execution and pass them into the function by reference? This should keep the variable's scope limited to the current client's page execution and not affected by other clients, right?
If that is correct -- is there a better way to accomplish this?

Each PHP client (better say request) uses its own data context. This means that if 2 clients are connected at the same time and execute the same PHP code, their variables are not shared and cannot influence to each other.
As pointed by Dan Lugg in comments:
You’d need to use an external data persistence technology to “share” values across PHP processes. Any conventional database/store/file (accounting for locking) would enable you to share state. But, as mentioned, no variables (regardless of static/global modifiers) are shared between processes

Related

Passing PHP SESSION Variables Between Server Side Scripts

Is it possible to have two scripts that both run on say a cron jobs, and pass a SESSION variable from Script1.php to Script2.php? I understand the most common usage of SESSION variables is to create the typical unique ID cookie for users accessing a site via the browser and carrying information about that user from page to page. What would happen if I set a SESSION variable in a script that was executed server side and then run another to attempt and pick up the particular variable? Would the server generate a unique ID for itself that would expire after the likely default of 1440 seconds?
My thoughts are that, I build a lot of PHP scripts for things like consuming APIs where there is multiple files that often need to run in some sort of sequence. Instead of passing information from one script to next via MySQL database updates and selects, I'd like to use the more lightweight and seemingly more convenient SESSION variable method.
Session variables are not for passing data between scripts. They are stored by the server, so the cli, which executes php scripts run by cron, would not have a session at all. Sessions are not something that makes the least bit of sense to use for passing data/state/whatever it is you are talking about between two processes. If you want IPC then you need to either use threading or another language. PHP has traditionally used a database of some sorts for sharing data between processes. There is a reason for this.
The short answer to your original question "What would happen if I set a SESSION variable in a script that was executed server side and then run another to attempt and pick up the particular variable?" Is that if the script was executed by the CLI you would get an error trying to access something that wasn't there. If you were accessing it through a script executed by Apache, for instance, you would put the data into the session belonging to the client that browsed to the URI. The next script would not be able to access that unless it was the same client.
You could set and get environment variables for cli scripts to pass data I suppose.

MySQL Variables PHP COnnections

I'm using a PHP web application to connect to MySQL, what I would like to do is set the userID of the client who has logged in and then use that MySQL variables within views and functions to limit data returned.
Currently, I'm simply using:-
SET #UserID = 3;
And then referencing this within views/functions.
Is this a suitable and reliable method to do this across multiple concurrent user sessions? Will this be present for the lifetime of that users MySQL connection (or page load) from PHP and I obviously want to ensure no other connections leverage this. It's set on every page load (or MySQL reconnection from my app).
Thanks all!
As it clearly states in the first paragraph of the mysql variables man page: http://dev.mysql.com/doc/refman/5.0/en/user-variables.html
User-defined variables are session-specific. That is, a user variable defined by one client cannot be seen or used by other clients. All variables for a given client session are automatically freed when that client exits.
e.g. they exist while the php<->mysql connection is kept alive, PER connection, and automatically removed when the connection is closed/terminated. Unless you're using persistent connections in PHP (which you shouldn't be anyways), the mysql variables would basically exist for the life of that particular script invocation, and will NOT be available when the same user comes back with another http request later.
So, strictly speaking, what you're doing shouldn't be a problem (each PHP connection exists more-or-less independantly). But, that said, it isn't the best approach.
I think you've got a "if all you have is a hammer, everything looks like a nail" problem. MySQL is not designed with the request lifecycle in mind, and it shouldn't need to be aware of it. PHP, on the other hand, is designed with exactly that idea.
Instead of:
mysqli_query('Set #UserID=' . $id);
$output = mysqli_query('SELECT * FROM FOO WHERE ID=#UserID');
Why not just use bound variables?

Static object that is accessible to all users like Application.cfc

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.

How long will an instance of a PHP class last?

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?

Reading and writing global variables across scripts in PHP

Does PHP have global variables that can be modified by one running script and read by another?
No, by design PHP is a "share nothing" architecture, which means nothing is shared between processes running at the same time or between requests running one after another. There are ways to share data, but you have to do it explicitly.
If you just want to share between 2 requests from the same user, sessions or cookies might be the way to go.
If you want to share between multiple users, you probably want some sort of shared persistence, either short term in a cache (eg. memcached) or more robust like a database.
Either way, the data is actually being retrieved and reconstructed on each request. It's just handled automatically for you in the case of sessions.
You can actually do this using shared memory, or APC (which is using shared memory itself).
You can use $_SESSION, i.e.:
script1.php
<?php
session_start();
$_SESSION['myVar'] = "something";
?>
script2.php
<?php
session_start();
echo $_SESSION['myVar'];
//something
?>
The only one which could be accessed between scripts is the superglobal $_SESSION array. This is because whatever you store in the array is sent to a cookie, which can then be picked up by the next PHP script.
Global variables simply mean that they can be accessed in the script regardless of the scope; that doesn't mean they can be sent between scripts.
So either you have to transfer the variables using the $_SESSION array (this stores a cookie on the client computer, so don't sent any sensitive information through that array) or you can either POST or GET between the scripts to send the variables.
Each request is handled by a php instance of its own. Global variables in php are only accessible from within the same php instance. However you can use something like the memchached module to share data between different instances (which should usually be faster than writing the data to the filesystem).
Not as such, but you can use cookies or sessions to maintain data for duration of a user's browsing experience, or you can write to a database or file on-disk if the information needs to persist beyond that.
Another common substitution for global variables in PHP is the shared use of a database like MySQL (albeit not a perfect one)
Global variables are bad in most programming. They're especially bad in multithreaded/multiuser systems like webapps. Avoid. If you must use global variables (rather than global constants) put them in a database with transactions guarding updates.
Since you talk about different scripts though, it sounds like what you really want is a web application framework in a more application oriented language --- something like Django (python) or Rails (ruby). These let you think of your code much more like a cohesive PROGRAM, rather than a lot of loosely connected scripts that process web requests.
I made a tiny library (~2 KB; <100 lines) that allows you to do just this: varDx
It has functions to write, read, modify, check and delete data.
It implements serialization, and therefore supports all data types.
Here's how you can use it:
<?php
require 'varDx.php';
$dx = new \varDx\cDX; //create an object
$dx->def('file.dat'); //define data file
$val1 = "this is a string";
$dx->write('data1', $val1); //writes key to file
echo $dx->read('data1'); //returns key value from file

Categories