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?
Related
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
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.
I'm working on a medium-sized (probably) PHP system which had MySQL connections being opened everywhere throughout different files and, made into global variables for the later included scripts to have access to. Since I'm creating another module, I'd like to avoid globals and keeping the same mysql connection for each page request. My current solution is this:
Class Db {
static public $dbConnectionArray = array();
}
For every request, the connections would be saved in the static array and referred back to at a later time. What do you think could go wrong? And why?
Would like to hear some opinions on how to best tackle this as I would love to reduce the number of opened connections per script run (currently, one page request invoked about 6-15 mysql connections to at least 3 different databases).
No need to reinvent the wheel. you can use mysql persistent connections to keep connections alive. (http://php.net/manual/en/function.mysql-pconnect.php)
By using persistent connections, your PHP scripts will reuse the same database connections (as long as the database name & credentials are the same)
Also, if your databases are on the same host, you should be able to use the same mysql connection by using mysql_select_db() function.
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?
My AJAX search program keeps asking PHP for results of a particular search term. The start of the PHP script reads thru a MySQL DB and initializes, so if the PHP keeps restarting, it will have to read the DB millions of times. If I can keep it alive and let multiple silly AJAX requests be served by a single running PHP script instance I'm sure performance would improve.
How do you do this typically? Use a service? Can this be done with services?
PHP has no concept of long-lived objects or shared state between threads or requests, every request always starts at zero (except for the session state, of course). You can emulate long-lived objects by caching to disk or memory (see memcached).
Do you have a particular reason to read the entire database when your script initializes?
How about storing the db results in a session variable? You'd check first if the keyword is not in the session (sessions allow to transport variable values between page refreshes), and if not, do a db query.
To store it:
$_SESSION['storedQueries']['keyword']= 'its definition, from the database';
To look for it:
$index= array_search('keyword',array_keys($_SESSION['storedQueries']));
$result = ($index) ? $_SESSION['storedQueries'][$index] : 'nothing found, you should do a db query';
The ajax part is pretty easy if you use a javascript library, such as jquery:
$('#resultZone').load('find.php',{keyword: $('input.search').val() });
If you know the results are the same every time, just move those results to a session variable.
PHP sessions are explained pretty well in their documentation:
http://us3.php.net/manual/en/book.session.php
If the search result is something that would be similar to multiple users, I usually create a cache file and serialize the result set there. As a filename I might use md5sum of a string containing the search query and perhaps user group. Then when a Ajax needs the data I just need to check if the file is too old, if not I just need to send it to the client or maybe even just redirect the Ajax http-request to the file (assuming it is formatted properly). If the file is too old, I just refresh it with new content.
For very high volume sites memcached is usually a better option. And also some kind of php cache helps and SQL connection pooling lowers the overhead of opening SQL connections.
connecting to the DB is a very expensive operation and you can go around that by caching the results, take a look at Zend_Cache and see how it can save you allot headache.