Modules

Kohana_Database_MySQLi
extends Database
extends Kohana_Database

This class is a transparent base class for Database_MySQLi and should not be accessed directly.

MySQLi database connection.

package
Kohana/Database
category
Drivers
author
Kohana Team
copyright
© 2008-2009 Kohana Team
license
https://kohana.top/license

Class declared in MODPATH/database/classes/Kohana/Database/MySQLi.php on line 12.

Constants

SELECT

integer 1

INSERT

integer 2

UPDATE

integer 3

DELETE

integer 4

Properties

public static string $default

default instance name

string(7) "default"

public static array $instances

Database instances

array(0) 

public string $last_query

the last query executed

Default value:
NULL

protected $_config

Default value:
NULL

protected $_connection

Default value:
NULL

protected $_connection_id

Default value:
NULL

protected static $_current_databases

array(0) 

protected $_identifier

Default value:
string(1) "`"

protected $_instance

Default value:
NULL

protected static $_set_names

NULL

Methods

public begin( [ string $mode = NULL ] ) (defined in Kohana_Database_MySQLi)

Start a SQL transaction

Parameters

  • string $mode = NULL - Isolation level

Tags

  • Link -

Return Values

  • boolean

Source Code

public function begin($mode = null)
{
    // Make sure the database is connected
    $this->_connection or $this->connect();

    if ($mode AND ! $this->_connection->query("SET TRANSACTION ISOLATION LEVEL $mode")) {
        throw new Database_Exception(':error', [':error' => $this->_connection->error], $this->_connection->errno);
    }

    return (bool) $this->_connection->query('START TRANSACTION');
}

public commit( ) (defined in Kohana_Database_MySQLi)

Commit a SQL transaction

Return Values

  • boolean

Source Code

public function commit()
{
    // Make sure the database is connected
    $this->_connection or $this->connect();

    return (bool) $this->_connection->query('COMMIT');
}

public connect( ) (defined in Kohana_Database_MySQLi)

Connect to the database. This is called automatically when the first query is executed.

$db->connect();

Tags

Return Values

  • void

Source Code

public function connect()
{
    if ($this->_connection)
        return;

    if (Database_MySQLi::$_set_names === null) {
        // Determine if we can use mysqli_set_charset(), which is only
        // available on PHP 5.2.3+ when compiled against MySQL 5.0+
        Database_MySQLi::$_set_names = !function_exists('mysqli_set_charset');
    }

    // Extract the connection parameters, adding required variabels
    extract($this->_config['connection'] + [
        'database' => '',
        'hostname' => '',
        'username' => '',
        'password' => '',
        'socket' => '',
        'port' => 3306,
        'ssl' => null,
    ]);

    // Prevent this information from showing up in traces
    unset($this->_config['connection']['username'], $this->_config['connection']['password']);

    try {
        if (is_array($ssl)) {
            $this->_connection = mysqli_init();
            $this->_connection->ssl_set(
                Arr::get($ssl, 'client_key_path'), Arr::get($ssl, 'client_cert_path'), Arr::get($ssl, 'ca_cert_path'), Arr::get($ssl, 'ca_dir_path'), Arr::get($ssl, 'cipher')
            );
            $this->_connection->real_connect($hostname, $username, $password, $database, $port, $socket, MYSQLI_CLIENT_SSL);
        } else {
            $this->_connection = new mysqli($hostname, $username, $password, $database, $port, $socket);
        }
    } catch (Exception $e) {
        // No connection exists
        $this->_connection = null;

        throw new Database_Exception(':error', [':error' => $e->getMessage()], $e->getCode());
    }

    // \xFF is a better delimiter, but the PHP driver uses underscore
    $this->_connection_id = sha1($hostname . '_' . $username . '_' . $password);

    if (!empty($this->_config['charset'])) {
        // Set the character set
        $this->set_charset($this->_config['charset']);
    }

    if (!empty($this->_config['connection']['variables'])) {
        // Set session variables
        $variables = [];

        foreach ($this->_config['connection']['variables'] as $var => $val) {
            $variables[] = 'SESSION ' . $var . ' = ' . $this->quote($val);
        }

        $this->_connection->query('SET ' . implode(', ', $variables));
    }
}

public datatype( string $type ) (defined in Kohana_Database_MySQLi)

Returns a normalized array describing the SQL data type

$db->datatype('char');

Parameters

  • string $type required - SQL data type

Return Values

  • array

Source Code

public function datatype($type)
{
    static $types = [
        'blob' => ['type' => 'string', 'binary' => true, 'character_maximum_length' => '65535'],
        'bool' => ['type' => 'bool'],
        'bigint unsigned' => ['type' => 'int', 'min' => '0', 'max' => '18446744073709551615'],
        'datetime' => ['type' => 'string'],
        'decimal unsigned' => ['type' => 'float', 'exact' => true, 'min' => '0'],
        'double' => ['type' => 'float'],
        'double precision unsigned' => ['type' => 'float', 'min' => '0'],
        'double unsigned' => ['type' => 'float', 'min' => '0'],
        'enum' => ['type' => 'string'],
        'fixed' => ['type' => 'float', 'exact' => true],
        'fixed unsigned' => ['type' => 'float', 'exact' => true, 'min' => '0'],
        'float unsigned' => ['type' => 'float', 'min' => '0'],
        'geometry' => ['type' => 'string', 'binary' => true],
        'int unsigned' => ['type' => 'int', 'min' => '0', 'max' => '4294967295'],
        'integer unsigned' => ['type' => 'int', 'min' => '0', 'max' => '4294967295'],
        'longblob' => ['type' => 'string', 'binary' => true, 'character_maximum_length' => '4294967295'],
        'longtext' => ['type' => 'string', 'character_maximum_length' => '4294967295'],
        'mediumblob' => ['type' => 'string', 'binary' => true, 'character_maximum_length' => '16777215'],
        'mediumint' => ['type' => 'int', 'min' => '-8388608', 'max' => '8388607'],
        'mediumint unsigned' => ['type' => 'int', 'min' => '0', 'max' => '16777215'],
        'mediumtext' => ['type' => 'string', 'character_maximum_length' => '16777215'],
        'national varchar' => ['type' => 'string'],
        'numeric unsigned' => ['type' => 'float', 'exact' => true, 'min' => '0'],
        'nvarchar' => ['type' => 'string'],
        'point' => ['type' => 'string', 'binary' => true],
        'real unsigned' => ['type' => 'float', 'min' => '0'],
        'set' => ['type' => 'string'],
        'smallint unsigned' => ['type' => 'int', 'min' => '0', 'max' => '65535'],
        'text' => ['type' => 'string', 'character_maximum_length' => '65535'],
        'tinyblob' => ['type' => 'string', 'binary' => true, 'character_maximum_length' => '255'],
        'tinyint' => ['type' => 'int', 'min' => '-128', 'max' => '127'],
        'tinyint unsigned' => ['type' => 'int', 'min' => '0', 'max' => '255'],
        'tinytext' => ['type' => 'string', 'character_maximum_length' => '255'],
        'year' => ['type' => 'string'],
    ];

    $type = str_replace(' zerofill', '', $type);

    if (isset($types[$type]))
        return $types[$type];

    return parent::datatype($type);
}

public disconnect( ) (defined in Kohana_Database_MySQLi)

Disconnect from the database. This is called automatically by Database::__destruct. Clears the database instance from Database::$instances.

$db->disconnect();

Return Values

  • boolean

Source Code

public function disconnect()
{
    try {
        // Database is assumed disconnected
        $status = true;

        if (is_resource($this->_connection)) {
            if ($status = $this->_connection->close()) {
                // Clear the connection
                $this->_connection = null;

                // Clear the instance
                parent::disconnect();
            }
        }
    } catch (Exception $e) {
        // Database is probably not disconnected
        $status = !is_resource($this->_connection);
    }

    return $status;
}

public escape( string $value ) (defined in Kohana_Database_MySQLi)

Sanitize a string by escaping characters that could cause an SQL injection attack.

$value = $db->escape('any string');

Parameters

  • string $value required - Value to quote

Return Values

  • string

Source Code

public function escape($value)
{
    // Make sure the database is connected
    $this->_connection or $this->connect();

    if (($value = $this->_connection->real_escape_string((string) $value)) === false) {
        throw new Database_Exception(':error', [':error' => $this->_connection->error], $this->_connection->errno);
    }

    // SQL standard is to use single-quotes for all values
    return "'$value'";
}

public list_columns( string $table [, string $like = NULL , boolean $add_prefix = bool TRUE ] ) (defined in Kohana_Database_MySQLi)

Lists all of the columns in a table. Optionally, a LIKE string can be used to search for specific fields.

// Get all columns from the "users" table
$columns = $db->list_columns('users');

// Get all name-related columns
$columns = $db->list_columns('users', '%name%');

// Get the columns from a table that doesn't use the table prefix
$columns = $db->list_columns('users', null, false);

Parameters

  • string $table required - Table to get columns from
  • string $like = NULL - Column to search for
  • boolean $add_prefix = bool TRUE - Whether to add the table prefix automatically or not

Return Values

  • array

Source Code

public function list_columns($table, $like = null, $add_prefix = true)
{
    // Quote the table name
    $table = ($add_prefix === true) ? $this->quote_table($table) : $table;

    if (is_string($like)) {
        // Search for column names
        $result = $this->query(Database::SELECT, 'SHOW FULL COLUMNS FROM ' . $table . ' LIKE ' . $this->quote($like), false);
    } else {
        // Find all column names
        $result = $this->query(Database::SELECT, 'SHOW FULL COLUMNS FROM ' . $table, false);
    }

    $count = 0;
    $columns = [];
    foreach ($result as $row) {
        list($type, $length) = $this->_parse_type($row['Type']);

        $column = $this->datatype($type);

        $column['column_name'] = $row['Field'];
        $column['column_default'] = $row['Default'];
        $column['data_type'] = $type;
        $column['is_nullable'] = ($row['Null'] == 'YES');
        $column['ordinal_position'] = ++$count;

        switch ($column['type']) {
            case 'float':
                if (isset($length)) {
                    list($column['numeric_precision'], $column['numeric_scale']) = explode(',', $length);
                }
                break;
            case 'int':
                if (isset($length)) {
                    // MySQL attribute
                    $column['display'] = $length;
                }
                break;
            case 'string':
                switch ($column['data_type']) {
                    case 'binary':
                    case 'varbinary':
                        $column['character_maximum_length'] = $length;
                        break;
                    case 'char':
                    case 'varchar':
                        $column['character_maximum_length'] = $length;
                    case 'text':
                    case 'tinytext':
                    case 'mediumtext':
                    case 'longtext':
                        $column['collation_name'] = $row['Collation'];
                        break;
                    case 'enum':
                    case 'set':
                        $column['collation_name'] = $row['Collation'];
                        $column['options'] = explode('\',\'', substr($length, 1, -1));
                        break;
                }
                break;
        }

        // MySQL attributes
        $column['comment'] = $row['Comment'];
        $column['extra'] = $row['Extra'];
        $column['key'] = $row['Key'];
        $column['privileges'] = $row['Privileges'];

        $columns[$row['Field']] = $column;
    }

    return $columns;
}

public list_tables( [ string $like = NULL ] ) (defined in Kohana_Database_MySQLi)

List all of the tables in the database. Optionally, a LIKE string can be used to search for specific tables.

// Get all tables in the current database
$tables = $db->list_tables();

// Get all user-related tables
$tables = $db->list_tables('user%');

Parameters

  • string $like = NULL - Table to search for

Return Values

  • array

Source Code

public function list_tables($like = null)
{
    if (is_string($like)) {
        // Search for table names
        $result = $this->query(Database::SELECT, 'SHOW TABLES LIKE ' . $this->quote($like), false);
    } else {
        // Find all table names
        $result = $this->query(Database::SELECT, 'SHOW TABLES', false);
    }

    $tables = [];
    foreach ($result as $row) {
        $tables[] = reset($row);
    }

    return $tables;
}

public query( integer $type , string $sql [, mixed $as_object = bool FALSE , array $params = NULL ] ) (defined in Kohana_Database_MySQLi)

Perform an SQL query of the given type.

// Make a SELECT query and use objects for results
$db->query(Database::SELECT, 'SELECT * FROM groups', true);

// Make a SELECT query and use "Model_User" for the results
$db->query(Database::SELECT, 'SELECT * FROM users LIMIT 1', 'Model_User');

Parameters

  • integer $type required - Database::SELECT, Database::INSERT, etc
  • string $sql required - SQL query
  • mixed $as_object = bool FALSE - Result object class string, true for stdClass, false for assoc array
  • array $params = NULL - Object construct parameters for result class

Return Values

  • object - Database_Result for SELECT queries
  • array - List (insert id, row count) for INSERT queries
  • integer - Number of affected rows for all other queries

Source Code

public function query($type, $sql, $as_object = false, array $params = null)
{
    // Make sure the database is connected
    $this->_connection or $this->connect();

    if (Kohana::$profiling) {
        // Benchmark this query for the current instance
        $benchmark = Profiler::start("Database ({$this->_instance})", $sql);
    }

    // Execute the query
    if (($result = $this->_connection->query($sql)) === false) {
        if (isset($benchmark)) {
            // This benchmark is worthless
            Profiler::delete($benchmark);
        }

        throw new Database_Exception(':error [ :query ]', [
        ':error' => $this->_connection->error,
        ':query' => $sql
        ], $this->_connection->errno);
    }

    if (isset($benchmark)) {
        Profiler::stop($benchmark);
    }

    // Set the last query
    $this->last_query = $sql;

    if ($type === Database::SELECT) {
        // Return an iterator of results
        return new Database_MySQLi_Result($result, $sql, $as_object, $params);
    } elseif ($type === Database::INSERT) {
        // Return a list of insert id and rows created
        return [
            $this->_connection->insert_id,
            $this->_connection->affected_rows,
        ];
    } else {
        // Return the number of rows affected
        return $this->_connection->affected_rows;
    }
}

public rollback( ) (defined in Kohana_Database_MySQLi)

Rollback a SQL transaction

Return Values

  • boolean

Source Code

public function rollback()
{
    // Make sure the database is connected
    $this->_connection or $this->connect();

    return (bool) $this->_connection->query('ROLLBACK');
}

public set_charset( string $charset ) (defined in Kohana_Database_MySQLi)

Set the connection character set. This is called automatically by Database::connect.

$db->set_charset('utf8');

Parameters

  • string $charset required - Character set name

Tags

Return Values

  • void

Source Code

public function set_charset($charset)
{
    // Make sure the database is connected
    $this->_connection or $this->connect();

    if (Database_MySQLi::$_set_names === true) {
        // PHP is compiled against MySQL 4.x
        $status = (bool) $this->_connection->query('SET NAMES ' . $this->quote($charset));
    } else {
        // PHP is compiled against MySQL 5.x
        $status = $this->_connection->set_charset($charset);
    }

    if ($status === false) {
        throw new Database_Exception(':error', [':error' => $this->_connection->error], $this->_connection->errno);
    }
}

public __construct( ) (defined in Kohana_Database)

Stores the database configuration locally and name the instance.

This method cannot be accessed directly, you must use Database::instance.

Return Values

  • void

Source Code

public function __construct($name, array $config)
{
    // Set the instance name
    $this->_instance = $name;

    // Store the config locally
    $this->_config = $config;

    if (empty($this->_config['table_prefix'])) {
        $this->_config['table_prefix'] = '';
    }
}

public __destruct( ) (defined in Kohana_Database)

Disconnect from the database when the object is destroyed.

// Destroy the database instance
unset(Database::instances[(string) $db], $db);

Calling unset($db) is not enough to destroy the database, as it will still be stored in Database::$instances.

Return Values

  • void

Source Code

public function __destruct()
{
    $this->disconnect();
}

public __toString( ) (defined in Kohana_Database)

Returns the database instance name.

echo (string) $db;

Return Values

  • string

Source Code

public function __toString()
{
    return $this->_instance;
}

public count_records( mixed $table ) (defined in Kohana_Database)

Count the number of records in a table.

// Get the total number of records in the "users" table
$count = $db->count_records('users');

Parameters

  • mixed $table required - Table name string or [query, alias]

Return Values

  • integer

Source Code

public function count_records($table)
{
    // Quote the table name
    $table = $this->quote_table($table);

    return $this->query(Database::SELECT, 'SELECT COUNT(*) AS total_row_count FROM ' . $table, false)
            ->get('total_row_count');
}

public static instance( [ string $name = NULL , array $config = NULL ] ) (defined in Kohana_Database)

Get a singleton Database instance. If configuration is not specified, it will be loaded from the database configuration file using the same group as the name.

// Load the default database
$db = Database::instance();

// Create a custom configured instance
$db = Database::instance('custom', $config);

Parameters

  • string $name = NULL - Instance name
  • array $config = NULL - Configuration parameters

Return Values

  • Database

Source Code

public static function instance($name = null, array $config = null)
{
    if ($name === null) {
        // Use the default instance name
        $name = Database::$default;
    }

    if (!isset(Database::$instances[$name])) {
        if ($config === null) {
            // Load the configuration for this database
            $config = Kohana::$config->load('database')->$name;
        }

        if (!isset($config['type'])) {
            throw new Kohana_Exception('Database type not defined in :name configuration', [':name' => $name]);
        }

        // Set the driver class name
        $driver = 'Database_' . ucfirst($config['type']);

        // Create the database connection instance
        $driver = new $driver($name, $config);

        // Store the database instance
        Database::$instances[$name] = $driver;
    }

    return Database::$instances[$name];
}

public quote( mixed $value ) (defined in Kohana_Database)

Quote a value for an SQL query.

$db->quote(null);   // 'NULL'
$db->quote(10);     // 10
$db->quote('fred'); // 'fred'

Objects passed to this function will be converted to strings. Database_Expression objects will be compiled. Database_Query objects will be compiled and converted to a sub-query. All other objects will be converted using the __toString method.

Parameters

  • mixed $value required - Any value to quote

Tags

Return Values

  • string

Source Code

public function quote($value)
{
    if ($value === null) {
        return 'NULL';
    } elseif ($value === true) {
        return "'1'";
    } elseif ($value === false) {
        return "'0'";
    } elseif (is_object($value)) {
        if ($value instanceof Database_Query) {
            // Create a sub-query
            return '(' . $value->compile($this) . ')';
        } elseif ($value instanceof Database_Expression) {
            // Compile the expression
            return $value->compile($this);
        } else {
            // Convert the object to a string
            return $this->quote((string) $value);
        }
    } elseif (is_array($value)) {
        return '(' . implode(', ', array_map([$this, __FUNCTION__], $value)) . ')';
    } elseif (is_int($value)) {
        return (int) $value;
    } elseif (is_float($value)) {
        // Convert to non-locale aware float to prevent possible commas
        return sprintf('%F', $value);
    }

    return $this->escape($value);
}

public quote_column( mixed $column ) (defined in Kohana_Database)

Quote a database column name and add the table prefix if needed.

$column = $db->quote_column($column);

You can also use SQL methods within identifiers.

$column = $db->quote_column(DB::expr('COUNT(`column`)'));

Objects passed to this function will be converted to strings. Database_Expression objects will be compiled. Database_Query objects will be compiled and converted to a sub-query. All other objects will be converted using the __toString method.

Parameters

  • mixed $column required - Column name or [column, alias]

Tags

Return Values

  • string

Source Code

public function quote_column($column)
{
    // Identifiers are escaped by repeating them
    $escaped_identifier = $this->_identifier . $this->_identifier;

    if (is_array($column)) {
        list($column, $alias) = $column;
        $alias = str_replace($this->_identifier, $escaped_identifier, $alias);
    }

    if ($column instanceof Database_Query) {
        // Create a sub-query
        $column = '(' . $column->compile($this) . ')';
    } elseif ($column instanceof Database_Expression) {
        // Compile the expression
        $column = $column->compile($this);
    } else {
        // Convert to a string
        $column = (string) $column;

        $column = str_replace($this->_identifier, $escaped_identifier, $column);

        if ($column === '*') {
            return $column;
        } elseif (strpos($column, '.') !== false) {
            $parts = explode('.', $column);

            if ($prefix = $this->table_prefix()) {
                // Get the offset of the table name, 2nd-to-last part
                $offset = count($parts) - 2;

                // Add the table prefix to the table name
                $parts[$offset] = $prefix . $parts[$offset];
            }

            foreach ($parts as & $part) {
                if ($part !== '*') {
                    // Quote each of the parts
                    $part = $this->_identifier . $part . $this->_identifier;
                }
            }

            $column = implode('.', $parts);
        } else {
            $column = $this->_identifier . $column . $this->_identifier;
        }
    }

    if (isset($alias)) {
        $column .= ' AS ' . $this->_identifier . $alias . $this->_identifier;
    }

    return $column;
}

public quote_identifier( mixed $value ) (defined in Kohana_Database)

Quote a database identifier

Objects passed to this function will be converted to strings. Database_Expression objects will be compiled. Database_Query objects will be compiled and converted to a sub-query. All other objects will be converted using the __toString method.

Parameters

  • mixed $value required - Any identifier

Return Values

  • string

Source Code

public function quote_identifier($value)
{
    // Identifiers are escaped by repeating them
    $escaped_identifier = $this->_identifier . $this->_identifier;

    if (is_array($value)) {
        list($value, $alias) = $value;
        $alias = str_replace($this->_identifier, $escaped_identifier, $alias);
    }

    if ($value instanceof Database_Query) {
        // Create a sub-query
        $value = '(' . $value->compile($this) . ')';
    } elseif ($value instanceof Database_Expression) {
        // Compile the expression
        $value = $value->compile($this);
    } else {
        // Convert to a string
        $value = (string) $value;

        $value = str_replace($this->_identifier, $escaped_identifier, $value);

        if (strpos($value, '.') !== false) {
            $parts = explode('.', $value);

            foreach ($parts as & $part) {
                // Quote each of the parts
                $part = $this->_identifier . $part . $this->_identifier;
            }

            $value = implode('.', $parts);
        } else {
            $value = $this->_identifier . $value . $this->_identifier;
        }
    }

    if (isset($alias)) {
        $value .= ' AS ' . $this->_identifier . $alias . $this->_identifier;
    }

    return $value;
}

public quote_table( mixed $table ) (defined in Kohana_Database)

Quote a database table name and adds the table prefix if needed.

$table = $db->quote_table($table);

Objects passed to this function will be converted to strings. Database_Expression objects will be compiled. Database_Query objects will be compiled and converted to a sub-query. All other objects will be converted using the __toString method.

Parameters

  • mixed $table required - Table name or [table, alias]

Tags

Return Values

  • string

Source Code

public function quote_table($table)
{
    // Identifiers are escaped by repeating them
    $escaped_identifier = $this->_identifier . $this->_identifier;

    if (is_array($table)) {
        list($table, $alias) = $table;
        $alias = str_replace($this->_identifier, $escaped_identifier, $alias);
    }

    if ($table instanceof Database_Query) {
        // Create a sub-query
        $table = '(' . $table->compile($this) . ')';
    } elseif ($table instanceof Database_Expression) {
        // Compile the expression
        $table = $table->compile($this);
    } else {
        // Convert to a string
        $table = (string) $table;

        $table = str_replace($this->_identifier, $escaped_identifier, $table);

        if (strpos($table, '.') !== false) {
            $parts = explode('.', $table);

            if ($prefix = $this->table_prefix()) {
                // Get the offset of the table name, last part
                $offset = count($parts) - 1;

                // Add the table prefix to the table name
                $parts[$offset] = $prefix . $parts[$offset];
            }

            foreach ($parts as & $part) {
                // Quote each of the parts
                $part = $this->_identifier . $part . $this->_identifier;
            }

            $table = implode('.', $parts);
        } else {
            // Add the table prefix
            $table = $this->_identifier . $this->table_prefix() . $table . $this->_identifier;
        }
    }

    if (isset($alias)) {
        // Attach table prefix to alias
        $table .= ' AS ' . $this->_identifier . $this->table_prefix() . $alias . $this->_identifier;
    }

    return $table;
}

public table_prefix( ) (defined in Kohana_Database)

Return the table prefix defined in the current configuration.

$prefix = $db->table_prefix();

Return Values

  • string

Source Code

public function table_prefix()
{
    return $this->_config['table_prefix'];
}

protected _parse_type( string $type ) (defined in Kohana_Database)

Extracts the text between parentheses, if any.

// Returns: ['CHAR', '6']
list($type, $length) = $db->_parse_type('CHAR(6)');

Parameters

  • string $type required - $type

Return Values

  • array - List containing the type and length, if any

Source Code

protected function _parse_type($type)
{
    if (($open = strpos($type, '(')) === false) {
        // No length specified
        return [$type, null];
    }

    // Closing parenthesis
    $close = strrpos($type, ')', $open);

    // Length without parentheses
    $length = substr($type, $open + 1, $close - 1 - $open);

    // Type without the length
    $type = substr($type, 0, $open) . substr($type, $close + 1);

    return [$type, $length];
}