Source for file mysql.php

Documentation is available at mysql.php

  1. <?php
  2. /**
  3.  * @package     Joomla.Platform
  4.  * @subpackage  Database
  5.  *
  6.  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7.  * @license     GNU General Public License version 2 or later; see LICENSE
  8.  */
  9.  
  10. defined('JPATH_PLATFORM'or die;
  11.  
  12. /**
  13.  * MySQL database driver
  14.  *
  15.  * @package     Joomla.Platform
  16.  * @subpackage  Database
  17.  * @see         http://dev.mysql.com/doc/
  18.  * @since       12.1
  19.  */
  20. {
  21.     /**
  22.      * The name of the database driver.
  23.      *
  24.      * @var    string 
  25.      * @since  12.1
  26.      */
  27.     public $name = 'mysql';
  28.  
  29.     /**
  30.      * Constructor.
  31.      *
  32.      * @param   array  $options  Array of database options with keys: host, user, password, database, select.
  33.      *
  34.      * @since   12.1
  35.      */
  36.     public function __construct($options)
  37.     {
  38.         // Get some basic values from the options.
  39.         $options['host'(isset($options['host'])) $options['host''localhost';
  40.         $options['user'(isset($options['user'])) $options['user''root';
  41.         $options['password'(isset($options['password'])) $options['password''';
  42.         $options['database'(isset($options['database'])) $options['database''';
  43.         $options['select'(isset($options['select'])) ? (bool) $options['select'true;
  44.  
  45.         // Finalize initialisation.
  46.         parent::__construct($options);
  47.     }
  48.  
  49.     /**
  50.      * Destructor.
  51.      *
  52.      * @since   12.1
  53.      */
  54.     public function __destruct()
  55.     {
  56.         $this->disconnect();
  57.     }
  58.  
  59.     /**
  60.      * Connects to the database if needed.
  61.      *
  62.      * @return  void  Returns void if the database connected successfully.
  63.      *
  64.      * @since   12.1
  65.      * @throws  RuntimeException
  66.      */
  67.     public function connect()
  68.     {
  69.         if ($this->connection)
  70.         {
  71.             return;
  72.         }
  73.  
  74.         // Make sure the MySQL extension for PHP is installed and enabled.
  75.         if (!function_exists('mysql_connect'))
  76.         {
  77.             throw new RuntimeException('Could not connect to MySQL.');
  78.         }
  79.  
  80.         // Attempt to connect to the server.
  81.         if (!($this->connection = mysql_connect($this->options['host']$this->options['user']$this->options['password']true)))
  82.         {
  83.             throw new RuntimeException('Could not connect to MySQL.');
  84.         }
  85.  
  86.         // Set sql_mode to non_strict mode
  87.         mysql_query("SET @@SESSION.sql_mode = '';"$this->connection);
  88.  
  89.         // If auto-select is enabled select the given database.
  90.         if ($this->options['select'&& !empty($this->options['database']))
  91.         {
  92.             $this->select($this->options['database']);
  93.         }
  94.  
  95.         // Set charactersets (needed for MySQL 4.1.2+).
  96.         $this->setUTF();
  97.  
  98.         // Turn MySQL profiling ON in debug mode:
  99.         if ($this->debug && $this->hasProfiling())
  100.         {
  101.             mysql_query("SET profiling = 1;"$this->connection);
  102.         }
  103.     }
  104.  
  105.     /**
  106.      * Disconnects the database.
  107.      *
  108.      * @return  void 
  109.      *
  110.      * @since   12.1
  111.      */
  112.     public function disconnect()
  113.     {
  114.         // Close the connection.
  115.         if (is_resource($this->connection))
  116.         {
  117.             foreach ($this->disconnectHandlers as $h)
  118.             {
  119.                 call_user_func_array($harray&$this));
  120.             }
  121.  
  122.             mysql_close($this->connection);
  123.         }
  124.  
  125.         $this->connection = null;
  126.     }
  127.  
  128.     /**
  129.      * Method to escape a string for usage in an SQL statement.
  130.      *
  131.      * @param   string   $text   The string to be escaped.
  132.      * @param   boolean  $extra  Optional parameter to provide extra escaping.
  133.      *
  134.      * @return  string  The escaped string.
  135.      *
  136.      * @since   12.1
  137.      */
  138.     public function escape($text$extra false)
  139.     {
  140.         $this->connect();
  141.  
  142.         $result mysql_real_escape_string($text$this->getConnection());
  143.  
  144.         if ($extra)
  145.         {
  146.             $result addcslashes($result'%_');
  147.         }
  148.  
  149.         return $result;
  150.     }
  151.  
  152.     /**
  153.      * Test to see if the MySQL connector is available.
  154.      *
  155.      * @return  boolean  True on success, false otherwise.
  156.      *
  157.      * @since   12.1
  158.      */
  159.     public static function isSupported()
  160.     {
  161.         return (function_exists('mysql_connect'));
  162.     }
  163.  
  164.     /**
  165.      * Determines if the connection to the server is active.
  166.      *
  167.      * @return  boolean  True if connected to the database engine.
  168.      *
  169.      * @since   12.1
  170.      */
  171.     public function connected()
  172.     {
  173.         if (is_resource($this->connection))
  174.         {
  175.             return @mysql_ping($this->connection);
  176.         }
  177.  
  178.         return false;
  179.     }
  180.  
  181.     /**
  182.      * Get the number of affected rows for the previous executed SQL statement.
  183.      *
  184.      * @return  integer  The number of affected rows.
  185.      *
  186.      * @since   12.1
  187.      */
  188.     public function getAffectedRows()
  189.     {
  190.         $this->connect();
  191.  
  192.         return mysql_affected_rows($this->connection);
  193.     }
  194.  
  195.     /**
  196.      * Get the number of returned rows for the previous executed SQL statement.
  197.      *
  198.      * @param   resource  $cursor  An optional database cursor resource to extract the row count from.
  199.      *
  200.      * @return  integer   The number of returned rows.
  201.      *
  202.      * @since   12.1
  203.      */
  204.     public function getNumRows($cursor null)
  205.     {
  206.         $this->connect();
  207.  
  208.         return mysql_num_rows($cursor $cursor $this->cursor);
  209.     }
  210.  
  211.     /**
  212.      * Get the version of the database connector.
  213.      *
  214.      * @return  string  The database connector version.
  215.      *
  216.      * @since   12.1
  217.      */
  218.     public function getVersion()
  219.     {
  220.         $this->connect();
  221.  
  222.         return mysql_get_server_info($this->connection);
  223.     }
  224.  
  225.     /**
  226.      * Method to get the auto-incremented value from the last INSERT statement.
  227.      *
  228.      * @return  integer  The value of the auto-increment field from the last inserted row.
  229.      *
  230.      * @since   12.1
  231.      */
  232.     public function insertid()
  233.     {
  234.         $this->connect();
  235.  
  236.         return mysql_insert_id($this->connection);
  237.     }
  238.  
  239.     /**
  240.      * Execute the SQL statement.
  241.      *
  242.      * @return  mixed  A database cursor resource on success, boolean false on failure.
  243.      *
  244.      * @since   12.1
  245.      * @throws  RuntimeException
  246.      */
  247.     public function execute()
  248.     {
  249.         $this->connect();
  250.  
  251.         if (!is_resource($this->connection))
  252.         {
  253.             JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED'$this->errorNum$this->errorMsg)JLog::ERROR'database');
  254.             throw new RuntimeException($this->errorMsg$this->errorNum);
  255.         }
  256.  
  257.         // Take a local copy so that we don't modify the original query and cause issues later
  258.         $query $this->replacePrefix((string) $this->sql);
  259.  
  260.         if (!($this->sql instanceof JDatabaseQuery&& ($this->limit > || $this->offset > 0))
  261.         {
  262.             $query .= ' LIMIT ' $this->offset . ', ' $this->limit;
  263.         }
  264.  
  265.         // Increment the query counter.
  266.         $this->count++;
  267.  
  268.         // Reset the error values.
  269.         $this->errorNum = 0;
  270.         $this->errorMsg = '';
  271.  
  272.         // If debugging is enabled then let's log the query.
  273.         if ($this->debug)
  274.         {
  275.             // Add the query to the object queue.
  276.             $this->log[$query;
  277.  
  278.             JLog::add($queryJLog::DEBUG'databasequery');
  279.  
  280.             $this->timings[microtime(true);
  281.         }
  282.  
  283.         // Execute the query. Error suppression is used here to prevent warnings/notices that the connection has been lost.
  284.         $this->cursor = @mysql_query($query$this->connection);
  285.  
  286.         if ($this->debug)
  287.         {
  288.             $this->timings[microtime(true);
  289.  
  290.             if (defined('DEBUG_BACKTRACE_IGNORE_ARGS'))
  291.             {
  292.                 $this->callStacks[debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
  293.             }
  294.             else
  295.             {
  296.                 $this->callStacks[debug_backtrace();
  297.             }
  298.         }
  299.  
  300.         // If an error occurred handle it.
  301.         if (!$this->cursor)
  302.         {
  303.             // Check if the server was disconnected.
  304.             if (!$this->connected())
  305.             {
  306.                 try
  307.                 {
  308.                     // Attempt to reconnect.
  309.                     $this->connection = null;
  310.                     $this->connect();
  311.                 }
  312.                 // If connect fails, ignore that exception and throw the normal exception.
  313.                 catch (RuntimeException $e)
  314.                 {
  315.                     // Get the error number and message.
  316.                     $this->errorNum = (int) mysql_errno($this->connection);
  317.                     $this->errorMsg = (string) mysql_error($this->connection' SQL=' $query;
  318.  
  319.                     // Throw the normal query exception.
  320.                     JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED'$this->errorNum$this->errorMsg)JLog::ERROR'databasequery');
  321.                     throw new RuntimeException($this->errorMsg$this->errorNum);
  322.                 }
  323.  
  324.                 // Since we were able to reconnect, run the query again.
  325.                 return $this->execute();
  326.             }
  327.             // The server was not disconnected.
  328.             else
  329.             {
  330.                 // Get the error number and message.
  331.                 $this->errorNum = (int) mysql_errno($this->connection);
  332.                 $this->errorMsg = (string) mysql_error($this->connection' SQL=' $query;
  333.  
  334.                 // Throw the normal query exception.
  335.                 JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED'$this->errorNum$this->errorMsg)JLog::ERROR'databasequery');
  336.                 throw new RuntimeException($this->errorMsg$this->errorNum);
  337.             }
  338.         }
  339.  
  340.         return $this->cursor;
  341.     }
  342.  
  343.     /**
  344.      * Select a database for use.
  345.      *
  346.      * @param   string  $database  The name of the database to select for use.
  347.      *
  348.      * @return  boolean  True if the database was successfully selected.
  349.      *
  350.      * @since   12.1
  351.      * @throws  RuntimeException
  352.      */
  353.     public function select($database)
  354.     {
  355.         $this->connect();
  356.  
  357.         if (!$database)
  358.         {
  359.             return false;
  360.         }
  361.  
  362.         if (!mysql_select_db($database$this->connection))
  363.         {
  364.             throw new RuntimeException('Could not connect to database');
  365.         }
  366.  
  367.         return true;
  368.     }
  369.  
  370.     /**
  371.      * Set the connection to use UTF-8 character encoding.
  372.      *
  373.      * @return  boolean  True on success.
  374.      *
  375.      * @since   12.1
  376.      */
  377.     public function setUTF()
  378.     {
  379.         $this->connect();
  380.  
  381.         return mysql_set_charset('utf8'$this->connection);
  382.     }
  383.  
  384.     /**
  385.      * Method to fetch a row from the result set cursor as an array.
  386.      *
  387.      * @param   mixed  $cursor  The optional result set cursor from which to fetch the row.
  388.      *
  389.      * @return  mixed  Either the next row from the result set or false if there are no more rows.
  390.      *
  391.      * @since   12.1
  392.      */
  393.     protected function fetchArray($cursor null)
  394.     {
  395.         return mysql_fetch_row($cursor $cursor $this->cursor);
  396.     }
  397.  
  398.     /**
  399.      * Method to fetch a row from the result set cursor as an associative array.
  400.      *
  401.      * @param   mixed  $cursor  The optional result set cursor from which to fetch the row.
  402.      *
  403.      * @return  mixed  Either the next row from the result set or false if there are no more rows.
  404.      *
  405.      * @since   12.1
  406.      */
  407.     protected function fetchAssoc($cursor null)
  408.     {
  409.         return mysql_fetch_assoc($cursor $cursor $this->cursor);
  410.     }
  411.  
  412.     /**
  413.      * Method to fetch a row from the result set cursor as an object.
  414.      *
  415.      * @param   mixed   $cursor  The optional result set cursor from which to fetch the row.
  416.      * @param   string  $class   The class name to use for the returned row object.
  417.      *
  418.      * @return  mixed   Either the next row from the result set or false if there are no more rows.
  419.      *
  420.      * @since   12.1
  421.      */
  422.     protected function fetchObject($cursor null$class 'stdClass')
  423.     {
  424.         return mysql_fetch_object($cursor $cursor $this->cursor$class);
  425.     }
  426.  
  427.     /**
  428.      * Method to free up the memory used for the result set.
  429.      *
  430.      * @param   mixed  $cursor  The optional result set cursor from which to fetch the row.
  431.      *
  432.      * @return  void 
  433.      *
  434.      * @since   12.1
  435.      */
  436.     protected function freeResult($cursor null)
  437.     {
  438.         mysql_free_result($cursor $cursor $this->cursor);
  439.     }
  440.  
  441.     /**
  442.      * Internal function to check if profiling is available
  443.      *
  444.      * @return  boolean 
  445.      *
  446.      * @since 3.1.3
  447.      */
  448.     private function hasProfiling()
  449.     {
  450.         try
  451.         {
  452.             $res mysql_query("SHOW VARIABLES LIKE 'have_profiling'"$this->connection);
  453.             $row mysql_fetch_assoc($res);
  454.  
  455.             return isset($row);
  456.         }
  457.         catch (Exception $e)
  458.         {
  459.             return false;
  460.         }
  461.     }
  462. }

Documentation generated on Tue, 19 Nov 2013 15:09:09 +0100 by phpDocumentor 1.4.3