PHP Class - Store MySQL connection for each instance - php

I'm facing a problem which I don't know how to solve. Let's start explaining:
I've got the following class:
class MyClass{
function MyClass($mysql_dbcon){
$this->mysql_dbcon = $mysql_dbcon;
}
function execute(){
include("myscript.php");
}
}
myscript.php is an HTML template which uses Ajax to comunicate with other PHP scripts. Since these other PHP scripts aren't included directly in the class I'm not able to get the variable mysql_dbcon and use a different connection for each instance. Let's guess I've got the following instances:
$i1 = new Myclass($dbcon1);
$i1->execute();
$i2 = new Myclass($dbcon2);
$i2->execute();
Both instances will execute an Ajax function which call other processing scripts but these scripts can't access the instance's mysql_dbcon variable due to they're independent script executions.
How can I solve this? Is it correct to store the MySQL connection in $_SESSION so all the scripts can access it? Maybe this:
$_SESSION['instance_identifier'] = $this->mysql_dbcon;
What I want to achieve
I want to create a class in which the developer can set a MySQL connection and each instance can access to different databases so each instance will show data from different databases. The problem is the dynamic loading of that data.
Thanks in advance

You cannot solve it.
but this script can't access the instance's mysql_dbcon variable due to it's an independent script execution
Exactly. Period. You're starting an entirely different PHP script which shares absolutely nothing with the previous script. In fact, by the time the AJAX request is initiated by the browser, the "existing" MySQL connection will already be torn down and closed since the entire PHP script has already stopped.
"myscript.php" will simply have to open a new connection. You cannot serialise a connection into a session; it's not data which can be represented in a serialised form. This is exactly the same mechanism as any other two independent PHP files, the fact that include and AJAX are involved changes nothing.
Also see https://stackoverflow.com/a/13840431/476

Is it correct to store the MySQL connection in $_SESSION so all the scripts can access it?
No.
I'm facing a problem
You probably aren't, or at least it's not the problem you think it is. It's likely there is no reason for you to need to try to "share" the same database connection across the scripts, even if you could. If you provide more context about why you want to access the same connection, then further advice can be given. There is probably a better way to achieve what you want.
Perhaps you are trying to access one query's result set in different places, in which case the answer would not be trying to share a connection but probably to pass the result set itself.
Additional note about your syntax
class MyClass {
function MyClass($mysql_dbcon) {
Looks like you're using outdated PHP 4 syntax for your constructors. See the manual entry on constructors in PHP 5 for the modern standard.
It's also good practice to define the visibility of your class members using the public/protected/private keywords. See the manual entry on visibility.

Related

Does an instance of a php class get destroyed when you go on another page?

I'm building a login class in php that will use sessions. I wanted to know:
If an instance of this very class will be saved until it is destroyed, even if I move to another page(without destroying it)?
Will I have to rebuild another instance of the class every time (with some saved data in the sessions)?
What is the life of a php class?
PHP variables persist while the program is running... just like any other programming language.
Now, how long does the program actually run? We have to distinguish between:
The PHP interpreter itself (written in C)
Your script (written in PHP)
The PHP interpreter is not designed to share variables between scripts so it doesn't really matter how long it runs.
Your script will run, well, until it's finished: it reaches the last line of finds an exit, die() or return statement. This simple fact should already answer your question. But it's also worth taking into account that there's no point in keeping a PHP script running continuously like a desktop application when it's only used to serve an HTTP request. Unlike other protocols (namely FTP or IRC), HTTP is stateless: each user request starts and closes the connection*.
(*) That's not entirely true (connections can and are normally reused) but doesn't affect the design implications.
Yes, the php class will be destroyed. You can serialize the object and store it in the session, if you choose : Documentation
A PHP object (class instance) acts just like a variable and will be destroyed at the end of the page request. Moreover you cannot store an object in a PHP session. The best you can try is to serialize() it and unserialize() it afterwards to keep your data.
You should see this per request. If you make a new request when going t another page then yes it needs to be rebuild.
What you could also do is Inversion of control or some sort of register setup. This way you can define it once and return an instance.
Example:
$ioc->translate(function() {
# Do stuff load configs. Get data from previous request
return new \Danoon\Link\Translate('../etc/lang/en_US.php');
});

PHP mysqli_connect and database connection without globals, how to make it clean and reliable?

I'll reference parts of the question to simplify what I'm referencing, I'm a non-traditional PHP developer so ask before you edit because past edits have destroyed questions and wasted the time of people trying to answer. If I don't understand the why of what you're telling me I can't understand the code even if it works.
The First Half
Part 1.1: My main question is simply this: how do I make the variable assigned to mysqli_connect() non-global yet clean reliably accessible?
Part 1.2: Adding some complexity to the issue: I access the same file for both AJAX and non-AJAX requests and the "dirty" part is the constant need to check if a non-global variable isset().
My structure for traditional non-AJAX requests looks like the following...
Part 1.3: Currently I have mysqli_connect() assigned to a global variable which I read all the time is apparently pure evil. As far as I can tell the whole global versus (what is non-global, local?) bit is in basic terms the ability to expose only PART of your server code so others can use PHP with a custom API you've built (if not then try to explain it in a single sentence with WHY a human would do that). I have no plans to create any APIs in this fashion though still would like to better understand this topic within the limited scope as in only what applies directly to this question to serve as a basis for the future.
Here is a slimmed down version of my database connection file; I've added commentary to clarify what is going on. I'm not looking to make any super-wild changes though I am obviously looking to improve my approach...
<?php
//This file included by the main PHP file.
if ($_SERVER['HTTP_HOST']!='localhost' && substr($_SERVER['HTTP_HOST'],0,7)!='192.168')
{// LIVE domain
$p0 = explode('www.',$_SERVER['HTTP_HOST'],2);
$domain = $p0[1];
}
else
{// Local or network access
$p0 = explode('www.',$_SERVER['REQUEST_URI'],2);
$p1 = explode('/',$p0[1],2);
$domain = $p1[0];
}
if (!isset($_SESSION['user_status']) || $_SESSION['user_status']<8)
{//Common VERY limited SQL syntax access only.
$GLOBALS['connection'] = mysqli_connect($vars['db_host'],$vars['db_user'],$vars['db_pass'],$vars['db_db']);
}
else
{//Admin SQL syntax access
$GLOBALS['connection'] = mysqli_connect($vars['db_host'],$vars['db_user_admin'],$vars['db_pass_admin'],$vars['db_db']);
}
if ($GLOBALS['connection'])
{
if (!isset($_SESSION)) {include('sessions.php');}
$_SESSION['database'] = 1;
$dbs = true;//structure leftover from 'mysql' to 'mysqli' API switch.
if ($dbs)
{//Timezone, etc...
$query1 = "SET time_zone = '+00:00';";
$result1 = mysqli_query($GLOBALS['connection'],$query1);
if ($result1) {}
else {mysqli_error_report($query1,mysqli_error($GLOBALS['connection']),__FUNCTION__);}
}
}
?>
So currently queries tend to look like this...
$result1 = mysqli_query($GLOBALS['connection'],$query1);
The Second Half
Part 2.1 After a bit of reading it seems that the intended approach for handling mysqli_connect() is to treat the variable in a procedural fashion. I'd much rather assign it once and not have to reconnect to the database seven times if there are seven SQL queries for a single page request (I currently connect once and can see it clearly with MySQL query log enabled). I've often encountered issues where the connection already exists (the dirty aspect of this) which creates conflicts. Even when I utilize classes I have to manually pass them as parameters to functions that are apparently too "deep" via PHP includes to be simply seen globally. So I'm looking to make sure I can have a standard include() of some kind that works cleanly around the site regardless of whether it's an AJAX request or not.
Part 2.2 So in another fashion if we're supposed to use mysqli_connect() in a procedural fashion what keeps the non-global variable from forcing PHP to reconnect to the database for say, all seven MySQL queries for a single page request?
Part 2.3 Simply put what is the best thing to assign mysqli_connect() to (variable, class, object...and what is it's scope)?
Part 2.4 Simply put what is the best way to include the file where mysqli_connect() is located (for the entire site) for more miscellaneous situations such as AJAX requests?
I'll be happy to clarify/edit as needed.
how do I make the variable assigned to mysqli_connect() non-global yet clean reliably accessible?
this one is simple.
If your application architecture is using OOP all the way, then just don't bother - by the time you need this variable, it will be always ready already surely you'll need no raw mysqli object at all.
If you are writing in the old good plain procedural PHP - just make it global.
I access the same file for both AJAX and non-AJAX requests
this one just have no relation to db problem at all.
Learn to use templates (or better MVC separation) and you will find that you can use exactly the same code to serve any request.
the ability to expose only PART of your server code so others can use PHP
This one is wrong.
the reasons are different.
Simply put what is the best thing to assign mysqli_connect() to
In fact, you are concerning of the most trifle things. While paying no attention to real ones.
And your real problem is use of prepared statements. If you are planning to use mysqli_query with raw SQL queries exactly the same way you used to be with old mysql_query - then there is not a single reason to move on - just keep with old mysql_query. As simple as that.

PHP custom session handler - database connection becoming NULL

I debugged and searched for quite a while and I can't figure out what is happening. This is my first time doing a custom session handler, so I'm afraid I'm overlooking something painfully obvious. I want to implement a custom session handler so I can store additional information with the sessions and be able to temporarily disable access to protected areas of the site for certain groups of users.
My login page (which was working fine with basic file-based php sessions), includes a php file with a lot of functions including the session handler functions and my error handler. That included file includes a third file that does the database connection. The connection is made using mysqli_connect() and the resulting link is stored in a variable, $dbc. That same connection is used throughout the site for logging errors, loading/editing site content, etc. I decided to use the same database connection, since it is used already on every page and my session handler will need to be used on almost every page as well. Nowhere in my code do I manually close the database connection, but I think perhaps it is automatically closing somehow.
My functions access the database connection ($dbc) with a global statement. Ex:
function sess_write($id, $data)
{
global $dbc;
...
My open, read, and write functions are supposed to use the variable in this manner. I checked the database connection variable in the open and read functions and it is non-null as expected, but in my write function it suddenly shows up as null. Is PHP doing something between read and write that could potentially be closing that connection? I created a test variable in the same included file that creates the database connection, and used the same global $test; statement in the write function, and that variable appears just fine, so I'm guessing it has something to do with the database being closed. I tried using a second variable to store the database connection (to only be used by the session handler) and that didn't work either. Any ideas? Am I just being dumb as usual?
Per your note, that is correct -- objects will be disposed of before write and close. The traditional workaround for this is to use the register_shutdown_function. PHP 5.4 now has an interface you can use to write a session handler class that simplifies this process. If you implement the interface in a session class, when you pass it to session_set_save_handler() it defaults to setting things up to register the shutdown call for you.

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?

In php how to do session instances?

I'm quite new on php and am trying to learn it.
My question is rather simple but I've been a bit lost while googling for it.
I just want to create an object to manage the database connection. I already did the object and now the problem I'm facing is:
How do i keep it instanced to a session? (So that i don't need to open/close the connection to the database on every page load) And how do I call it afterward?
Are there any way to declare a destroyer, so that when the instance is dying, the connection to the database gets closed?
If you define a __destruct() method on your object, it'll get called when the object is about to be destroyed. You can use this to close your database connection.
You can also use __sleep() and __wakeup() for serializing your objects. They'll get called automatically upon serialization and unserialization. You could use these methods to connect and disconnect as required.
I hate to answer by refuting the question but I think you are going about resolving the problem in the wrong way here.
Rather than worrying about the connection being opened/closed I would suggest using caching, indexing, etc. to solve performance problems when they arise rather than being concerned about the resources involved in establishing a connection.
If you are really concerned about performance why not cache the affected pages and avoid using the database connection at all?
I think you could get the desired effect with this function (don't use this myself, assuming mysql) but be sure to read the comments:
http://www.php.net/mysql-pconnect
I don't think you want to start using sleep/wakeup techniques as to get this working as I understand it would involve creating a whole bunch of separate threads each with its own database connection which will just sap your resources and produce the opposite of the intended effect.

Categories