# Better Database Connection Function

I'm about a week into learning pdo. I've created, with help from an example online, a database connection function. I have a config file with all my info (username, pass, database, host) and a function inside a file called db.php. Everything works great with the function below.

Though, I have to put dataConnect() on the top of every page that uses $dbo. Since the function is included in my db.php file, I was hoping that the file was the only thing I needed to include on the page: not both the db.php and dataConnect(). I've been searching online for a better way to do this function but most of the db examples are single use examples. Also, having the variables from the config file as global in the function... I'm assuming is a bad thing. I'm hoping someone can help or let me know that this is a good function. require('config.php'); function dataConnect() { try { global$dbo;
global $dbname; global$dbuser;
global $dbpass;$info['dbhost_name'] = $dbserver;$info['database'] = $dbname;$info['username'] = $dbuser;$info['password'] = $dbpass;$dbConnString = "mysql:host=" . $info['dbhost_name'] . "; dbname=" .$info['database'];

$dbo = new PDO($dbConnString, $info['username'],$info['password'], array(PDO::ATTR_PERSISTENT => true));
$dbo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);$dbo->exec("SET CHARACTER SET utf8");
}
catch(PDOException $e) { header("Location:$basehttp/error");
exit();
}
}


Globals are indeed a bad thing. They are old and full of security issues as well as being nearly impossible to debug. Stay away from them at all costs. Instead, pass those variables as a parameter into any function that needs them and have the function return any modifications if necessary. Once you start learning OOP then you can use class properties in place of globals, but parameter injection is the only solution for procedural programming. Well, you could also use constants, but you don't want to go flashing your password into the global scope that way. At least, I'm pretty sure that is a bad idea. It sounds bad... My experience with security and SQL databases is a bit limited, so you might want clarification here. Database names and non-sensitive information should make fine constants though.

Speaking of constants, typically that is what config files are for. For storing site constants so that they can be reused. You define() a constant by giving it a name, conventionally in caps separated by underscores, and a value and use it almost the same way as a variable, except without the $. For example: define( 'DB_NAME', 'name' ); //implementation$info[ 'database' ] = DB_NAME;


Another problem here is that you are not using those globals even though you went to all the trouble of making them. Instead, you immediately wrap them into an associative array. This seems kind of redundant. What's wrong with using the variables as they are? You don't appear to be using that $info array anywhere else and besides adding clutter, you are just making your code harder to read by using longer instances of the same data. Finally, in regards to your problem, you could use your .htaccess file to advantage, but this really depends on the situation. I would not use this for database connections as it would enforce that connnection on EVERY page, which does not seem necessary. It would be helpful in including the config file in every page though, which is why I mention it. php_value auto_prepend_file "config.php"  As I said, I would not recommend the above for database connections. If you have a number of pages that require a database connection, I would use a "template" to create this connection, then use specific "views" to do certain tasks. This way you only have to write the code once and you can dynamically change which action is performed. For instance, here is an extremely basic, barebone example. Please don't just copy-paste this, its for demonstration purposes only. Extrapolate from it. Template <?php //create db connection$db;//db should be available in local scope
include $_GET[ 'view' ] . '.php'; ?>  Sample View <?php$db->stuff();//do some stuff with db
//print results
?>


The template is the page you would call, but a GET parameter would define what action to perform by loading another page with the database specific actions to take. Whatever variables are in the local scope in the template will also be available in the local scope on the view. Which is why we are able to use the $db as if it were a global. Though this is typically frowned upon because, just like globals, it is hard to figure out where those variables are coming from without the proper context. Again, this is just to give you an idea. • Thanks for the feedback! I've made some changes you've listed in your post. Now the only global is global$dbo; I've used your define( 'DB_NAME', 'name' ); in my config matching them in the db.php file to the $info[]. Everything seem to work great. I'm hoping that this will do the trick. Being that I'm using$dbo throughout the script to connect to the database, being global (I hope) isn't a bad thing. – Jim K Sep 18 '12 at 4:45
• @JimK: Globals are always bad. You could go the rest of your career without ever needing them. You can try converting it to a SESSION variable instead, $_SESSION[ 'dbo' ] =$dbo;. This will make it available on every page, all you have to do is make sure you have a session started first (should be the very first thing you do to avoid accidental whitespace). Just remember, you don't need to start the session if one already exists from a page that is already loaded, this will throw errors. – mseancole Sep 18 '12 at 13:01
• mseancole thanks for the feedback. I've found a great example using classes, so I'm going to take a stab at that and hopefully I can get this global thing nipped in the bud! – Jim K Sep 18 '12 at 17:58