Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.
Even if you don’t realize it yet, there’s something problematic about your connect.php script. Look at the first few MySQL calls you make:
<?phpmysql_connect("your.database.host","your-username", "your-password")or die("<p>Error connecting to database: " . mysql_error() . "</p>"); echo "<p>Connected to MySQL!</p>";mysql_select_db("your-database-name")or die("<p>Error selecting the database bmclaugh: " . mysql_error() . "</p>"); echo "<p>Connected to MySQL, using database bmclaugh.</p>"; // And so on... ?>
You’re manually typing your database host, your username, your password, and your database name into your script. Now suppose you have 10 scripts and you’re typing that 10 times. The chance of a typo is pretty high.
Not only that, what happens when you change your password? Or you upgrade to a better hosting plan to handle all the web traffic your apps are generating, and you need to change your database host? You’ve got to track down every place you put that information, in every PHP script. That’s a nightmare, and keeps you from actually writing new code and making more cash. Not good.
You need a way to abstract out those pieces of information. Abstraction is a programming term that means hiding the implementation, the way something (like a password) works, from the programs that uses it. You basically have a symbol, or a name, and that name refers to something else with a lot more detail. And even if that detail changes, the name still points to the right thing.
It’s like saying “Leigh,” and meaning my wife, without having to say, “that hot 34-year old woman with short blond hair and great legs.” And the beauty of “Leigh” is that every birthday, you can keep saying, “Leigh,” instead of changing your description.
So suppose you want your code to look more like this (actually, you really do want it to look more like this):
<?phpmysql_connect($database_host, $username, $password)or die("<p>Error connecting to database: " . mysql_error() . "</p>"); echo "<p>Connected to MySQL!</p>";mysql_select_db($database_name)or die("<p>Error selecting the database bmclaugh: " . mysql_error() . "</p>"); echo "<p>Connected to MySQL, using database bmclaugh.</p>"; // And so on... ?>
All you’re doing is writing something that looks a bit like a variable in place of hand-typing the username or database name. Now you can define those variables up above your connection code:
<?php$database_host = "your.database.host";$username = "your-username";$password = "your-password";$database_name = "your-database-name";// Database connection code ?>
But is this really that much better? Not yet; you’ve still got these same values hand-typed into your script. You want to stick the values in a file so no human has to type them. Read on.
Your goal is to get these values out of connect.php, into some place that all your PHP scripts can access them with no typing from you. Open up a new file, and call it app_config.php. Now drop your variables into this new file:
<?php // Database connection constants $database_host = "your.database.host"; $username = "your-username"; $password = "your-password"; $database_name = "your-database-name"; ?>
Be sure and save app_config.php somewhere that makes sense for all your application’s scripts to access it. In this book’s examples, app_config.php is in the root of the site, under scripts/. So if you’re in the ch04/scripts/ directory, you’d access this file at ../../scripts/app_config.php, or [site_root]/scripts/app_config.php. You can save the file wherever you want, as long as you get the path right in your PHP scripts that reference it.
When you move to a production version of your application, you probably want to place this file outside of the site root. That way, web users can’t simply type the path to your configuration script and get all your passwords. Alternatively, you could add security to this directory, although simply getting it out of the web-serving directories altogether is usually easiest.
Now, you can have all your different PHP scripts use these shared variables. Change a variable here in app_config.php, and that change affects all your PHP scripts that use these shared variables.
But how do you actually access these variables? Go back to connect.php, and remove where you defined these variables yourself. If you try and access connect.php through connect.html now, though, you’ll get a nasty error, as shown in see Figure 4-6.
Figure 4-6. You defined your variables in app_config. php, but connect.php doesn’t know this. You need to tell your connection script that it shouldn’t run until it loads app_config.php. Then things will behave, because the variables connect.php uses will be set properly.
The error occurs because connect.php now has no idea what $username or $password refers to. You need to inform PHP that before it tries to do anything in connect.php, it’s required to load app_config.php. And that’s (almost) exactly what you type in your script:
<?php
require '../../scripts/app_config.php';
// Database connection code
?>
Now, PHP loads the file ../../scripts/app_config.php before it runs your mysql_connect function. In effect, require says, “Hey PHP, if you can’t load the file I’m giving, then throw a nasty error, because nothing else is going to work.”
Make sure the path and filename you give require matches where you actually put app_config.php, or you’ll see the error that require produces up close and personal.
Try and run your connection script again, and you should see your table listing, which means things are working well again.
There’s just one more nagging little problem with your code: you’re still using variables for your username and password, along with the database host and database name. And what’s a variable? Something that varies or changes. Accordingly, PHP happily lets you write the following code in connect.php:
mysql_connect($database_host, $username, $password)
or die("<p>Error connecting to database: " . mysql_error() . "</p>");
// This is allowed, but some bad mojo
$password = "hijinks";
So what happens when some other script—which also requires app_config.php—tries to connect with mysql_connect? It’s going to use $password, but now $password isn’t correct anymore. It’s set to “hijinks,” and chaos will ensue.
What you really want is for those values in app_config.php to be constant, and never change. You can do this with the special define function. Open up app_config.php and change your code:
<?php // Database connection constantsdefine("DATABASE_HOST", "your.database.host");define("DATABASE_USERNAME", "your-username");define("DATABASE_PASSWORD", "your-password");define("DATABASE_NAME", "your-database-name");?>
You define the name of a constant and the value for that constant, and PHP creates a new constant. That way, you can type DATABASE_HOST into your code, and PHP really sees “your.database.host”. Perfect! And since this is a constant, it can’t be changed anywhere along the line.
Constants are typed in all-uppercase letters. Caps aren’t required, but it’s another one of those “speak like a PHP programmer” things. You want constants to look different from variables, and using all uppercase names is one way to do that. Constants also don’t have the $ before their name, which is yet another way to differentiate a constant from a variable.
Now you need to make some quick changes to connect.php to use these new capitalized names of constants:
<?php require '../../scripts/app_config.php';mysql_connect(DATABASE_HOST, DATABASE_USERNAME, DATABASE_PASSWORD)or die("<p>Error connecting to database: " . mysql_error() . "</p>"); echo "<p>Connected to MySQL!</p>";mysql_select_db(DATABASE_NAME)or die("<p>Error selecting the database ". DATABASE_NAME .mysql_error() . "</p>");echo "<p>Connected to MySQL, using database " . DATABASE_NAME . "</p>";// SQL query-running goodness proceeds... ?>
You can’t use the { } inside your quotes to print constants. It’s only when you surround a variable (which starts with $) with { } that PHP prints the value of that variable. Instead, use the normal string concatenation approach where you end your string and add the constants using the dot (.), as discussed on Combining Text.
Try connect.php again. You should get a perfectly good list of table names. But this time, you’ve got constants for your important information, safely tucked away in a file separated out of connect.php.
It’s also a good idea to add some additional security to app_config.php, and any other scripts that contain special values like passwords. You can set the permissions on the file to be more restrictive, or move the file to some place your PHP script can access, but your web users can’t. Ask your web or server admin for help if you’re not sure how to do that.