Reputation: 838
I have a DB configuration (db.php) in the root folder
MySQL with PDO_MYSQL
$host = "";
$user = "";
$pass = "";
$dbname = "";
# connect to the database
$DBH = new PDO("mysql:host=$host;port=3306;dbname=$dbname", $user, $pass,array(PDO::ATTR_PERSISTENT => true));
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
I figured that if I need a DB connection I would need to do
<?php
include '../../db.php';
In all the PHP files that need the DB connection.
My question is do I need to do "include" everytime I need a DB connection or is there a way to set this connections setting Global so I can just call $DBH->prepare(SQLSTATEMENT) any where in the project and it will work.
Or is there a better way to handle DB connection settings?
Upvotes: 0
Views: 384
Reputation: 3582
The short answer: Yes, you need to include your DB file in every page that uses it.
The long answer... PHP doesn't load every PHP file in existence every time a script is run, so it has to know where your variables/classes are coming from. However, there are a couple of ways to not have to include the db file each time. Your options for this are that you can auto-prepend the file, you can have your file included from another file that already has the db variable set up, or you can set your code up in an OO manner and include an autoload file.
auto-prepend
If every file you have on this server needs to access the database AND you have access to the php.ini file, you can set the auto-prepend-file option in your php.ini. This will automatically include the file in every file as if loaded by require
. If you go this route, make sure you are checking in your db file if it's already been loaded:
your-db-file.php
if (!defined('MYPROJECT_DB_FILE_LOADED')) {
define('MYPROJECT_DB_FILE_LOADED', true);
// load DBH and stuff here.
}
include from another file
Another good option that doesn't require you messing with the php.ini file is to structure your code in a way that your php files are loaded from a parent file. A great example of this is how WordPress handles loading its pages. WordPress has a main index.php file that checks the URL and loads pages based on the path. Pages included from this file have access to the variables from that file. A simple example of how to set that up could be like this:
.htaccess in root directory (assuming mod_rewrite is enabled)
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.* /index.php
This will route everything through your index.php file which could have something like this:
// Do all of your DBH stuff
$DBH = ...
$url = trim($_SERVER['REQUEST_URI'], '/');
if ($url === 'some/path/here') {
include 'other-file.php';
}
Then, other-file.php would have access to the DBH variable:
$DBH->do_something();
use OO (object orientated) design and include autoload
The most common method (and imho the best) is to structure your code in an OO way and just include the autoload file. A great example of this is how composer installs dependencies into your project and generates a vendor/autoload.php file to be included.
One simple approach to this would be to namespace your classes, place them all in a directory, and then create an autoload file (using spl_autoload_register). Here is a quick (and untested) example of how you could accomplish that:
Inside /projectroot/lib for example:
/projectroot/lib/MyDB.php
namespace MyProject;
if (!class_exists('\MyProject\MyDB')) {
class MyDB {
// Add some DB methods in here.
}
}
/projectroot/lib/autoload.php
if (!defined('MYPROJECT_SPL_AUTOLOAD_REGISTERED')) {
define('MYPROJECT_SPL_AUTOLOAD_REGISTERED', true);
spl_autoload_register(function($class) {
$class = explode($class, '\\');
if (array_shift($class) === 'MyProject') {
require __DIR__.'/'.join('/', $class);
}
});
}
Then, from any other file you have:
require '/projectroot/lib/autoload.php';
$db = new \MyProject\MyDB();
I realize that the last option doesn't stop you from having to use an include in every file, but you always include the same file (so you can copy/paste), AND any class namespaced correctly in your lib folder will automatically be included any time you need it, so it will work with more than just your db stuff.
Upvotes: 3