PHPLIB and multiple databases

Expanding PHPLIB
PHPLIB accesses databases through an object created from class DB_Sql.
Db_mysql.inc includes the DB_Sql class as modified for MySQL. We will extend
DB_Sql by adding code to common.php3, after the line that includes db_mysql.inc.
DB_Sql contains many functions to perform queries. The one we want to change is:
<?php
/* public: connection management */
function connect($Database = "", $Host = "", $User = "", $Password = "") {
/* Handle defaults */
if ("" == $Database)
$Database = $this->Database;
if ("" == $Host)
$Host

= $this->Host;

if ("" == $User)
$User

= $this->User;

if ("" == $Password)
$Password = $this->Password;
/* establish connection, select database */
if ( 0 == $this->Link_ID ) {
$this->Link_ID=mysql_pconnect($Host, $User, $Password);
if (!$this->Link_ID) {
$this->halt("pconnect($Host, $User, \$Password) failed.");
return 0;
}
if (!@mysql_select_db($Database,$this->Link_ID)) {
$this->halt("cannot use database ".$this->Database);
return 0;
}
}
return $this->Link_ID;
}
?>
Find the connect() function in your db_mysql.inc (or the .inc for your database), then
copy it in to common.php3 somewhere after the include of db_mysql.inc. You will
have to wrap it in a class definition as described at the end of this article.
I find the code hard to read. Therefore, the first thing to do is make the copied code
readable:
<?php

If your PHP pages use more than one database. This connect() function is run before every database query. $User = "". I suggest always use the brackets to avoid errors when you add code later. it only selects the database once when it makes the connection."). Notice how the connect() code checks the existence of a connection and creates the connection if the connection does not exist. Now. } if ("" == $User) { $User = $this->User. I added brackets to single lines. if (!$this->Link_ID) { $this->halt("pconnect($Host. } ?> I indented the code so the levels let me match the brackets. } } return $this->Link_ID. the connect() code will not pick up the change of database.$this->Database). } /* establish connection. Unfortunately. $User. \$Password) failed. return 0. $Host = "". return 0. This avoids errors caused by missing brackets.$this->Link_ID)) { $this->halt("cannot use database ". } if ("" == $Host) { $Host = $this->Host. with the enclosed code. for the connect code change. } if ("" == $Password) { $Password = $this->Password. the shortcut fails. As soon as you add extra code. PHP lets you get away without brackets around single lines of code after if statements. $Password = "") { /* Handle defaults */ if ("" == $Database) { $Database = $this->Database./* public: connection management */ function connect($Database = "". select database */ if ( 0 == $this->Link_ID ) { $this->Link_ID=mysql_pconnect($Host. } if (!@mysql_select_db($Database. $User. $Password). .

?> (There are shorter ways to write the print line. if we need to diagnose a problem. $db_connect_user="".php3: <?php $db_connection = 0. $db_connect_pass). We are looking for the change that has the least impact on PHPLIB and lets us display the status of the database activity. we change PHPLIB to store the connection id and database name in these fields. If you need to find which database is in use when diagnosing a problem.) How do we get connect() to use our new variables? We could add an extra line near the top so you have: <?php { globals $db_connect. db_connect()). add: <?php function db_connect($db_connect_host="". "</p>"). make both external to PHPLIB. } . // Name of current database. ?> Next.$db_connect_pass="") { globals $db_connect. $db_database = "". Therefore. In common. $db_database . // Common database connection id. if(!empty($db_connect_host)) { $db_connect = mysql_pconnect($db_connect_host. The two things we need outside PHPLIB are the connection id and the database name. /* Handle defaults */ ?> The extra line makes our extra variables available within connect(). } return($db_connect). Straight after the definition of $db_database.There are several ways to change the code. It also works reliable with arrays and other compound variable names. $db_database. Here is a more sophisticated way. insert this in your page: <?php Print("<p>db_database: " . $db_connect_user. This way highlights the variable name in editors that have colour coding. if(!empty($db_database_new)) { $db_database = @mysql_select_db($db_database_new. } function db_database($db_database_new="") { globals $db_database. The rest of your code can set and use the same fields.

Here is the common() function using our db functions: <?php function connect($Database = "". $User. return 0. } } } . $this->Database). } if ("" == $Password) { $Password = $this->Password. return 0."). if (!$this->Link_ID) { $this->halt("pconnect($Host. } if ("" == $Host) { $Host = $this->Host. $Host = "". $Password = "") { /* Handle defaults */ if ("" == $Database) { $Database = $this->Database. } if ("" == $User) { $User = $this->User. $User = "". select database */ if ( 0 == db_connect()) { $this->Link_ID = db_connect($Host. $User. \$Password) failed.return($db_database). } ?> By defining these common functions once. you can get the common variables in all sorts of places. } /* establish connection. without having to add the globals line all over the place. } } if (0 != db_connect()) { if($Database != db_database()) { $this->Database = db_database($Database)) if(empty($this->Database)) { $this->halt("cannot use database " . $Password).

We do that by wrapping connect() in: <?php class db_DB_Sql extends DB_Sql { } ?> . you will have to set up a special connection for that access. The result is worth the slight extra processing. You could also add: <?php $db_type = "". but does not fix the way databases interpret data and SQL. ODBC handles many databases in a generic way that may be a little slower. Oracle. mysql. ODBC lets you use the same code on multiple types of databases. The connect() function is wrapped in a class definition: <?php class DB_Sql { } ?> When we copy the function in to common. ODBC simplifies the connection. user and password for all database accesses. you can have problems with dates requiring different formats and generally weird differences between the databases. then use the ODBC option in PHPLIB. so you can access multiple databases. $db_user = "". Changing the code to handle multiple databases is more complex. You might want to read up on PHP's ODBC connection. } ?> The test for the database is taken outside the test for the connect so that connect() can check for a new database. ?> and store in it the type of database. How? Define variables: <?php $db_host = "". There is only one disadvantage at this stage: We assume the same host. It means we compare db_connect() to 0 twice as often. If you have a user logging on.php3. We place the database connection and the database selection outside of PHPLIB.return $this->Link_ID. You have to change the query functions. then accessing a special database with special privileges. Now for a quick lesson on redefining object classes. If you do use multiple database types. $db_pass = "". etc. even when there is a current connection. ?> Expand the db_database() function to compare the current user and host to the special user and host. as well as the connect and select. we need to redefine the DB_Sql class. so we can use the same functions for database selection everywhere else in your PHP code.

If you have errors with database access.000 more per year. instead of the original. classes.txt".inc to the db_DB_Sql in common. Now define: <?php function db_log($db_log_message) { globals $db_log_file. then insert a print statement to see the SQL in use. When you set up PHPLIB. add log messages like: <?php db_log("current database: " . You are now an expert on objects. you will have a statement that says: <?php $x = new DB_Sql. "a"). make sure you use a directory that exists or you will get a weird error. Start with: $db_log_file = "t:/diag.PHP3. You can now do a lot more. ?> That will use the modified class." ". } ?> Anytime you need to see what is happening. We made an effective change with the minimum impact on the PHPLIB code. In Windows. fwrite($db_log_f. Keep track of the changes. ?> Change it to: <?php $x = new db_DB_Sql. Ignore the errors or write the diagnostic messages to a disk file."\r\n"). OOP and can demand $10. you can copy the query() function from DB_Sql in db_mysql. If the SQL seems to fail. you can place print statements in the external functions to see when connections are made. so you can reapply them to a new release of PHPLIB. db_database()).$db_log_message. A print statement in the middle of PHPLIB may produce error messages about problems writing HTTP headers. Point to a text file somewhere on your disk. fclose($db_log_f). $db_log_f = fopen($db_log_file. PHPLIB writes cookies. .Have a look at the PHP documentation on objects and classes to see what "extends" does. The "25 words or less" summary is: Everything in the extended definition replaces and overrides everything in the original definition. without changing the PHPLIB code. date("Y m d H:i:s"). or similar. Now to use db_DB_Sql.

$db_query_sql) { return(mysql_db_query(db_database($db_query_database). This separate log gives you some control during testing. db_connect()). you can use db_database() first. "select * from?". db_database()). ?> with <?php $result = mysql_db_query(db_database("bookcatalogue"). You might like to create a wrapper function for the database query function or change the function you use. You can also replace: <?php db_database("bookcatalogue"). } ?> Now you can use PHPLIB (and any similar software) with multiple databases extend classes/objects insert diagnostic checks write a log of anything to a file . If you use mysql_query().?> There are some built in logging techniques and system logs you can use. db_log("current database: " . ?> Remember to use the right database in your database accesses so you do not query the PHPLIB database. db_connect()). $result = mysql_query("select * from?". db_database()). $db_query_sql. db_connect()). ?> which suggests the function: <?php function db_query($db_query_database. I recommend it before and after logs like: <?php db_log("current database: " . You may not have access to the right directories and may have to search large files to find a tiny piece of information. db_database("bookcatalogue").