dbConnector, XML_Structor and db.xml sample

[email protected] (Robert Kelly) Thu, 1 Mar 2001 14:54:28 -0700
Newsgroups php.pear
Message-ID <[email protected]>
For those of us who have many databases to connect to.

dbConnector.php creates an XML_Structor object which 
parses a file.  Developers pass which database name they
are seeking to the dbConnector constructor and receive
all the connection-relevant data and a DSN.

db.xml (sample file) should be in a very secure place, of
course.

 <<db.xml>>  <<dbConnector.php>>  <<Structor.php>> 
 <<dbcon.php>> 
-Bob Kelly
[email protected]
db.xml (application/octet-stream, 697 B)
<?xml version="1.0"?>
<dbConnect>
<dbServer> 
    <hostname>dbServerMulder</hostname>
    <ip>255.255.255.1</ip>

    <DB>
        <dbType>mysql</dbType>
        <dbUser>rebate</dbUser>
        <dbName>RebateData</dbName>
        <dbPass>IceParasites</dbPass>
    </DB>

    <DB>
        <dbType>mysql</dbType>
        <dbUser>dbuser</dbUser>
        <dbPass>jerseydevel</dbPass>
        <dbName>Xfiles</dbName>
    </DB>
</dbServer>
<dbServer>
    <hostname>dbServerScully</hostname>
    <ip>222.222.222.222</ip>
    <DB>
        <dbType>oci8</dbType>
        <dbUser>skinner</dbUser>
        <dbPass>nanotech</dbPass>
        <dbName>HowIHateKrychek</dbName>
    </DB>

</dbServer>
</dbConnect>
dbConnector.php (application/octet-stream, 4.5 KB)
<?php
// DB/dbConnector.ph
// reads and translates a XML file with database connectivity information
// returning a DSN 
// +----------------------------------------------------------------------+
// | PHP version 4.0                                                      |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2001 The PHP Group                                |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license,      |
// | that is bundled with this package in the file LICENSE, and is        |
// | available at through the world-wide-web at                           |
// | http://www.php.net/license/2_02.txt.                                 |
// | If you did not receive a copy of the PHP license and are unable to   |
// | obtain it through the world-wide-web, please send a note to          |
// | [email protected] so we can mail you a copy immediately.               |
// +----------------------------------------------------------------------+
// | Authors: Stig Bakken <[email protected]>, Bob Kelly <[email protected]>|
// | Code largely taken from XML/Parser.php                               |
// +----------------------------------------------------------------------+
//

/*
    $id$
    dbConnector.php
    Parses an XML file, seeking for a specific database, returning
    an object that holds all DB information including a
    dbConnector->DSN, which is passed to PEAR DB and allows
    complete connectivity to all DBs.

*/

/*
    TODO 
    PEAR-ERROR 
    Accurate documentation
    Adding new DBs to the buildDSN and confirmData methods
*/

/*
    configuration
    probably needs to use $GLOBALS
*/

    if ( ! defined ( XML_DATA_FILE ) )  define ( XML_DATA_FILE, "./db.xml" ); 
    if ( ! defined ( XML_DATA_TAG ) )  define ( XML_DATA_TAG, "DBNAME" ); 


    if ( ! defined ( PEARDEBUG ) ) {
        define ( "PEARDEBUG", 1 );
        require_once ( "Insight/debug.php" );
    }
    include_once ( "XML/Structor.php" );

    /** dbConnector constructor

     */
    class dbConnector {
        var $data;
        var $DSN;

    function dbConnector ($find) {
        $dbStruct = new XML_Structor();
        $dbStruct->setInputFile ( XML_DATA_FILE );
        $dbStruct->setInput ($this->fp );
        $dbStruct->struct ( );

        if (!  $this->data = $dbStruct->retrieveData ( XML_DATA_TAG, $find ) ){
            return ( "Error" );
        } 

        if (! $err = $this->confirmData() ) {
            $this->buildDSN();
        } else {
            _errPrint ( $err );
        }

        return ( $this->DSN );
    }

    /** confirmData
         Confirms this->data to ensure it has all 
         necessary values to create a DSN.  Functions off of the 
         absolute bare minimum.
    */
    function confirmData ( ) {
        switch ( $this->data["DBTYPE"] ) {
            case "mysql" :
                $req = array ( "DBTYPE", "DBNAME", "DBUSER", "DBPASS");
                break;
            case "oci8" :
                $req = array ( "DBTYPE", "DBNAME", "DBUSER", "DBPASS");
                break;
        }
        return ( $this->compareRequired($req) );
    }// end method confirmData

    /** compareRequired
    */
    function compareRequired ( $req ) {
        foreach ( $req as $r ) {
            if ( !isset ( $this->data[$r] ) || $this->data[$r] == "" ) {
                $err[] = "Missing: " . $r;
            }
        }
        if ( isset ( $err )  ) {
            return $err ;
        } else {
            return ($true);
        }
    }// end method compareRequired

    /** compareRequired
    */
    function buildDSN () {
        $this->DSN = $this->data["DBTYPE"] ;
        switch (  $this->data["DBTYPE"] ) {
            case 'mysql' :
                $this->DSN .= "://". $this->data["DBUSER"] .":". $this->data["DBPASS"] ."@";
                if (! $this->data["HOSTNAME"]) {
                    $hostspec = $this->data["HOSTNAME"];
                } else {
                    $hostspec = $this->data["HOSTNAME"];
                }
                // Note that 3306 is the MySQL default port
                if ( in_array ("DBPORT", $this->data) && $this->data["DBPORT"] != "3306" ) {
                    $hostspec .= ":" . $this->data["DBPORT"];
                }
                $this->DSN .= $hostspec . "/" . $this->data["DBNAME"];
                break;
            case "oci8" :
                
                break;
        }
    } // end method buildDSN

    } // dbConnector

?>
Structor.php (application/octet-stream, 4.4 KB)
<?php
// XML/Structor.php extending XML/Parser.php
// +----------------------------------------------------------------------+
// | PHP version 4.0                                                      |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2001 The PHP Group                                |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license,      |
// | that is bundled with this package in the file LICENSE, and is        |
// | available at through the world-wide-web at                           |
// | http://www.php.net/license/2_02.txt.                                 |
// | If you did not receive a copy of the PHP license and are unable to   |
// | obtain it through the world-wide-web, please send a note to          |
// | [email protected] so we can mail you a copy immediately.               |
// +----------------------------------------------------------------------+
// | Authors: Bob Kelly <[email protected]>                           |
// | Code largely taken from XML/Parser.php                               |
// +----------------------------------------------------------------------+
//

require_once "XML/Parser.php";

/*
TODO
A Return All data function (getChildren)
Support FETCHMODE in RETURN ALL data
PEAR-ERROR extension for not finding the 
data.
*/

/**
 * XML_Structor class.  This is an XML parse-to-struct based on PHP's 
 * "xml" extension,
 * based on the bundled expat library.
 *
 * @author Bob Kelly <[email protected]>
 *
 */
class XML_Structor extends XML_Parser {
    // {{{ properties

    var $values;
    var $index;

    // }}}
    // {{{ constructor()

    function XML_Structor($charset = 'UTF-8') {
        $this->PEAR();
        $xp = @xml_parser_create($charset);
        if (is_resource($xp)) {
            $this->parser = $xp;
        }
    }

    // }}}
    
    // {{{ struct()

    function struct() {
	    if (!is_resource($this->fp)) {
	        return new XML_Parser_Error("no input");
	    }
	    if (!is_resource($this->parser)) {
	        return new XML_Parser_Error("no parser");
	    }
    
        while ( ! feof ( $this->fp ) ){
            $data .= fgets ($this->fp, 2048 );
        }
        fclose ( $this->fp);
	    if ( ! @xml_parse_into_struct($this->parser, $data, $this->vals, $this->index) ){
            return false;
	    }
	    return true;
    }

    // }}}

    // {{{ retrieveData()
    /** retrieveData
        seeks a TAG and VALUE combination in an
	XML values array and returns all relatives
        of that discrete data
    */
    function retrieveData ( $tag, $value ) {
        for ( $i = 0; $i < count ( $this->vals ) ; $i++ ) {
            if ( $this->vals[$i][value] == $value 
                && $this->vals[$i][tag] = $tag) {
                $data = $this->getRelatives ( $i );
                return ( $data ) ;
            }
        }
        return ( false);
    }
    // }}}

    // {{{ getRelative()
    /** getRelatives
        seeks the index of a XML value array and returns all relatives
        of that discrete data
    */
    function getRelatives ( $num ) {
        $parentTag = $this->vals[$num-1][tag];
        for ( $i = $num-1 ; $i < count ( $this->vals ) ; $i++ ){
            if ( $this->vals[$i]["tag"] == $parentTag && $this->vals[$i]["type"] == "close" ) {
                $upperLimit = $i;
                break;
            }
        }
    
        for ( $i = $num-1 ; $i >  0 ; $i-- ){
            if ( $this->vals[$i][tag] == $parentTag 
                && $this->vals[$i][type] == "open" ) {
                $lowerLimit = $i;
                break;
            }
        }
    
        for ( $i = $lowerLimit; $i < $upperLimit ; $i++ ){
            if ( $this->vals[$i][tag] != $parentTag
                && $this->vals[$num][level] == $this->vals[$i][level]
                && "" != trim ( $this->vals[$i][value] ) ) {
                $key = $this->vals[$i][tag];
                $val = $this->vals[$i][value];
                $data[$key] = $val;
            }
        }
    
        if ( $lowerLimit != 0 ) {
            $data = array_merge ( $data , $this->getRelatives ( $lowerLimit ));
        }
        $data = array_merge ( $data , $this->getChildren ( $num ));
        return ( $data );
    }
    // }}}

    // getChildren
    /** getChildren
        TO BE DONE
    */
    function getChildren ( $num ) {
        return (array ());
    }
}
?>
dbcon.php (application/octet-stream, 518 B)
<?php

// how to use dbConnector.php
    require_once ( "DB/dbConnector.php" ); 

    // "foobar" is the DATABASE NAME you wish to 
    // connect to 
    $dbcon = new dbConnector ( "foobar" );
    // you may use whatever variable suits you

    $db = DB::connect ( $dbcon-DSN );

    echo "<b>". $dbcon->DSN ."</b> is the string in which you connect to the database.<P>";
    echo "You pass this string to the \$db = DB::connect( \$dbcon->DSN ) ) line.<P>";
    echo "This works the same for Oracle, MySQL, ODBC.";
?>