How to reuse a MySQLi connection - php

I've ran into an issue with user already has more than 'max_user_connections' active connections
This happens because I use functions for the website functionality, each function contains a
$mysqli = connect();
Though at the same time, each function closes the mysqli at the end of function
mysqli_close($mysqli);
I do not want to include $mysqli as a parameter of the function, as the function is dynamic and would be tiresome to include it with each function call.
the connect() function just contains:
$mysqli = new mysqli(...);
return $mysqli;
I believe the error is thrown because the function sometimes calls itself for different executions, based on user input and pre-requisites... even though the mysqli is closed at the end of the function...
I'd like to know if there is a way of re-using a $mysqli connection sort of like in a global way...
I'm not sure whether I've explained myself fully so if you need some more information please leave a comment.

The proper way to reuse the same object across multiple functions/classes is to use dependency injection. Together with DI container, it can take care of providing the necessary dependencies to your functions leaving them clean.
The principle of clean code demands that your functions do not have side effects and they only do what their name states. This means that you should never be using globals in your functions as that would be causing side effects. The proper way to provide data without side effects to your function is via parameters. A connection to the database is the data that is required by your function.
If your code will be used as some kind of public library, it's even more reason to keep it clean. A function cannot have surprising behaviour. The best way to reduce surprises is by having a clear function signature. This means that all dependencies are listed as parameters with their correct types, the function cannot take dynamic arguments, and the return type must be clearly specified.
When it comes to mysqli connections (or PDO for that matter which you should prefer over mysqli), the connection should only be opened once during the execution of the script. You should never need to close the connection manually.
Here's an example of clean code. Let's imagine that you need to save bookings in the database. You create a service in your model:
<?php
class BookingService
{
public function __construct(protected mysqli $mysqli)
{
}
public function saveBooking(Booking $booking)
{
$stmt = $this->mysqli->prepare('INSERT INTO bookings (date, surname) VALUES (?,?)');
$stmt->execute([$booking->getDate(), $booking->getSurname()]);
}
}
Then in your controller, you just use your service as a dependency:
class BookingController
{
public function __construct(protected BookingService $bookingService)
{
}
public function index(Request $request)
{
$boooking = new Booking($request->get('date'), $request->get('surname'));
$this->bookingService->saveBooking($boooking);
}
}
Your DI container takes care of instantiating the mysqli and BookingService class. You can only create value objects in your controller. The necessary data is passed via parameters. This makes for a very clean and understandable code. Everyone knows what each function does, there are no surprises and everything has type specified.

There are a number of techniques to instantiate a variable only once. This is an anti-solution. Please do not use solutions listed here!
Static variable
If you only want a variable to be instantiated the first time the function is called, you can use a static variable.
function foo(){
static $mysqli;
if ($mysqli === null) {
$mysqli = connect();
}
// call the same function in recursive mode and the same connection will be reused
foo();
// do not close the connection manually!
}
This is a bad solution because your function fetches the dependency manually. You should not create functions that have side effects or multiple objectives. A function that connects should not be called from within a function that does something else. This leads to nightmarish code, which is the reason why you are having this problem now.
Using singleton
Singletons are bad for testing and for code readability. Anytime you need to change the dependency, you need to change all the places where the singleton is used. For a better explanation of why they are bad see What are drawbacks or disadvantages of singleton pattern?
Using globals
Globals are very bad for code maintainability. They are the bane of programmers since forever. It's precisely the reason why we have encapsulation and dependency injection.
Using a global would be very similar to using a static variable, except that the side effect is now global.
function foo(){
// declare a variable as global.
// this will instantiate the variable to null if it doesn't exist as a global yet
global $mysqli;
// if it's null, connect
if ($mysqli === null) {
$mysqli = connect();
}
// call the same function in recursive mode and the same connection will be reused
foo();
// do not close the connection manually!
// but if you must close the connection, just set the variable back to null
}
Do not use any of the above solutions! These are examples of bad unmaintainable spaghetti code. A programmer's nightmare. This answer is only supposed to be a warning of what not to do!

Related

Static Varible vs PDO::ATTR_PERSISTENT

I have a database class that I developed. But I have doubts about performance in case of load. There are two issues that I was curious about and couldn't find the answer even though I searched.
When the database connection is bound to a static variable in the class,
class DB
{
static $connect;
......
function __construct()
{
try {
self::$connect = new PDO("{$this->db_database}:host={$this->db_host};dbname={$this->db_name};charset=utf8mb4", "{$this->db_username}", "{$this->db_password}");
self::$connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::$connect->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES utf8mb4");
} catch ( PDOException $e ){
echo '<b>ERROR: </b>'.$e->getMessage();
exit;
}
}
}
PDO::ATTR_PERSISTENT => true
Does it have an equivalent ability?
Also, I didn't fully understand the pdo permalink logic, it uses the existing connection instead of opening a separate connection for each user. But how does he use the existing link here? For example "ip address" etc.
Thank you for your help.
Let me approach the issues from a different direction.
A program should have only one connection to the database. (There are rare exceptions.) Your code, as it stands, seems to be inconsistent. It has a single ("static") connection, yet the class can be instantiated multiple times, thereby connecting multiple times. (I don't want to depend on anything "persist" to clean up the inconsistency.)
Either make the class a singleton or otherwise avoid being able to call __construct a second time. One approach goes something like this:
class DB {
private static $connect;
......
public function __construct() {
if (! self::$connect) {
self::$connect = ...
}
}
public function Fetch(...) {
self::$connect->...
return ...;
}
$con = new DB();
$data = $con->Fetch(...);
(plus suitable try/catch)
Note that that allows you to sub-class as needed.
Another approach might involve preventing the use of new:
private function __construct() { ... }
plus having some public method invoke that constructor.
Here's another approach. It can be used on an existing class that you don't want to (or can't) modify:
function GetConnection() {
static $db;
if (! $db) {
$db = new ...;
}
return $db;
}
$db = GetConnection();
$db->Fetch(...)'
As for "connection pooling", it is of limited use with MySQL. (Other products need it much more than MySQL does.) In my opinion, don't worry about such.
Do not use "auto-reconnect". If the connection dies in the middle of a transaction and is automatically restarted, then the first part of the transaction will be rolled back while the rest might get committed. That is likely to lead to data inconsistency.
Singletons, statics, globals, void*, critical sections all make me cringe. When I need such, I rush to find a way to "hide" it, even if that means writing cryptic code in some class(es).
For performance, MySQL really needs a single connection throughout the program. I compromise by hiding the connection in a "static" that serves at a "global". Then I hide that inside the class that I use to abstract the object(s).
I agree with Karwin's [now delete] Answer -- that this discussion is "much ado about nothing". MySQL performance is mostly about indexing, query formulation, and even the architecture of the application. Not about connections, common code elimination, redundant function calls, etc.

Mysqli conn include file - global variable PHP

I'm including the MySQLi connection file in the constructor of a PHP class. Since I need to reach the connect variable in methods in this class I need to make the variable global. I always heard global variables are bad. So I wonder, is this the only/best way to deal with this?
class CheckUser {
function __construct() {
require_once('mysqli.php');
}
function checkEmail($email) {
// sql code here
}
}
That's just a meme. (And dependency injection is coming right up...)
Your connection handle is a central resource. Use it as such. A global variable is perfectly fine and the intended langauge construct for that. It makes sense as long as you only have one database / connection.
If global variables were bad, we wouldn't have $_GET and $_POST (which are actual global variables).
Should your class (guessing here) be the central access point to database queries, then keeing the handle as simple property is just as cromulent.
function __construct() {
require_once('mysqli.php');
$this->db = $db;
}
Or whatever local variable the mysqli.php script created.

What to use instead of a global variable? [duplicate]

For years I have used global $var,$var2,...,$varn for methods in my application. I've used them for two main implementations:
Getting an already set class (such as DB connection), and passing info to functions that display to page.
Example:
$output['header']['log_out'] = "Log Out";
function showPage(){
global $db, $output;
$db = ( isset( $db ) ) ? $db : new Database();
$output['header']['title'] = $db->getConfig( 'siteTitle' );
require( 'myHTMLPage.html' );
exit();
}
There are, however, performance and security ramifications of doing it like this.
What alternative practice can I use that will maintain my functionality but improve design, performance, and/or security?
This is the first question I've ever asked on SO, so if you need clarifications please comment!
1. Globals. Works like a charm. Globals are hated thus my thoughts of not using it.
Well, globals are not just hated. They are hated for a reason. If you didn't run so far into the problems globals cause, fine. There is no need for you to refactor your code.
2. Define a constant in my config.php file.
This is actually just like a global, but with another name. You would spare the $ as well and to use the global at the beginning of functions. Wordpress did this for their configuration, I'd say this is more bad than using global variables. It makes it much more complicated to introduce seams. Also you can not assign an object to a constant.
3. Include the config file in the function.
I'd consider this as overhead. You segmentize the codebase for not much gain. The "global" here will become the name of the file you inlcude btw..
Taken these three thoughts of you and my comments to them into account I'd say: Unless you run into actual issues with some global variables, you can stick to them. Global then work as your service locator (configuration, database). Others do much more to create the same.
If you run into problems (e.g. you probably want to develop test-driven), I suggest you start with putting one part after the other under test and then you learn how to avoid the globals.
Dependency Injection
As inside comments it became clear you're looking for dependency injection, and if you can not edit the function parameter definition, you can - if you use objects - inject dependencies via the constructor or by using so called setter methods. In the following example code I'll do both which is for demonstration purposes only as you might have guessed, it's not useful to use both at once:
Let's say the configuration array is the dependency we would like to inject. Let's call it config and name the variable $config. As it is an array, we can type-hint it as array. first of all define the configuration in a include file maybe, you could also use parse_ini_file if you prefer the ini-file format. I think it's even faster.
config.php:
<?php
/**
* configuration file
*/
return array(
'db_user' => 'root',
'db_pass' => '',
);
That file then can just be required inside your application where-ever you want to:
$config = require('/path/to/config.php');
So it can be easily turned into an array variable somewhere in your code. Nothing spectacular so far and totally unrelated to dependency injection. Let's see an exemplary database class which needs to have the configuration here, it needs to have the username and the password otherwise it can't connect let's say:
class DBLayer
{
private $config;
public function __construct(array $config)
{
$this->setConfig($config);
}
public function setConfig(array $config)
{
$this->config = $config;
}
public function oneICanNotChange($paramFixed1, $paramFixed2)
{
$user = $this->config['db_user'];
$password = $this->config['db_pass'];
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
throw new DBLayerException('Connection failed: ' . $e->getMessage());
}
...
}
This example is a bit rough, but it has the two examples of dependency injection. First via the constructor:
public function __construct(array $config)
This one is very common, all dependencies the class needs to do it's work are injection at creation time. This also ensures that when any other method of that object is called, the object will be in a pre-determinable state - which is somewhat important for a system.
The second example is to have a public setter method:
public function setConfig(array $config)
This allows to add the dependency later, but some methods might need to check for things being available prior doing their job. E.g. if you could create the DBLayer object without providing configuration, the oneICanNotChange method could be called without that object having configuration and should had to deal with that (which is not shown in this example).
Service Locator
As you need to probably integrate code on the fly and you want your new code to be put under test with dependency injection and all that what's making our live easier, you might need to put this together with your ancient / legacy code. I think that part is tough. Dependency injection on it's own is pretty easy, but putting this together with old code is not that straight forward.
What I can suggest here is that you make one global variable that is the so called service locator. It contains a central point to fetch objects (or even arrays like your $config) from. It can be used then and the contract is that single variable name. So to remove globals we make use of a global variable. Sounds a bit counter-productive and it even is if your new code uses it too much as well. However, you need some tool to bring old and new together. So here is the most bare PHP service locator implementation I could imagine so far.
It consists of one Services object that offers all of your services, like the config from above. Because when a PHP script starts, we yet do not know if a service at all is needed (e.g. we might not run any database query, so we don't need to instantiate the database), it offers some lazy initialization feature as well. This is done by using factory-scripts that are just PHP files that setup the service and return it.
A first example: Let's say the function oneICanNotChange would not have been part of an object but just a simple function in the global namespace. We would not have been able to inject config dependency. This is where the Services Service Locator object comes in:
$services = new Services(array(
'config' => '/path/to/config.php',
));
...
function oneICanNotChange($paramFixed1, $paramFixed2)
{
global $services;
$user = $services['config']['db_user'];
$password = $services['config']['db_pass'];
...
As the example already shows, the Services object does map the string 'config' to the path of the PHP file that defines the $config array: /path/to/config.php. It uses the ArrayAccess interface than to expose that service inside the oneICanNotChange function.
I suggest the ArrayAccess interface here, because it's well defined and it shows that we have some dynamic character here. On the other hand it allows us the lazy initialization:
class Services implements ArrayAccess
{
private $config;
private $services;
public function __construct(array $config)
{
$this->config = $config;
}
...
public function offsetGet($name)
{
return #$this->services[$name] ?
: $this->services[$name] = require($this->config[$name]);
}
...
}
This exemplary stub just requires the factory scripts if it has not done so far, otherwise will return the scripts return value, like an array, an object or even a string (but not NULL which makes sense).
I hope these examples are helpful and show that not much code is needed to gain more flexibility here and punching globals out of your code. But you should be clear, that the service locator introduces global state to your code. The benefit is just, that it's easier to de-couple this from concrete variable names and to provide a bit more flexibility. Maybe you're able to divide the objects you use in your code into certain groups, of which only some need to become available via the service-locator and you can keep the code small that depends on the locator.
The alternative is called dependency injection. In a nutshell it means that you pass the data a function/class/object requires as parameters.
function showPage(Database $db, array &$output) {
...
}
$output['header']['log_out'] = "Log Out";
$db = new Database;
showPage($db, $output);
This is better for a number of reasons:
localizing/encapsulating/namespacing functionality (the function body has no implicit dependencies to the outside world anymore and vice versa, you can now rewrite either part without needing to rewrite the other as long as the function call doesn't change)
allows unit testing, since you can test functions in isolation without needing to setup a specific outside world
it's clear what a function is going to do to your code just by looking at the signature
There are, however, performance and security ramifications of doing it like this.
To tell you truth, there are no performance nor security ramifications. Using globals is a matter of cleaner code, and nothing more. (Well, okay, as long as you're not passing variables of tens of megabytes in size)
So, you have to think first, will alternatives make cleaner code for you, or not.
In matters of cleaner code, I'd be in fear if I see a db connection in the function called showPage.
One option that some people may frown upon is to create a singleton object responsible for holding the application state. When you want to access some shared "global" object you could make a call like: State::get()->db->query(); or $db = State::get()->db;.
I see this method as a reasonable approach as it saves having to pass around a bunch of objects all over the place.
EDIT:
Using this approach can help simplify the organization and readability of your application. For example, your state class could call the proper methods to initialize your database object and decouple its initialization from your showPage function.
class State {
private static $instance;
private $_db;
public function getDB() {
if(!isset($this->_db)){
// or call your database initialization code or set this in some sort of
// initialization method for your whole application
$this->_db = new Database();
}
return $this->_db;
}
public function getOutput() {
// do your output stuff here similar to the db
}
private function __construct() { }
public static function get() {
if (!isset(self::$instance)) {
$className = __CLASS__;
self::$instance = new State;
}
return self::$instance;
}
public function __clone() {
trigger_error('Clone is not allowed.', E_USER_ERROR);
}
public function __wakeup() {
trigger_error('Unserializing is not allowed.', E_USER_ERROR);
}
}
and your show page function could be something like this:
function showPage(){
$output = State::get()->getOutput();
$output['header']['title'] = State::get()->getDB()->getConfig( 'siteTitle' );
require( 'myHTMLPage.html' );
exit();
}
An alternative to using a singleton object is to pass the state object to your various functions, this allows you to have alternative "states" if your application gets complicated and you will only need to pass around a single state object.
function showPage($state){
$output = $state->getOutput();
$output['header']['title'] = $state->getDB()->getConfig( 'siteTitle' );
require( 'myHTMLPage.html' );
exit();
}
$state = new State; // you'll have to remove all the singleton code in my example.
showPage($state);
function showPage(&$output, $db = null){
$db = is_null( $db ) ? new Database() : $db;
$output['header']['title'] = $db->getConfig( 'siteTitle' );
require( 'myHTMLPage.html' );
exit();
}
and
$output['header']['log_out'] = "Log Out";
showPage($output);
$db =new Database();
showPage($output,$db);
Start designing your code in OOP, then you can pass config to the constructor. You could also encapsulate all your functions into a class.
<?php
class functions{
function __construct($config){
$this->config = $config;
}
function a(){
//$this->config is available in all these functions/methods
}
function b(){
$doseSomething = $this->config['someKey'];
}
...
}
$config = array(
'someKey'=>'somevalue'
);
$functions = new functions($config);
$result = $functions->a();
?>
Or if you cant refactor the script, loop through the config array and define constants.
foreach($config as $key=>$value){
define($key,$value);
}

Safe alternatives to PHP Globals (Good Coding Practices)

For years I have used global $var,$var2,...,$varn for methods in my application. I've used them for two main implementations:
Getting an already set class (such as DB connection), and passing info to functions that display to page.
Example:
$output['header']['log_out'] = "Log Out";
function showPage(){
global $db, $output;
$db = ( isset( $db ) ) ? $db : new Database();
$output['header']['title'] = $db->getConfig( 'siteTitle' );
require( 'myHTMLPage.html' );
exit();
}
There are, however, performance and security ramifications of doing it like this.
What alternative practice can I use that will maintain my functionality but improve design, performance, and/or security?
This is the first question I've ever asked on SO, so if you need clarifications please comment!
1. Globals. Works like a charm. Globals are hated thus my thoughts of not using it.
Well, globals are not just hated. They are hated for a reason. If you didn't run so far into the problems globals cause, fine. There is no need for you to refactor your code.
2. Define a constant in my config.php file.
This is actually just like a global, but with another name. You would spare the $ as well and to use the global at the beginning of functions. Wordpress did this for their configuration, I'd say this is more bad than using global variables. It makes it much more complicated to introduce seams. Also you can not assign an object to a constant.
3. Include the config file in the function.
I'd consider this as overhead. You segmentize the codebase for not much gain. The "global" here will become the name of the file you inlcude btw..
Taken these three thoughts of you and my comments to them into account I'd say: Unless you run into actual issues with some global variables, you can stick to them. Global then work as your service locator (configuration, database). Others do much more to create the same.
If you run into problems (e.g. you probably want to develop test-driven), I suggest you start with putting one part after the other under test and then you learn how to avoid the globals.
Dependency Injection
As inside comments it became clear you're looking for dependency injection, and if you can not edit the function parameter definition, you can - if you use objects - inject dependencies via the constructor or by using so called setter methods. In the following example code I'll do both which is for demonstration purposes only as you might have guessed, it's not useful to use both at once:
Let's say the configuration array is the dependency we would like to inject. Let's call it config and name the variable $config. As it is an array, we can type-hint it as array. first of all define the configuration in a include file maybe, you could also use parse_ini_file if you prefer the ini-file format. I think it's even faster.
config.php:
<?php
/**
* configuration file
*/
return array(
'db_user' => 'root',
'db_pass' => '',
);
That file then can just be required inside your application where-ever you want to:
$config = require('/path/to/config.php');
So it can be easily turned into an array variable somewhere in your code. Nothing spectacular so far and totally unrelated to dependency injection. Let's see an exemplary database class which needs to have the configuration here, it needs to have the username and the password otherwise it can't connect let's say:
class DBLayer
{
private $config;
public function __construct(array $config)
{
$this->setConfig($config);
}
public function setConfig(array $config)
{
$this->config = $config;
}
public function oneICanNotChange($paramFixed1, $paramFixed2)
{
$user = $this->config['db_user'];
$password = $this->config['db_pass'];
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
throw new DBLayerException('Connection failed: ' . $e->getMessage());
}
...
}
This example is a bit rough, but it has the two examples of dependency injection. First via the constructor:
public function __construct(array $config)
This one is very common, all dependencies the class needs to do it's work are injection at creation time. This also ensures that when any other method of that object is called, the object will be in a pre-determinable state - which is somewhat important for a system.
The second example is to have a public setter method:
public function setConfig(array $config)
This allows to add the dependency later, but some methods might need to check for things being available prior doing their job. E.g. if you could create the DBLayer object without providing configuration, the oneICanNotChange method could be called without that object having configuration and should had to deal with that (which is not shown in this example).
Service Locator
As you need to probably integrate code on the fly and you want your new code to be put under test with dependency injection and all that what's making our live easier, you might need to put this together with your ancient / legacy code. I think that part is tough. Dependency injection on it's own is pretty easy, but putting this together with old code is not that straight forward.
What I can suggest here is that you make one global variable that is the so called service locator. It contains a central point to fetch objects (or even arrays like your $config) from. It can be used then and the contract is that single variable name. So to remove globals we make use of a global variable. Sounds a bit counter-productive and it even is if your new code uses it too much as well. However, you need some tool to bring old and new together. So here is the most bare PHP service locator implementation I could imagine so far.
It consists of one Services object that offers all of your services, like the config from above. Because when a PHP script starts, we yet do not know if a service at all is needed (e.g. we might not run any database query, so we don't need to instantiate the database), it offers some lazy initialization feature as well. This is done by using factory-scripts that are just PHP files that setup the service and return it.
A first example: Let's say the function oneICanNotChange would not have been part of an object but just a simple function in the global namespace. We would not have been able to inject config dependency. This is where the Services Service Locator object comes in:
$services = new Services(array(
'config' => '/path/to/config.php',
));
...
function oneICanNotChange($paramFixed1, $paramFixed2)
{
global $services;
$user = $services['config']['db_user'];
$password = $services['config']['db_pass'];
...
As the example already shows, the Services object does map the string 'config' to the path of the PHP file that defines the $config array: /path/to/config.php. It uses the ArrayAccess interface than to expose that service inside the oneICanNotChange function.
I suggest the ArrayAccess interface here, because it's well defined and it shows that we have some dynamic character here. On the other hand it allows us the lazy initialization:
class Services implements ArrayAccess
{
private $config;
private $services;
public function __construct(array $config)
{
$this->config = $config;
}
...
public function offsetGet($name)
{
return #$this->services[$name] ?
: $this->services[$name] = require($this->config[$name]);
}
...
}
This exemplary stub just requires the factory scripts if it has not done so far, otherwise will return the scripts return value, like an array, an object or even a string (but not NULL which makes sense).
I hope these examples are helpful and show that not much code is needed to gain more flexibility here and punching globals out of your code. But you should be clear, that the service locator introduces global state to your code. The benefit is just, that it's easier to de-couple this from concrete variable names and to provide a bit more flexibility. Maybe you're able to divide the objects you use in your code into certain groups, of which only some need to become available via the service-locator and you can keep the code small that depends on the locator.
The alternative is called dependency injection. In a nutshell it means that you pass the data a function/class/object requires as parameters.
function showPage(Database $db, array &$output) {
...
}
$output['header']['log_out'] = "Log Out";
$db = new Database;
showPage($db, $output);
This is better for a number of reasons:
localizing/encapsulating/namespacing functionality (the function body has no implicit dependencies to the outside world anymore and vice versa, you can now rewrite either part without needing to rewrite the other as long as the function call doesn't change)
allows unit testing, since you can test functions in isolation without needing to setup a specific outside world
it's clear what a function is going to do to your code just by looking at the signature
There are, however, performance and security ramifications of doing it like this.
To tell you truth, there are no performance nor security ramifications. Using globals is a matter of cleaner code, and nothing more. (Well, okay, as long as you're not passing variables of tens of megabytes in size)
So, you have to think first, will alternatives make cleaner code for you, or not.
In matters of cleaner code, I'd be in fear if I see a db connection in the function called showPage.
One option that some people may frown upon is to create a singleton object responsible for holding the application state. When you want to access some shared "global" object you could make a call like: State::get()->db->query(); or $db = State::get()->db;.
I see this method as a reasonable approach as it saves having to pass around a bunch of objects all over the place.
EDIT:
Using this approach can help simplify the organization and readability of your application. For example, your state class could call the proper methods to initialize your database object and decouple its initialization from your showPage function.
class State {
private static $instance;
private $_db;
public function getDB() {
if(!isset($this->_db)){
// or call your database initialization code or set this in some sort of
// initialization method for your whole application
$this->_db = new Database();
}
return $this->_db;
}
public function getOutput() {
// do your output stuff here similar to the db
}
private function __construct() { }
public static function get() {
if (!isset(self::$instance)) {
$className = __CLASS__;
self::$instance = new State;
}
return self::$instance;
}
public function __clone() {
trigger_error('Clone is not allowed.', E_USER_ERROR);
}
public function __wakeup() {
trigger_error('Unserializing is not allowed.', E_USER_ERROR);
}
}
and your show page function could be something like this:
function showPage(){
$output = State::get()->getOutput();
$output['header']['title'] = State::get()->getDB()->getConfig( 'siteTitle' );
require( 'myHTMLPage.html' );
exit();
}
An alternative to using a singleton object is to pass the state object to your various functions, this allows you to have alternative "states" if your application gets complicated and you will only need to pass around a single state object.
function showPage($state){
$output = $state->getOutput();
$output['header']['title'] = $state->getDB()->getConfig( 'siteTitle' );
require( 'myHTMLPage.html' );
exit();
}
$state = new State; // you'll have to remove all the singleton code in my example.
showPage($state);
function showPage(&$output, $db = null){
$db = is_null( $db ) ? new Database() : $db;
$output['header']['title'] = $db->getConfig( 'siteTitle' );
require( 'myHTMLPage.html' );
exit();
}
and
$output['header']['log_out'] = "Log Out";
showPage($output);
$db =new Database();
showPage($output,$db);
Start designing your code in OOP, then you can pass config to the constructor. You could also encapsulate all your functions into a class.
<?php
class functions{
function __construct($config){
$this->config = $config;
}
function a(){
//$this->config is available in all these functions/methods
}
function b(){
$doseSomething = $this->config['someKey'];
}
...
}
$config = array(
'someKey'=>'somevalue'
);
$functions = new functions($config);
$result = $functions->a();
?>
Or if you cant refactor the script, loop through the config array and define constants.
foreach($config as $key=>$value){
define($key,$value);
}

Pass MySQL connection to function

I am trying to set up a MySQL connection in a main script, and then call various functions depending on what I want to do. I am having trouble passing the connection information to the function.
I have a class "queries" which contains various functions, all which return an array. This is what the code looks like in my main script (calling function normal)
$mysqli = new mysqli($db_host, $db_user, $db_pass, $db_name) or die (mysql_error());
$stats = $queries->normal($mysqli);
And then inside of the queries resource, I have this code:
class queries {
function normal($mysqli) {
$query = "SELECT number, first, last FROM roster";
$roster = $mysqli->query($query);
Then I proceed to do what I need. I cannot get this to work though. I get the error
Call to a member function normal() on a non-object
on the line that I call the function in my main file.
This is similar to these questions, but I can't quite figure it out.
Passing database connection by reference in PHP
Ensuring MySQL connection works in PHP function
Thank you
$queries is not an object, much less a queries object. Figure out what you assigned to it instead, and assign the right thing to it :)
Ahh, I think I get it now. queries is a class, not an object. You need to make an object that is an instance of the class.
$queries_obj = new queries;
$queries_obj->normal($mysqli);
"Call to a member function normal() on a non-object" means that you are trying to call normal() on a variable that is not an object. Probably you meant to do this:
$queries = new queries();
$stats = $queries->normal($mysqli);
Think of your class definition as a recipe and the object as the actual dish you made using that recipe.
As stated by others, you likely haven't instantiated (created) an object of that class.
I would really not recommend structuring your code like this. Passing around the mysql connection can make your function signatures incredibly cluttered. Two other options are:
Singleton Pattern: Encapsulate your database interaction functions into a single class, and then every time you need to call one of them, you grab an instance of that class. What's nice about this method is that you always get the same db connection, instead of opening many request. If you're not using heavy OO (lots of procedural php, or lots of global functions), this is really helpful. For example:
public function foo() {
$results = Db::getInstance()->query("SELECT * FROM bar");
// Do other stuff
return $results;
}
Inheritance: This pattern is really helpful if you're working in something like MVC, or you need to have objects share functionality. Combined with a singleton, you keep a single db connection per request, and the easy access of the db instance in a member variable.
class DB {
public function __construct() {
$this->conn = Db::getInstance();
}
}
class Foo extends DB {
public function foo() {
$this->conn->query("SELECT * FROM bar");
}
}
Whilst i could agree that passing database handlers around in methods/functions isn't probably the best idea, it's not dirty to pass database objects through to classes via the constructor, especially if you have multiple connections.

Categories