Support Joomla!

Packages

Package: Joomla-Framework

License

Content on this site is copyright © 2005 - 2008 Open Source Matters Inc and can be used in accordance with the Joomla! Electronic Documentation License. Some parts of this website may be subject to other licenses.
Source code for file /joomla/database/database/mysqli.php

Documentation is available at mysqli.php

  1. <?php
  2. /**
  3. @version        $Id: mysqli.php 11316 2008-11-27 03:11:24Z ian $
  4. @package        Joomla.Framework
  5. @subpackage    Database
  6. @copyright    Copyright (C) 2005 - 2008 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.     /**
  28.      *  The database driver name
  29.      *
  30.      * @var string 
  31.      */
  32.     var $name            = 'mysqli';
  33.  
  34.     /**
  35.      * The null/zero date string
  36.      *
  37.      * @var string 
  38.      */
  39.     var $_nullDate        = '0000-00-00 00:00:00';
  40.  
  41.     /**
  42.      * Quote for named objects
  43.      *
  44.      * @var string 
  45.      */
  46.     var $_nameQuote        = '`';
  47.  
  48.     /**
  49.     * Database object constructor
  50.     *
  51.     * @access    public
  52.     * @param    array    List of options used to configure the connection
  53.     * @since    1.5
  54.     * @see        JDatabase
  55.     */
  56.     function __construct$options )
  57.     {
  58.         $host        array_key_exists('host'$options)    $options['host']        'localhost';
  59.         $user        array_key_exists('user'$options)    $options['user']        '';
  60.         $password    array_key_exists('password',$options)    $options['password']    '';
  61.         $database    array_key_exists('database',$options)    $options['database']    '';
  62.         $prefix        array_key_exists('prefix'$options)    $options['prefix']    'jos_';
  63.         $select        array_key_exists('select'$options)    $options['select']    true;
  64.  
  65.         // Unlike mysql_connect(), mysqli_connect() takes the port and socket
  66.         // as separate arguments. Therefore, we have to extract them from the
  67.         // host string.
  68.         $port    NULL;
  69.         $socket    NULL;
  70.         $targetSlot substrstrstr$host":" ));
  71.         if (!empty$targetSlot )) {
  72.             // Get the port number or socket name
  73.             if (is_numeric$targetSlot ))
  74.                 $port    $targetSlot;
  75.             else
  76.                 $socket    $targetSlot;
  77.  
  78.             // Extract the host name only
  79.             $host substr$host0strlen$host (strlen$targetSlot 1) );
  80.             // This will take care of the following notation: ":3306"
  81.             if($host == '')
  82.                 $host 'localhost';
  83.         }
  84.  
  85.         // perform a number of fatality checks, then return gracefully
  86.         if (!function_exists'mysqli_connect' )) {
  87.             $this->_errorNum = 1;
  88.             $this->_errorMsg = 'The MySQL adapter "mysqli" is not available.';
  89.             return;
  90.         }
  91.  
  92.         // connect to the server
  93.         if (!($this->_resource = @mysqli_connect($host$user$passwordNULL$port$socket))) {
  94.             $this->_errorNum = 2;
  95.             $this->_errorMsg = 'Could not connect to MySQL';
  96.             return;
  97.         }
  98.  
  99.         // finalize initialization
  100.         parent::__construct($options);
  101.  
  102.         // select the database
  103.         if $select {
  104.             $this->select($database);
  105.         }
  106.     }
  107.  
  108.     /**
  109.      * Database object destructor
  110.      *
  111.      * @return boolean 
  112.      * @since 1.5
  113.      */
  114.     function __destruct()
  115.     {
  116.         $return false;
  117.         if (is_resource($this->_resource)) {
  118.             $return mysqli_close($this->_resource);
  119.         }
  120.         return $return;
  121.     }
  122.  
  123.     /**
  124.      * Test to see if the MySQLi connector is available
  125.      *
  126.      * @static
  127.      * @access public
  128.      * @return boolean  True on success, false otherwise.
  129.      */
  130.     function test()
  131.     {
  132.         return (function_exists'mysqli_connect' ));
  133.     }
  134.  
  135.     /**
  136.      * Determines if the connection to the server is active.
  137.      *
  138.      * @access    public
  139.      * @return    boolean 
  140.      * @since    1.5
  141.      */
  142.     function connected()
  143.     {
  144.         return $this->_resource->ping();
  145.     }
  146.  
  147.     /**
  148.      * Select a database for use
  149.      *
  150.      * @access    public
  151.      * @param    string $database 
  152.      * @return    boolean True if the database has been successfully selected
  153.      * @since    1.5
  154.      */
  155.     function select($database)
  156.     {
  157.         if $database )
  158.         {
  159.             return false;
  160.         }
  161.  
  162.         if !mysqli_select_db($this->_resource$database)) {
  163.             $this->_errorNum = 3;
  164.             $this->_errorMsg = 'Could not connect to database';
  165.             return false;
  166.         }
  167.  
  168.         // if running mysql 5, set sql-mode to mysql40 - thereby circumventing strict mode problems
  169.         if strpos$this->getVersion()'5' === {
  170.             $this->setQuery"SET sql_mode = 'MYSQL40'" );
  171.             $this->query();
  172.         }
  173.  
  174.         return true;
  175.     }
  176.  
  177.     /**
  178.      * Determines UTF support
  179.      *
  180.      * @access public
  181.      * @return boolean True - UTF is supported
  182.      */
  183.     function hasUTF()
  184.     {
  185.         $verParts explode'.'$this->getVersion() );
  186.         return ($verParts[0== || ($verParts[0== && $verParts[1== && (int)$verParts[2>= 2));
  187.     }
  188.  
  189.     /**
  190.      * Custom settings for UTF support
  191.      *
  192.      * @access public
  193.      */
  194.     function setUTF()
  195.     {
  196.         mysqli_query$this->_resource"SET NAMES 'utf8'" );
  197.     }
  198.  
  199.     /**
  200.      * Get a database escaped string
  201.      *
  202.      * @param    string    The string to be escaped
  203.      * @param    boolean    Optional parameter to provide extra escaping
  204.      * @return    string 
  205.      * @access    public
  206.      * @abstract
  207.      */
  208.     function getEscaped$text$extra false )
  209.     {
  210.         $result mysqli_real_escape_string$this->_resource$text );
  211.         if ($extra{
  212.             $result addcslashes$result'%_' );
  213.         }
  214.         return $result;
  215.     }
  216.     /**
  217.     * Execute the query
  218.     *
  219.     * @access public
  220.     * @return mixed A database resource if successful, FALSE if not.
  221.     */
  222.     function query()
  223.     {
  224.         if (!is_object($this->_resource)) {
  225.             return false;
  226.         }
  227.  
  228.         // Take a local copy so that we don't modify the original query and cause issues later
  229.         $sql $this->_sql;
  230.         if ($this->_limit > || $this->_offset > 0{
  231.             $sql .= ' LIMIT '.$this->_offset.', '.$this->_limit;
  232.         }
  233.         if ($this->_debug{
  234.             $this->_ticker++;
  235.             $this->_log[$sql;
  236.         }
  237.         $this->_errorNum = 0;
  238.         $this->_errorMsg = '';
  239.         $this->_cursor = mysqli_query$this->_resource$sql );
  240.  
  241.         if (!$this->_cursor)
  242.         {
  243.             $this->_errorNum = mysqli_errno$this->_resource );
  244.             $this->_errorMsg = mysqli_error$this->_resource )." SQL=$sql";
  245.  
  246.             if ($this->_debug{
  247.                 JError::raiseError(500'JDatabaseMySQL::query: '.$this->_errorNum.' - '.$this->_errorMsg );
  248.             }
  249.             return false;
  250.         }
  251.         return $this->_cursor;
  252.     }
  253.  
  254.     /**
  255.      * Description
  256.      *
  257.      * @access public
  258.      * @return int The number of affected rows in the previous operation
  259.      * @since 1.0.5
  260.      */
  261.     function getAffectedRows()
  262.     {
  263.         return mysqli_affected_rows$this->_resource );
  264.     }
  265.  
  266.     /**
  267.     * Execute a batch query
  268.     *
  269.     * @access public
  270.     * @return mixed A database resource if successful, FALSE if not.
  271.     */
  272.     function queryBatch$abort_on_error=true$p_transaction_safe false)
  273.     {
  274.         $this->_errorNum = 0;
  275.         $this->_errorMsg = '';
  276.         if ($p_transaction_safe{
  277.             $this->_sql = rtrim($this->_sql"; \t\r\n\0");
  278.             $si $this->getVersion();
  279.             preg_match_all"/(\d+)\.(\d+)\.(\d+)/i"$si$m );
  280.             if ($m[1>= 4{
  281.                 $this->_sql = 'START TRANSACTION;' $this->_sql . '; COMMIT;';
  282.             else if ($m[2>= 23 && $m[3>= 19{
  283.                 $this->_sql = 'BEGIN WORK;' $this->_sql . '; COMMIT;';
  284.             else if ($m[2>= 23 && $m[3>= 17{
  285.                 $this->_sql = 'BEGIN;' $this->_sql . '; COMMIT;';
  286.             }
  287.         }
  288.         $query_split $this->splitSql($this->_sql);
  289.         $error 0;
  290.         foreach ($query_split as $command_line{
  291.             $command_line trim$command_line );
  292.             if ($command_line != ''{
  293.                 $this->_cursor = mysqli_query$this->_resource$command_line );
  294.                 if ($this->_debug{
  295.                     $this->_ticker++;
  296.                     $this->_log[$command_line;
  297.                 }
  298.                 if (!$this->_cursor{
  299.                     $error 1;
  300.                     $this->_errorNum .= mysqli_errno$this->_resource ' ';
  301.                     $this->_errorMsg .= mysqli_error$this->_resource )." SQL=$command_line <br />";
  302.                     if ($abort_on_error{
  303.                         return $this->_cursor;
  304.                     }
  305.                 }
  306.             }
  307.         }
  308.         return $error false true;
  309.     }
  310.  
  311.     /**
  312.      * Diagnostic function
  313.      *
  314.      * @access public
  315.      * @return    string 
  316.      */
  317.     function explain()
  318.     {
  319.         $temp $this->_sql;
  320.         $this->_sql = "EXPLAIN $this->_sql";
  321.  
  322.         if (!($cur $this->query())) {
  323.             return null;
  324.         }
  325.         $first true;
  326.  
  327.         $buffer '<table id="explain-sql">';
  328.         $buffer .= '<thead><tr><td colspan="99">'.$this->getQuery().'</td></tr>';
  329.         while ($row mysqli_fetch_assoc$cur )) {
  330.             if ($first{
  331.                 $buffer .= '<tr>';
  332.                 foreach ($row as $k=>$v{
  333.                     $buffer .= '<th>'.$k.'</th>';
  334.                 }
  335.                 $buffer .= '</tr>';
  336.                 $first false;
  337.             }
  338.             $buffer .= '</thead><tbody><tr>';
  339.             foreach ($row as $k=>$v{
  340.                 $buffer .= '<td>'.$v.'</td>';
  341.             }
  342.             $buffer .= '</tr>';
  343.         }
  344.         $buffer .= '</tbody></table>';
  345.         mysqli_free_result$cur );
  346.  
  347.         $this->_sql = $temp;
  348.  
  349.         return $buffer;
  350.     }
  351.  
  352.     /**
  353.      * Description
  354.      *
  355.      * @access public
  356.      * @return int The number of rows returned from the most recent query.
  357.      */
  358.     function getNumRows$cur=null )
  359.     {
  360.         return mysqli_num_rows$cur $cur $this->_cursor );
  361.     }
  362.  
  363.     /**
  364.     * This method loads the first field of the first row returned by the query.
  365.     *
  366.     * @access public
  367.     * @return The value returned in the query or null if the query failed.
  368.     */
  369.     function loadResult()
  370.     {
  371.         if (!($cur $this->query())) {
  372.             return null;
  373.         }
  374.         $ret null;
  375.         if ($row mysqli_fetch_row$cur )) {
  376.             $ret $row[0];
  377.         }
  378.         mysqli_free_result$cur );
  379.         return $ret;
  380.     }
  381.  
  382.     /**
  383.     * Load an array of single field results into an array
  384.     *
  385.     * @access public
  386.     */
  387.     function loadResultArray($numinarray 0)
  388.     {
  389.         if (!($cur $this->query())) {
  390.             return null;
  391.         }
  392.         $array array();
  393.         while ($row mysqli_fetch_row$cur )) {
  394.             $array[$row[$numinarray];
  395.         }
  396.         mysqli_free_result$cur );
  397.         return $array;
  398.     }
  399.  
  400.     /**
  401.     * Fetch a result row as an associative array
  402.     *
  403.     * @access public
  404.     * @return array 
  405.     */
  406.     function loadAssoc()
  407.     {
  408.         if (!($cur $this->query())) {
  409.             return null;
  410.         }
  411.         $ret null;
  412.         if ($array mysqli_fetch_assoc$cur )) {
  413.             $ret $array;
  414.         }
  415.         mysqli_free_result$cur );
  416.         return $ret;
  417.     }
  418.  
  419.     /**
  420.     * Load a assoc list of database rows
  421.     *
  422.     * @access public
  423.     * @param string The field name of a primary key
  424.     * @return array If <var>key</var> is empty as sequential list of returned records.
  425.     */
  426.     function loadAssocList$key='' )
  427.     {
  428.         if (!($cur $this->query())) {
  429.             return null;
  430.         }
  431.         $array array();
  432.         while ($row mysqli_fetch_assoc$cur )) {
  433.             if ($key{
  434.                 $array[$row[$key]] $row;
  435.             else {
  436.                 $array[$row;
  437.             }
  438.         }
  439.         mysqli_free_result$cur );
  440.         return $array;
  441.     }
  442.  
  443.     /**
  444.     * This global function loads the first row of a query into an object
  445.     *
  446.     * @access public
  447.     * @return object 
  448.     */
  449.     function loadObject)
  450.     {
  451.         if (!($cur $this->query())) {
  452.             return null;
  453.         }
  454.         $ret null;
  455.         if ($object mysqli_fetch_object$cur )) {
  456.             $ret $object;
  457.         }
  458.         mysqli_free_result$cur );
  459.         return $ret;
  460.     }
  461.  
  462.     /**
  463.     * Load a list of database objects
  464.     *
  465.     * If <var>key</var> is not empty then the returned array is indexed by the value
  466.     * the database key.  Returns <var>null</var> if the query fails.
  467.     *
  468.     * @access public
  469.     * @param string The field name of a primary key
  470.     * @return array If <var>key</var> is empty as sequential list of returned records.
  471.     */
  472.     function loadObjectList$key='' )
  473.     {
  474.         if (!($cur $this->query())) {
  475.             return null;
  476.         }
  477.         $array array();
  478.         while ($row mysqli_fetch_object$cur )) {
  479.             if ($key{
  480.                 $array[$row->$key$row;
  481.             else {
  482.                 $array[$row;
  483.             }
  484.         }
  485.         mysqli_free_result$cur );
  486.         return $array;
  487.     }
  488.  
  489.     /**
  490.      * Description
  491.      *
  492.      * @access public
  493.      * @return The first row of the query.
  494.      */
  495.     function loadRow()
  496.     {
  497.         if (!($cur $this->query())) {
  498.             return null;
  499.         }
  500.         $ret null;
  501.         if ($row mysqli_fetch_row$cur )) {
  502.             $ret $row;
  503.         }
  504.         mysqli_free_result$cur );
  505.         return $ret;
  506.     }
  507.  
  508.     /**
  509.     * Load a list of database rows (numeric column indexing)
  510.     *
  511.     * If <var>key</var> is not empty then the returned array is indexed by the value
  512.     * the database key.  Returns <var>null</var> if the query fails.
  513.     *
  514.     * @access public
  515.     * @param string The field name of a primary key
  516.     * @return array If <var>key</var> is empty as sequential list of returned records.
  517.     */
  518.     function loadRowList$key=null )
  519.     {
  520.         if (!($cur $this->query())) {
  521.             return null;
  522.         }
  523.         $array array();
  524.         while ($row mysqli_fetch_row$cur )) {
  525.             if ($key !== null{
  526.                 $array[$row[$key]] $row;
  527.             else {
  528.                 $array[$row;
  529.             }
  530.         }
  531.         mysqli_free_result$cur );
  532.         return $array;
  533.     }
  534.  
  535.     /**
  536.      * Inserts a row into a table based on an objects properties
  537.      *
  538.      * @access public
  539.      * @param    string    The name of the table
  540.      * @param    object    An object whose properties match table fields
  541.      * @param    string    The name of the primary key. If provided the object property is updated.
  542.      */
  543.     function insertObject$table&$object$keyName NULL )
  544.     {
  545.         $fmtsql 'INSERT INTO '.$this->nameQuote($table).' ( %s ) VALUES ( %s ) ';
  546.         $fields array();
  547.         foreach (get_object_vars$object as $k => $v{
  548.             if (is_array($vor is_object($vor $v === NULL{
  549.                 continue;
  550.             }
  551.             if ($k[0== '_'// internal field
  552.                 continue;
  553.             }
  554.             $fields[$this->nameQuote$k );
  555.             $values[$this->isQuoted$k $this->Quote$v : (int) $v;
  556.         }
  557.         $this->setQuerysprintf$fmtsqlimplode","$fields ,  implode","$values ) ) );
  558.         if (!$this->query()) {
  559.             return false;
  560.         }
  561.         $id $this->insertid();
  562.         if ($keyName && $id{
  563.             $object->$keyName $id;
  564.         }
  565.         return true;
  566.     }
  567.  
  568.     /**
  569.      * Description
  570.      *
  571.      * @access public
  572.      * @param [type] $updateNulls 
  573.      */
  574.     function updateObject$table&$object$keyName$updateNulls=true )
  575.     {
  576.         $fmtsql 'UPDATE '.$this->nameQuote($table).' SET %s WHERE %s';
  577.         $tmp array();
  578.         foreach (get_object_vars$object as $k => $v{
  579.             ifis_array($vor is_object($vor $k[0== '_' // internal or NA field
  580.                 continue;
  581.             }
  582.             if$k == $keyName // PK not to be updated
  583.                 $where $keyName '=' $this->Quote$v );
  584.                 continue;
  585.             }
  586.             if ($v === null)
  587.             {
  588.                 if ($updateNulls{
  589.                     $val 'NULL';
  590.                 else {
  591.                     continue;
  592.                 }
  593.             else {
  594.                 $val $this->isQuoted$k $this->Quote$v : (int) $v;
  595.             }
  596.             $tmp[$this->nameQuote$k '=' $val;
  597.         }
  598.         $this->setQuerysprintf$fmtsqlimplode","$tmp $where ) );
  599.         return $this->query();
  600.     }
  601.  
  602.     /**
  603.      * Description
  604.      *
  605.      * @access public
  606.      */
  607.     function insertid()
  608.     {
  609.         return mysqli_insert_id$this->_resource );
  610.     }
  611.  
  612.     /**
  613.      * Description
  614.      *
  615.      * @access public
  616.      */
  617.     function getVersion()
  618.     {
  619.         return mysqli_get_server_info$this->_resource );
  620.     }
  621.  
  622.     /**
  623.      * Assumes database collation in use by sampling one text field in one table
  624.      *
  625.      * @access public
  626.      * @return string Collation in use
  627.      */
  628.     function getCollation ()
  629.     {
  630.         if $this->hasUTF() ) {
  631.             $this->setQuery'SHOW FULL COLUMNS FROM #__content' );
  632.             $array $this->loadAssocList();
  633.             return $array['4']['Collation'];
  634.         else {
  635.             return "N/A (mySQL < 4.1.2)";
  636.         }
  637.     }
  638.  
  639.     /**
  640.      * Description
  641.      *
  642.      * @access public
  643.      * @return array A list of all the tables in the database
  644.      */
  645.     function getTableList()
  646.     {
  647.         $this->setQuery'SHOW TABLES' );
  648.         return $this->loadResultArray();
  649.     }
  650.  
  651.     /**
  652.      * Shows the CREATE TABLE statement that creates the given tables
  653.      *
  654.      * @access    public
  655.      * @param     array|string    A table name or a list of table names
  656.      * @return     array A list the create SQL for the tables
  657.      */
  658.     function getTableCreate$tables )
  659.     {
  660.         settype($tables'array')//force to array
  661.         $result array();
  662.  
  663.         foreach ($tables as $tblval)
  664.         {
  665.             $this->setQuery'SHOW CREATE table ' $this->getEscaped$tblval ) );
  666.             $rows $this->loadRowList();
  667.             foreach ($rows as $row{
  668.                 $result[$tblval$row[1];
  669.             }
  670.         }
  671.  
  672.         return $result;
  673.     }
  674.  
  675.     /**
  676.      * Retrieves information about the given tables
  677.      *
  678.      * @access    public
  679.      * @param     array|string    A table name or a list of table names
  680.      * @param    boolean            Only return field types, default true
  681.      * @return    array An array of fields by table
  682.      */
  683.     function getTableFields$tables$typeonly true )
  684.     {
  685.         settype($tables'array')//force to array
  686.         $result array();
  687.  
  688.         foreach ($tables as $tblval)
  689.         {
  690.             $this->setQuery'SHOW FIELDS FROM ' $tblval );
  691.             $fields $this->loadObjectList();
  692.  
  693.             if($typeonly)
  694.             {
  695.                 foreach ($fields as $field{
  696.                     $result[$tblval][$field->Fieldpreg_replace("/[(0-9)]/",''$field->Type );
  697.                 }
  698.             }
  699.             else
  700.             {
  701.                 foreach ($fields as $field{
  702.                     $result[$tblval][$field->Field$field;
  703.                 }
  704.             }
  705.         }
  706.  
  707.         return $result;
  708.     }
  709. }

Documentation generated on Sat, 14 Nov 2009 11:16:20 +0000 by phpDocumentor 1.3.1