Support Joomla!

Joomla! 1.5 Documentation

Packages

Package: Joomla-Framework

Developer Network License

The Joomla! Developer Network content is © copyright 2006 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution- NonCommercial- ShareAlike 2.5
Source code for file /joomla/database/database/mysqli.php

Documentation is available at mysqli.php

  1. <?php
  2. /**
  3. * @version        $Id: mysqli.php 6748 2007-03-01 22:49:19Z hackwar $
  4. * @package        Joomla.Framework
  5. * @subpackage    Database
  6. * @copyright    Copyright (C) 2005 - 2007 Open Source Matters. All rights reserved.
  7. * @license        GNU/GPL, see LICENSE.php
  8. *  Joomla! is free software. This version may have been modified pursuant
  9. *  to the GNU General Public License, and as distributed it includes or
  10. *  is derivative of works licensed under the GNU General Public License or
  11. *  other free or open source software licenses.
  12. *  See COPYRIGHT.php for copyright notices and details.
  13. */
  14.  
  15. // Check to ensure this file is within the rest of the framework
  16. defined('JPATH_BASE') or die();
  17.  
  18. /**
  19.  * MySQLi database driver
  20.  *
  21.  * @package        Joomla.Framework
  22.  * @subpackage    Database
  23.  * @since        1.0
  24.  */
  25. class JDatabaseMySQLi extends JDatabase
  26. {
  27.     /** @var string The database driver name */
  28.     var $name            = 'mysqli';
  29.     /** @var string The null/zero date string */
  30.     var $_nullDate        = '0000-00-00 00:00:00';
  31.     /** @var string Quote for named objects */
  32.     var $_nameQuote        = '`';
  33.  
  34.     /**
  35.     * Database object constructor
  36.     * @param string Database host
  37.     * @param string Database user name
  38.     * @param string Database user password
  39.     * @param string Database name
  40.     * @param string Common prefix for all tables
  41.     */
  42.     function __construct( $host='localhost', $user, $pass, $db='', $table_prefix='')
  43.     {
  44.         // Unlike mysql_connect(), mysqli_connect() takes the port and socket
  45.         // as separate arguments. Therefore, we have to extract them from the
  46.         // host string.
  47.         $port    = NULL;
  48.         $socket    = NULL;
  49.         $targetSlot = substr( strstr( $host, ":" ), 1 );
  50.         if (!empty( $targetSlot )) {
  51.             // Get the port number or socket name
  52.             if (is_numeric( $targetSlot ))
  53.                 $port    = $targetSlot;
  54.             else
  55.                 $socket    = $targetSlot;
  56.  
  57.             // Extract the host name only
  58.             $host = substr( $host, 0, strlen( $host ) - (strlen( $targetSlot ) + 1) );
  59.             // This will take care of the following notation: ":3306"
  60.             if($host == '')
  61.                 $host = 'localhost';
  62.         }
  63.  
  64.         // perform a number of fatality checks, then die gracefully
  65.         if (!function_exists( 'mysqli_connect' )) {
  66.             $this->_errorNum = 1;
  67.             $this->_errorMsg = 'The MySQL adapter "mysqli" is not available.';
  68.             return;
  69.         }
  70.         if (!($this->_resource = @mysqli_connect($host, $user, $pass, NULL, $port, $socket))) {
  71.             $this->_errorNum = 2;
  72.             $this->_errorMsg = 'Could not connect to MySQL';
  73.             return;
  74.         }
  75.         if ($db != '' && !mysqli_select_db($this->_resource, $db)) {
  76.             $this->_errorNum = 3;
  77.             $this->_errorMsg = 'Could not connect to database';
  78.             return;
  79.         }
  80.  
  81.         // if running mysql 5, set sql-mode to mysql40 - thereby circumventing strict mode problems
  82.         if ( strpos( $this->getVersion(), '5' ) === 0 ) {
  83.             $this->setQuery( "SET sql_mode = 'MYSQL40'" );
  84.             $this->query();
  85.         }
  86.  
  87.         parent::__construct($host, $user, $pass, $db, $table_prefix);
  88.     }
  89.  
  90.     /**
  91.      * Database object destructor
  92.      *
  93.      * @return boolean 
  94.      * @since 1.5
  95.      */
  96.     function __destruct()
  97.     {
  98.         // mysqli does not persist connections, so let's make sure it's closed
  99.         return @mysqli_close($this->_resource);
  100.     }
  101.  
  102.     function _parseHost( $host )
  103.     {
  104.  
  105.     }
  106.  
  107.     /**
  108.      * Determines UTF support
  109.      * @return boolean True - UTF is supported
  110.      */
  111.     function hasUTF()
  112.     {
  113.         $verParts = explode( '.', $this->getVersion() );
  114.         return ($verParts[0] == 5 || ($verParts[0] == 4 && $verParts[1] == 1 && (int)$verParts[2] >= 2));
  115.     }
  116.  
  117.     /**
  118.      * Custom settings for UTF support
  119.      */
  120.     function setUTF()
  121.     {
  122.         mysqli_query( $this->_resource, "SET NAMES 'utf8'" );
  123.     }
  124.  
  125.     /**
  126.     * Get a database escaped string
  127.     * @return string 
  128.     */
  129.     function getEscaped( $text )
  130.     {
  131.         return mysqli_real_escape_string( $this->_resource, $text );
  132.     }
  133.  
  134.     /**
  135.     * Execute the query
  136.     * @return mixed A database resource if successful, FALSE if not.
  137.     */
  138.     function query()
  139.     {
  140.         if (!is_object($this->_resource)) {
  141.             return false;
  142.         }
  143.  
  144.         if ($this->_limit > 0 || $this->_offset > 0) {
  145.             $this->_sql .= ' LIMIT '.$this->_offset.', '.$this->_limit;
  146.         }
  147.         if ($this->_debug) {
  148.             $this->_ticker++;
  149.             $this->_log[] = $this->_sql;
  150.         }
  151.         $this->_errorNum = 0;
  152.         $this->_errorMsg = '';
  153.         $this->_cursor = mysqli_query( $this->_resource, $this->_sql );
  154.  
  155.         if (!$this->_cursor)
  156.         {
  157.             $this->_errorNum = mysqli_errno( $this->_resource );
  158.             $this->_errorMsg = mysqli_error( $this->_resource ) . " SQL=$this->_sql";
  159.  
  160.             if ($this->_debug) {
  161.                 JError::raiseError('joomla.database:'.$this->_errorNum, 'JDatabaseMySQLi::query: '.$this->_errorMsg );
  162.             }
  163.             return false;
  164.         }
  165.         return $this->_cursor;
  166.     }
  167.  
  168.     /**
  169.      * @return int The number of affected rows in the previous operation
  170.      * @since 1.0.5
  171.      */
  172.     function getAffectedRows()
  173.     {
  174.         return mysqli_affected_rows( $this->_resource );
  175.     }
  176.  
  177.    /**
  178.     * Execute a batch query
  179.     * @return mixed A database resource if successful, FALSE if not.
  180.     */
  181.     function queryBatch( $abort_on_error=true, $p_transaction_safe = false)
  182.     {
  183.         $this->_errorNum = 0;
  184.         $this->_errorMsg = '';
  185.         if ($p_transaction_safe) {
  186.             $si = mysqli_get_server_info();
  187.             preg_match_all( "/(\d+)\.(\d+)\.(\d+)/i", $si, $m );
  188.             if ($m[1] >= 4) {
  189.                 $this->_sql = 'START TRANSACTION;' . $this->_sql . '; COMMIT;';
  190.             } else if ($m[2] >= 23 && $m[3] >= 19) {
  191.                 $this->_sql = 'BEGIN WORK;' . $this->_sql . '; COMMIT;';
  192.             } else if ($m[2] >= 23 && $m[3] >= 17) {
  193.                 $this->_sql = 'BEGIN;' . $this->_sql . '; COMMIT;';
  194.             }
  195.         }
  196.         $query_split = preg_split ("/[;]+/", $this->_sql);
  197.         $error = 0;
  198.         foreach ($query_split as $command_line) {
  199.             $command_line = trim( $command_line );
  200.             if ($command_line != '') {
  201.                 $this->_cursor = mysqli_query( $command_line, $this->_resource );
  202.                 if (!$this->_cursor) {
  203.                     $error = 1;
  204.                     $this->_errorNum .= mysqli_errno( $this->_resource ) . ' ';
  205.                     $this->_errorMsg .= mysqli_error( $this->_resource )." SQL=$command_line <br />";
  206.                     if ($abort_on_error) {
  207.                         return $this->_cursor;
  208.                     }
  209.                 }
  210.             }
  211.         }
  212.         return $error ? false : true;
  213.     }
  214.  
  215.     /**
  216.     * Diagnostic function
  217.     */
  218.     function explain()
  219.     {
  220.         $temp = $this->_sql;
  221.         $this->_sql = "EXPLAIN $this->_sql";
  222.         $this->query();
  223.  
  224.         if (!($cur = $this->query())) {
  225.             return null;
  226.         }
  227.         $first = true;
  228.  
  229.         $buffer = '<table id="explain-sql">';
  230.         $buffer .= '<thead><tr><td colspan="99">'.$this->getQuery().'</td></tr>';
  231.         while ($row = mysqli_fetch_assoc( $cur )) {
  232.             if ($first) {
  233.                 $buffer .= '<tr>';
  234.                 foreach ($row as $k=>$v) {
  235.                     $buffer .= '<th>'.$k.'</th>';
  236.                 }
  237.                 $buffer .= '</tr>';
  238.                 $first = false;
  239.             }
  240.             $buffer .= '</thead><tbody><tr>';
  241.             foreach ($row as $k=>$v) {
  242.                 $buffer .= '<td>'.$v.'</td>';
  243.             }
  244.             $buffer .= '</tr>';
  245.         }
  246.         $buffer .= '</tbody></table>';
  247.         mysqli_free_result( $cur );
  248.  
  249.         $this->_sql = $temp;
  250.  
  251.         return $buffer;
  252.     }
  253.     /**
  254.     * @return int The number of rows returned from the most recent query.
  255.     */
  256.     function getNumRows( $cur=null )
  257.     {
  258.         return mysqli_num_rows( $cur ? $cur : $this->_cursor );
  259.     }
  260.  
  261.     /**
  262.     * This method loads the first field of the first row returned by the query.
  263.     *
  264.     * @return The value returned in the query or null if the query failed.
  265.     */
  266.     function loadResult()
  267.     {
  268.         if (!($cur = $this->query())) {
  269.             return null;
  270.         }
  271.         $ret = null;
  272.         if ($row = mysqli_fetch_row( $cur )) {
  273.             $ret = $row[0];
  274.         }
  275.         mysqli_free_result( $cur );
  276.         return $ret;
  277.     }
  278.     /**
  279.     * Load an array of single field results into an array
  280.     */
  281.     function loadResultArray($numinarray = 0)
  282.     {
  283.         if (!($cur = $this->query())) {
  284.             return null;
  285.         }
  286.         $array = array();
  287.         while ($row = mysqli_fetch_row( $cur )) {
  288.             $array[] = $row[$numinarray];
  289.         }
  290.         mysqli_free_result( $cur );
  291.         return $array;
  292.     }
  293.  
  294.     /**
  295.     * Fetch a result row as an associative array
  296.     *
  297.     * return array
  298.     */
  299.     function loadAssoc()
  300.     {
  301.         if (!($cur = $this->query())) {
  302.             return null;
  303.         }
  304.         $ret = null;
  305.         if ($array = mysqli_fetch_assoc( $cur )) {
  306.             $ret = $array;
  307.         }
  308.         mysqli_free_result( $cur );
  309.         return $ret;
  310.     }
  311.  
  312.     /**
  313.     * Load a assoc list of database rows
  314.     * @param string The field name of a primary key
  315.     * @return array If <var>key</var> is empty as sequential list of returned records.
  316.     */
  317.     function loadAssocList( $key='' )
  318.     {
  319.         if (!($cur = $this->query())) {
  320.             return null;
  321.         }
  322.         $array = array();
  323.         while ($row = mysqli_fetch_assoc( $cur )) {
  324.             if ($key) {
  325.                 $array[$row[$key]] = $row;
  326.             } else {
  327.                 $array[] = $row;
  328.             }
  329.         }
  330.         mysqli_free_result( $cur );
  331.         return $array;
  332.     }
  333.     /**
  334.     * This global function loads the first row of a query into an object
  335.     *
  336.     * return object
  337.     */
  338.     function loadObject( )
  339.     {
  340.         if (!($cur = $this->query())) {
  341.             return null;
  342.         }
  343.         $ret = null;
  344.         if ($object = mysqli_fetch_object( $cur )) {
  345.             $ret = $object;
  346.         }
  347.         mysqli_free_result( $cur );
  348.         return $ret;
  349.     }
  350.     /**
  351.     * Load a list of database objects
  352.     * @param string The field name of a primary key
  353.     * @return array If <var>key</var> is empty as sequential list of returned records.
  354.     *  If <var>key</var> is not empty then the returned array is indexed by the value
  355.     *  the database key.  Returns <var>null</var> if the query fails.
  356.     */
  357.     function loadObjectList( $key='' )
  358.     {
  359.         if (!($cur = $this->query())) {
  360.             return null;
  361.         }
  362.         $array = array();
  363.         while ($row = mysqli_fetch_object( $cur )) {
  364.             if ($key) {
  365.                 $array[$row->$key] = $row;
  366.             } else {
  367.                 $array[] = $row;
  368.             }
  369.         }
  370.         mysqli_free_result( $cur );
  371.         return $array;
  372.     }
  373.     /**
  374.     * @return The first row of the query.
  375.     */
  376.     function loadRow()
  377.     {
  378.         if (!($cur = $this->query())) {
  379.             return null;
  380.         }
  381.         $ret = null;
  382.         if ($row = mysqli_fetch_row( $cur )) {
  383.             $ret = $row;
  384.         }
  385.         mysqli_free_result( $cur );
  386.         return $ret;
  387.     }
  388.     /**
  389.     * Load a list of database rows (numeric column indexing)
  390.     * @param string The field name of a primary key
  391.     * @return array If <var>key</var> is empty as sequential list of returned records.
  392.     *  If <var>key</var> is not empty then the returned array is indexed by the value
  393.     *  the database key.  Returns <var>null</var> if the query fails.
  394.     */
  395.     function loadRowList( $key=null )
  396.     {
  397.         if (!($cur = $this->query())) {
  398.             return null;
  399.         }
  400.         $array = array();
  401.         while ($row = mysqli_fetch_row( $cur )) {
  402.             if ($key !== null) {
  403.                 $array[$row[$key]] = $row;
  404.             } else {
  405.                 $array[] = $row;
  406.             }
  407.         }
  408.         mysqli_free_result( $cur );
  409.         return $array;
  410.     }
  411.     /**
  412.      * Inserts a row into a table based on an objects properties
  413.      * @param    string    The name of the table
  414.      * @param    object    An object whose properties match table fields
  415.      * @param    string    The name of the primary key. If provided the object property is updated.
  416.      */
  417.     function insertObject( $table, &$object, $keyName = NULL )
  418.     {
  419.         $fmtsql = "INSERT INTO $table ( %s ) VALUES ( %s ) ";
  420.         $fields = array();
  421.         foreach (get_object_vars( $object ) as $k => $v) {
  422.             if (is_array($v) or is_object($v) or $v === NULL) {
  423.                 continue;
  424.             }
  425.             if ($k[0] == '_') { // internal field
  426.                 continue;
  427.             }
  428.             $fields[] = $this->nameQuote( $k );;
  429.             $values[] = $this->isQuoted( $k ) ? $this->Quote( $v ) : $v;
  430.         }
  431.         $this->setQuery( sprintf( $fmtsql, implode( ",", $fields ) ,  implode( ",", $values ) ) );
  432.         if (!$this->query()) {
  433.             return false;
  434.         }
  435.         $id = mysqli_insert_id( $this->_resource );
  436.         if ($keyName && $id) {
  437.             $object->$keyName = $id;
  438.         }
  439.         return true;
  440.     }
  441.  
  442.     /**
  443.      * Document::db_updateObject()
  444.      * @param [type] $updateNulls 
  445.      */
  446.     function updateObject( $table, &$object, $keyName, $updateNulls=true )
  447.     {
  448.         $fmtsql = "UPDATE $table SET %s WHERE %s";
  449.         $tmp = array();
  450.         foreach (get_object_vars( $object ) as $k => $v) {
  451.             if( is_array($v) or is_object($v) or $k[0] == '_' ) { // internal or NA field
  452.                 continue;
  453.             }
  454.             if( $k == $keyName ) { // PK not to be updated
  455.                 $where = $keyName . '=' . $this->Quote( $v );
  456.                 continue;
  457.             }
  458.             if ($v === null)
  459.             {
  460.                 if ($updateNulls) {
  461.                     $val = 'NULL';
  462.                 } else {
  463.                     continue;
  464.                 }
  465.             } else {
  466.                 $val = $this->isQuoted( $k ) ? $this->Quote( $v ) : $v;
  467.             }
  468.             $tmp[] = $this->nameQuote( $k ) . '=' . $val;
  469.         }
  470.         $this->setQuery( sprintf( $fmtsql, implode( ",", $tmp ) , $where ) );
  471.         return $this->query();
  472.     }
  473.  
  474.     function insertid()
  475.     {
  476.         return mysqli_insert_id( $this->_resource );
  477.     }
  478.  
  479.     /**
  480.      * Assumes database collation in use by sampling one text field in one table
  481.      * @return string Collation in use
  482.      */
  483.     function getCollation ()
  484.     {
  485.         if ( $this->hasUTF() ) {
  486.             $this->setQuery( 'SHOW FULL COLUMNS FROM #__content' );
  487.             $array = $this->loadAssocList();
  488.             return $array['4']['Collation'];
  489.         } else {
  490.             return "N/A (mySQL < 4.1.2)";
  491.         }
  492.     }
  493.  
  494.     function getVersion()
  495.     {
  496.         return mysqli_get_server_info( $this->_resource );
  497.     }
  498.  
  499.     /**
  500.      * @return array A list of all the tables in the database
  501.      */
  502.     function getTableList()
  503.     {
  504.         $this->setQuery( 'SHOW TABLES' );
  505.         return $this->loadResultArray();
  506.     }
  507.     /**
  508.      * @param array A list of table names
  509.      * @return array A list the create SQL for the tables
  510.      */
  511.     function getTableCreate( $tables )
  512.     {
  513.         $result = array();
  514.  
  515.         foreach ($tables as $tblval) {
  516.             $this->setQuery( 'SHOW CREATE table ' . $this->getEscaped( $tblval ) );
  517.             $rows = $this->loadRowList();
  518.             foreach ($rows as $row) {
  519.                 $result[$tblval] = $row[1];
  520.             }
  521.         }
  522.  
  523.         return $result;
  524.     }
  525.     /**
  526.      * @param array A list of table names
  527.      * @return array An array of fields by table
  528.      */
  529.     function getTableFields( $tables )
  530.     {
  531.         $result = array();
  532.  
  533.         foreach ($tables as $tblval) {
  534.             $this->setQuery( 'SHOW FIELDS FROM ' . $tblval );
  535.             $fields = $this->loadObjectList();
  536.             foreach ($fields as $field) {
  537.                 $result[$tblval][$field->Field] = preg_replace("/[(0-9)]/",'', $field->Type );
  538.             }
  539.         }
  540.  
  541.         return $result;
  542.     }
  543. }

Documentation generated on Mon, 05 Mar 2007 21:11:59 +0000 by phpDocumentor 1.3.1