Source for file DataBaseConnector.class.php

  1. <?php
  2.   /**
  3.     * This class encapsulates all of the functions for interacting with a database.
  4.     * @author Richard Sharp
  5.     * @copyright 2006-2010
  6.     * @version 3.0
  7.     * @package Database
  8. */
  9. {
  10.     
  11.     /********************************* Public Variables **********************************************/
  12.     
  13.     /**
  14.      * Gets or sets whether or not to automaticllay update the Modified and Created fields in the  table.
  15.      *    @var boolean 
  16.      */
  17.     var $bUpdateTimestamps=true;
  18.     
  19.     /**
  20.      * Gets or sets the name of the database.
  21.      *    @var string 
  22.      */
  23.     var $sDatabase="";
  24.     
  25.     /**
  26.      * Gets or sets the hostname of the database. If not provided, localhost will be assumed.
  27.      *    @var string 
  28.      */
  29.     var $sHost="";
  30.     
  31.     /**
  32.     * If a value is provided, all errors will be written to this filename if possible.
  33.     * @var string 
  34.     */
  35.     var $sErrorLog="";
  36.     
  37.     /**
  38.      * Gets the SQL text of the last query processed.
  39.      *    @var string 
  40.      */
  41.     var $sLastQuery="";
  42.     
  43.     /**
  44.      * Gets or sets the database password.
  45.      *    @var string 
  46.      */
  47.     var $sPassword="";
  48.     
  49.     /**
  50.      * Gets or sets the database username.
  51.      *    @var string 
  52.      */
  53.     var $sUser="";
  54.     
  55.     /********************************* Private Variables **********************************************/
  56.     /**
  57.     * @access private
  58.     */
  59.     var $_objConnection;
  60.     
  61.     
  62.     /********************************* Public Methods **********************************************/
  63.     
  64.      /**
  65.      * Constructor for the class.
  66.      * @param string The database username.
  67.      * @param string The database password.
  68.      * @param string The database name.
  69.      * @param string The database host.
  70.      * @return void 
  71.      */ 
  72.     function DataBaseConnector($User="",$Password="",$Database="",$Host="")
  73.     {
  74.         if($Host!=""$this->sHost=$Host;
  75.         elseif(defined("DBHost")) $this->sHost=DBHost;
  76.         else $this->sHost="localhost";
  77.         if($User!=""$this->sUser=$User;
  78.         elseif(defined("DBUser")) $this->sUser=DBUser;
  79.         if($Password!=""$this->sPassword=$Password;
  80.         elseif(defined("DBPass")) $this->sPassword=DBPass;
  81.         if($Database!=""$this->sDatabase=$Database;
  82.         elseif(defined("DBase")) $this->sDatabase=DBase;
  83.     }
  84.     
  85.     
  86.     /**
  87.     * Escapes the value to be placed in a field. This helps prevent problems with quotes, and also prevents
  88.     * SQL injection attacks.
  89.     * @param string The value to escape.
  90.     * @return string Escapped string.
  91.     */
  92.     function Escape($value)
  93.     {
  94.         if($this->TestConnection())
  95.         {
  96.             return(mysql_real_escape_string($value,$this->_objConnection));
  97.         }
  98.         else return(false);
  99.     }
  100.     
  101.     /**
  102.     * Returns the number of rows affected by the last query
  103.     * @return int The number of affected rows.
  104.     */
  105.     function GetAffectedRows()
  106.     {
  107.         if($this->TestConnection())
  108.         {
  109.             return(@mysql_affected_rows($this->_objConnection));
  110.         }
  111.     }
  112.     
  113.      /**
  114.      * Gets the text of the last error, if any.
  115.      * @return string The text of the last error, if any.
  116.      */ 
  117.     function GetLastError()
  118.     {
  119.         if($this->TestConnection())
  120.         {
  121.             return(mysql_error($this->_objConnection));
  122.         }
  123.     }
  124.     
  125.     /**
  126.      * Inserts a record into the database.
  127.      * @param string The name of the table. Returns the insert auto-incremented ID.
  128.      * @param array An array of the fields/values to insert. Each element key is the column name for the table, and the value is the value to insert. Ex: $fields["FirstName"]="John";
  129.      * @return mixed The inserted row ID on success, false on fail.
  130.      */ 
  131.     function Insert($sTable,$aFields)
  132.     {
  133.         //validate the passed information
  134.         if(!$sTable || ($sTable==''))
  135.         {
  136.             $this->_logError("Attempted to insert record with missing table name.");
  137.             return false;
  138.         }
  139.         if(!is_array($aFields)) 
  140.         {
  141.             $this->_logError("Attempted to insert record with missing fields.");
  142.             return(false);
  143.         }
  144.         if($this->TestConnection())
  145.         {
  146.             foreach($aFields as $sKey => $sValue)
  147.             {
  148.                 $aKeys[]=$sKey;
  149.                 
  150.                 //if this is a password value, don't escape
  151.                 if(substr_count($sValue,"password(")>0$aValues[]=$sValue;
  152.                 //if the value is NULL, use "NULL"
  153.                 elseif(strtolower($sValue)=="null"$aValues[]="NULL";
  154.                 //escape the value
  155.                 else $aValues[]='"'.mysql_real_escape_string($sValue,$this->_objConnection).'"';
  156.             }
  157.             
  158.             //build the query
  159.             $sQuery='INSERT INTO '.$sTable.' ('.implode(",",$aKeys);
  160.             if($this->bUpdateTimestamps$sQuery.=',Modified,Created';
  161.             $sQuery.=') VALUES ('.implode(',',$aValues);
  162.             if($this->bUpdateTimestamps$sQuery.=',now(),now()';
  163.             $sQuery.=')';
  164.             $this->sLastQuery=$sQuery;
  165.             
  166.             //run the query
  167.             $ok=mysql_query($sQuery,$this->_objConnection);
  168.             if($okreturn(mysql_insert_id($this->_objConnection));
  169.             else 
  170.             {
  171.                 $this->_logError();
  172.                 return(false);
  173.             }
  174.         }
  175.         else return(false);
  176.     }
  177.     
  178.      /**
  179.      * Runs a query on the database that does not expect any return.
  180.      * @param string The query to run.
  181.      * @return mixed The result object of the query.
  182.      */ 
  183.     function Query($sQuery)
  184.     {
  185.         
  186.         if(!$sQuery || ($sQuery==''))
  187.         {
  188.             $this->_logError("Attempted to run a blank raw query.");
  189.             return false;
  190.         }
  191.         if($this->TestConnection())
  192.         {
  193.             $this->sLastQuery=$sQuery;
  194.             $oResult=mysql_query($sQuery,$this->_objConnection);
  195.             if(!$oResult$this->_logError();
  196.             return($oResult);
  197.         }
  198.     }
  199.     
  200.      /**
  201.      * Performs an Update query on the database. Returns success or failure.
  202.      * @param string The name of the table.
  203.      * @param array An associative array of the fields to update. Each element's key is the column name in the table, and the value of the element is the value to update.
  204.      * @param boolean Whether or not to use delayed replace. Default false.
  205.      * @return bool Returns true on success, false on failure.
  206.      */ 
  207.     function Replace($sTable,$aFields,$bDelayed=false)
  208.     {
  209.         //check for required information
  210.         if(!$sTable || ($sTable==''))
  211.         {
  212.             $this->_logError("Attempted to replace records with missing table name.");
  213.             return false;
  214.         }
  215.         if(!is_array($aFields)) 
  216.         {
  217.             $this->_logError("Attempted to replace records with missing fields.");
  218.             return(false);
  219.         }
  220.         
  221.         if($this->TestConnection())
  222.         {
  223.             foreach($aFields as $sKey => $sValue)
  224.             {
  225.                 $aKeys[]=$sKey;
  226.                 
  227.                 //if this is a password value, don't escape
  228.                 if(substr_count($sValue,"password(")>0$aValues[]=$sValue;
  229.                 //if the value is NULL, use "NULL"
  230.                 elseif(strtolower($sValue)=="null"$aValues[]="NULL";
  231.                 //escape the value
  232.                 else $aValues[]='"'.mysql_real_escape_string($sValue,$this->_objConnection).'"';
  233.             }
  234.             
  235.             //build the query
  236.             $sQuery='REPLACE'.($bDelayed?" DELAYED":"").' INTO '.$sTable.' ('.implode(",",$aKeys);
  237.             if($this->bUpdateTimestamps$sQuery.=',Modified,Created';
  238.             $sQuery.=') VALUES ('.implode(',',$aValues);
  239.             if($this->bUpdateTimestamps$sQuery.=',now(),now()';
  240.             $sQuery.=')';
  241.             $this->sLastQuery=$sQuery;
  242.             
  243.             //return the query
  244.             $ok=mysql_query($sQuery,$this->_objConnection);
  245.             if($okreturn(true);
  246.             else 
  247.             {
  248.                 $this->_logError();
  249.                 return(false);
  250.             }
  251.         }
  252.         else return(false);
  253.     }
  254.     
  255.      /**
  256.      * Runs a Select query on the database. Returns an associative array of rows.
  257.      * @param string The SQL query to run.
  258.      * @return mixed On success, a numbered array of result rows. Each array element is an associative array of the results. False on failure.
  259.      */ 
  260.     function Select($sQuery)
  261.     {
  262.         //check that a query was sent
  263.         if(!$sQuery || ($sQuery==''))
  264.         {
  265.             $this->_logError("Attempted to run a Select with no query.");
  266.             return false;
  267.         }
  268.         
  269.         if($this->TestConnection())
  270.         {
  271.             $this->sLastQuery=$sQuery;
  272.             $oResult=mysql_query($sQuery,$this->_objConnection);
  273.             if($oResult)
  274.             {
  275.                 while($aRow=mysql_fetch_array($oResult,MYSQL_ASSOC))
  276.                 {
  277.                     //loop through each value and strip out slashes
  278.                     unset($this_row);
  279.                     foreach($aRow as $sKey => $sValue$this_row[$sKey]=stripslashes($sValue);
  280.                     $aReturn[]=$this_row;
  281.                 }
  282.             }
  283.             else $this->_logError();
  284.         }
  285.         else return(false);
  286.         return($aReturn);
  287.     }
  288.     
  289.      /**
  290.      * Tests to make sure the connection to the database is open, and if not, attempts to re-open the connection. This prevents unnecessary connections to the database.
  291.      * @return bool 
  292.      */ 
  293.     function TestConnection()
  294.     {
  295.         //if no connection resource, attempt to connect
  296.         if(!$this->_objConnection$this->_connect();
  297.         
  298.         //if still no conenction resource, connection failed
  299.         if(!$this->_objConnectionreturn false;
  300.         
  301.         //ping the conection to test and reactivate if necessary
  302.         if(!mysql_ping($this->_objConnection)) return(false);
  303.         
  304.         return(true);
  305.     }
  306.     
  307.      /**
  308.      * Performs an Update query on the database. Returns success or failure.
  309.      * @param string The name of the table.
  310.      * @param array An associative array of the fields to update. Each element's key is the column name in the table, and the value of the element is the value to update.
  311.      * @param string The WHERE clause of the query. Required. Use "1=1" to update all fields.
  312.      * @param int Optional. The limit to the number of rows that should be affected.
  313.      * @return bool True on success, false on failure.
  314.      */ 
  315.     function Update($sTable,$aFields,$sCondition,$iLimit=0)
  316.     {
  317.         //check for required information
  318.         if(!$sTable || ($sTable==''))
  319.         {
  320.             $this->_logError("Attempted to update records with missing table name.");
  321.             return false;
  322.         }
  323.         if(!is_array($aFields)) 
  324.         {
  325.             $this->_logError("Attempted to update records with missing fields.");
  326.             return(false);
  327.         }
  328.         if(!$sCondition || ($sCondition==''))
  329.         {
  330.             $this->_logError("Attempted to update records with missing condition.");
  331.             return false;
  332.         }
  333.         
  334.         if($this->TestConnection())
  335.         {
  336.             foreach($aFields as $sKey => $sValue
  337.             {                
  338.                 //if this is a password value, don't escape
  339.                 if(substr_count($sValue,"password(")>0$aUpdates[]=$sKey.'='.$sValue;
  340.                 //if the value is NULL, use "NULL"
  341.                 elseif(strtolower($sValue)=="null"$aValues[]="NULL"
  342.                 //escape the value
  343.                 else $aUpdates[]=$sKey.'="'.mysql_real_escape_string($sValue,$this->_objConnection).'"';
  344.             }
  345.             
  346.             //build the query
  347.             $sQuery='UPDATE '.$sTable.' SET '.implode(",",$aUpdates);
  348.             if($this->bUpdateTimestamps$sQuery.=',Modified=now() ';
  349.             $sQuery.=' WHERE '.$sCondition;
  350.             if($iLimit$sQuery.=' LIMIT '.$iLimit;
  351.             $this->sLastQuery=$sQuery;
  352.             
  353.             //run the query
  354.             $ok=mysql_query($sQuery,$this->_objConnection);
  355.             if(!$ok$this->_logError();
  356.             return($ok);
  357.         }
  358.     }
  359.     
  360.     /************ Private Functions *************/
  361.     
  362.     /**
  363.      * Connects to the database.
  364.      * @access private
  365.      * @return boolean True if successful, otherwise false.
  366.      */ 
  367.     function _connect()
  368.     {
  369.         //make sure that the connection authentication values have been set
  370.         if(    !$this->sHost ||
  371.             !$this->sUser ||
  372.             !$this->sPassword ||
  373.             !$this->sDatabase)
  374.         {
  375.             $this->_logError("Attempted to connect with missing authentication information.");
  376.             return false;
  377.         }
  378.         
  379.         //connect to the database
  380.         $_objConnection=mysql_connect($this->sHost,$this->sUser,$this->sPassword);
  381.         
  382.         //if connected, select the database
  383.         if($_objConnection)
  384.         {
  385.             $bDatabase=mysql_select_db($this->sDatabase,$_objConnection);
  386.             if($bDatabase)
  387.             {
  388.                 $this->_objConnection=$_objConnection;
  389.                 return true;
  390.             }
  391.             else return false;
  392.         }
  393.         else return false;
  394.     }
  395.     
  396.     /**
  397.      * Logs errors to an external text error log. Only if sErrorLog is set
  398.      * @access private
  399.      * @param string The message to store. If not set, the last query and database error will be stored.
  400.      * @return void 
  401.      */ 
  402.     function _logError($message)
  403.     {
  404.         if(!$this->sErrorLogreturn(true);
  405.         $file=@fopen($this->sErrorLog,"a");
  406.         if($file)
  407.         {
  408.             if(!$message$message=$this->sLastQuery."\n".$this->GetLastError();
  409.             $message=date("m/d/y H:i:s")."\n".$message."\n--------------------------------------------------------------------\n";
  410.             fputs($file,$message,strlen($message));
  411.             fclose($file);
  412.         }
  413.     }
  414. }
  415. ?>