You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

6.1 KiB

Database basics

Yii has a database access layer built on top of PHP's PDO. It provides uniform API and solves some inconsistencies between different DBMS. By default Yii supports MySQL, SQLite, PostgreSQL, Oracle and MSSQL.

Configuration

In order to start using database you need to configure database connection component first by adding db component to application configuration (for "basic" web application it's config/web.php) like the following:

return array(
	// ...
	'components' => array(
		// ...
		'db' => array(
			'class' => 'yii\db\Connection',
			'dsn' => 'mysql:host=localhost;dbname=mydatabase', // MySQL, MariaDB
			//'dsn' => 'sqlite:/path/to/database/file', // SQLite
			//'dsn' => 'pgsql:host=localhost;port=5432;dbname=mydatabase', // PostgreSQL
			//'dsn' => 'sqlsrv:Server=localhost;Database=mydatabase', // MS SQL Server, sqlsrv driver
			//'dsn' => 'dblib:host=localhost;dbname=mydatabase', // MS SQL Server, dblib driver
			//'dsn' => 'mssql:host=localhost;dbname=mydatabase', // MS SQL Server, mssql driver
			//'dsn' => 'oci:dbname=//localhost:1521/mydatabase', // Oracle
			'username' => 'root',
			'password' => '',
			'charset' => 'utf8',
		),
	),
	// ...
);

After the component is configured you can access it using the following syntax:

$connection = \Yii::$app->db;

You can refer to \yii\db\Connection for a list of properties you can configure. Also note that you can define more than one connection component and use both at the same time if needed:

$primaryConnection = \Yii::$app->db;
$secondaryConnection = \Yii::$app->secondDb;

If you don't want to define the connection as an application component you can instantiate it directly:

$connection = new \yii\db\Connection(array(
	'dsn' => $dsn,
 	'username' => $username,
 	'password' => $password,
));
$connection->open();

Basic SQL queries

Once you have a connection instance you can execute SQL queries using \yii\db\Command.

SELECT

When query returns a set of rows:

$command = $connection->createCommand('SELECT * FROM tbl_post');
$posts = $command->queryAll();

When only a single row is returned:

$command = $connection->createCommand('SELECT * FROM tbl_post WHERE id=1');
$post = $command->query();

When there are multiple values from the same column:

$command = $connection->createCommand('SELECT title FROM tbl_post');
$titles = $command->queryColumn();

When there's a scalar value:

$command = $connection->createCommand('SELECT COUNT(*) FROM tbl_post');
$postCount = $command->queryScalar();

UPDATE, INSERT, DELETE etc.

If SQL executed doesn't return any data you can use command's execute method:

$command = $connection->createCommand('UPDATE tbl_post SET status=1 WHERE id=1');
$command->execute();

Alternatively the following syntax that takes care of proper table and column names quoting is possible:

// INSERT
$connection->createCommand()->insert('tbl_user', array(
	'name' => 'Sam',
	'age' => 30,
))->execute();

// INSERT multiple rows at once
$connection->createCommand()->batchInsert('tbl_user', array('name', 'age'), array(
	array('Tom', 30),
	array('Jane', 20),
	array('Linda', 25),
))->execute();

// UPDATE
$connection->createCommand()->update('tbl_user', array(
	'status' => 1,
), 'age > 30')->execute();

// DELETE
$connection->createCommand()->delete('tbl_user', 'status = 0')->execute();

Quoting table and column names

Most of the time you would use the following syntax for quoting table and column names:

$sql = "SELECT COUNT([[$column]]) FROM {{$table}}";
$rowCount = $connection->createCommand($sql)->queryScalar();

In the code above [[X]] will be converted to properly quoted column name while {{Y}} will be converted to properly quoted table name.

The alternative is to quote table and column names manually using \yii\db\Connection::quoteTableName() and \yii\db\Connection::quoteColumnName():

$column = $connection->quoteColumnName($column);
$table = $connection->quoteTableName($table);
$sql = "SELECT COUNT($column) FROM $table";
$rowCount = $connection->createCommand($sql)->queryScalar();

Prepared statements

In order to securely pass query parameters you can use prepared statements:

$command = $connection->createCommand('SELECT * FROM tbl_post WHERE id=:id');
$command->bindValue(':id', $_GET['id']);
$post = $command->query();

Another usage is performing a query multiple times while preparing it only once:

$command = $connection->createCommand('DELETE FROM tbl_post WHERE id=:id');
$command->bindParam(':id', $id);

$id = 1;
$command->execute();

$id = 2;
$command->execute();

Transactions

If the underlying DBMS supports transactions, you can perform transactional SQL queries like the following:

$transaction = $connection->beginTransaction();
try {
	$connection->createCommand($sql1)->execute();
 	$connection->createCommand($sql2)->execute();
	// ... executing other SQL statements ...
	$transaction->commit();
} catch(Exception $e) {
	$transaction->rollback();
}

Working with database schema

Getting schema information

You can get a \yii\db\Schema instance like the following:

$schema = $connection->getSchema();

It contains a set of methods allowing you to retrieve various information about the database:

$tables = $schema->getTableNames();

For the full reference check \yii\db\Schema.

Modifying schema

Aside from basic SQL queries \yii\db\Command contains a set of methods allowing to modify database schema:

  • createTable, renameTable, dropTable, truncateTable
  • addColumn, renameColumn, dropColumn, alterColumn
  • addPrimaryKey, dropPrimaryKey
  • addForeignKey, dropForeignKey
  • createIndex, dropIndex

These can be used as follows:

// CREATE TABLE
$connection->createCommand()->createTable('tbl_post', array(
	'id' => 'pk',
	'title' => 'string',
	'text' => 'text',
);

For the full reference check \yii\db\Command.