# CakePHP 数据库教程

> 原文： [https://zetcode.com/php/cakephpdatabase/](https://zetcode.com/php/cakephpdatabase/)

CakePHP 数据库教程展示了如何使用 CakePHP 的数据库包在 PHP 中编程数据库。

## CakePHP 数据库

CakePHP 数据库是一个灵活而强大的数据库抽象库，它具有类似 PDO 的 API。 该库可帮助程序员构建查询，防止 SQL 注入，检查和更改模式，以及将调试和配置文件查询发送到数据库。

CakePHP 数据库支持 MySQL/MariaDB，PostgresSQL，SQLite 和 Microsoft SQL Server。

## MariaDB 数据库

在本教程中，我们将使用 MariaDB 数据库

`countries_mariadb.sql`

```php
DROP TABLE IF EXISTS countries;
CREATE TABLE countries(id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(255), population INT);

INSERT INTO countries(name, population) VALUES('China', 1382050000);
INSERT INTO countries(name, population) VALUES('India', 1313210000);
INSERT INTO countries(name, population) VALUES('USA', 324666000);
INSERT INTO countries(name, population) VALUES('Indonesia', 260581000);
INSERT INTO countries(name, population) VALUES('Brazil', 207221000);
INSERT INTO countries(name, population) VALUES('Pakistan', 196626000);
INSERT INTO countries(name, population) VALUES('Nigeria', 186988000);
INSERT INTO countries(name, population) VALUES('Bangladesh', 162099000);
INSERT INTO countries(name, population) VALUES('Nigeria', 186988000);
INSERT INTO countries(name, population) VALUES('Russia', 146838000);
INSERT INTO countries(name, population) VALUES('Japan', 126830000);

```

这些 SQL 命令创建一个`countries`表。

## 安装 CakePHP 数据库

```php
$ composer require cakephp/database

```

CakePHP 数据库是使用上述命令安装的。

## CakePHP 执行

`execute()`执行查询。

`version.php`

```php
<?php

require __DIR__ . '/vendor/autoload.php';

use Cake\Database\Connection;
use Cake\Database\Driver\Mysql;

$driver = new Mysql([
    'database' => 'mydb',
    'username' => 'root',
    'password' => 's$cret',
]);

$conn = new Connection([
    'driver' => $driver,
]);

$stm = $conn->execute('SELECT VERSION()');
$version = $stm->fetch()[0];

echo $version . "\n";

```

该示例打印 MariaDB 数据库的版本。

```php
$driver = new Mysql([
    'database' => 'mydb',
    'username' => 'root',
    'password' => 's$cret',
]);

```

创建一个新的 MySQL 驱动程序。 我们提供数据库名称，用户名和密码。

```php
$conn = new Connection([
    'driver' => $driver,
]);

```

创建一个连接对象。

```php
$ php version.php
10.1.36-MariaDB

```

这是输出。

## CakePHP 获取

`fetch()`方法在执行 SQL 语句后返回结果集的下一行。 可以提取行以包含列作为名称或位置。 如果结果集中没有剩余行，则返回`false`。

`fetch_rows.php`

```php
<?php

require __DIR__ . '/vendor/autoload.php';

use Cake\Database\Connection;
use Cake\Database\Driver\Mysql;

$driver = new Mysql([
    'database' => 'mydb',
    'username' => 'root',
    'password' => 's$cret',
]);

$conn = new Connection([
    'driver' => $driver,
]);

$stm = $conn->execute('SELECT * FROM countries');

while ($row = $stm->fetch('assoc')) {
    echo "{$row['id']} {$row['name']}  {$row['population']}\n";
}

```

该示例从`countries`表中提取所有行。

```php
$stm = $conn->execute('SELECT * FROM countries');

```

使用`execute()`执行查询。

```php
while ($row = $stm->fetch('assoc')) {
    echo "{$row['id']} {$row['name']}  {$row['population']}\n";
}

```

我们在`while`循环中使用`fetch()`获取所有行。

```php
$ php fetch_rows.php
1 China  1382050000
2 India  1313210000
3 USA  324666000
4 Indonesia  260581000
5 Brazil  207221000
6 Pakistan  196626000
7 Nigeria  186988000
8 Bangladesh  162099000
9 Nigeria  186988000
10 Russia  146838000
11 Japan  126830000

```

This is the output.

## CakePHP 插入

使用`insert()`将新行添加到数据库。

`insert_row.php`

```php
<?php

require __DIR__ . '/vendor/autoload.php';

use Cake\Database\Connection;
use Cake\Database\Driver\Mysql;

$driver = new Mysql([
    'database' => 'mydb',
    'username' => 'root',
    'password' => 's$cret',
]);

$conn = new Connection([
    'driver' => $driver,
]);

$conn->insert('countries', ['name' => 'Ethiopia', 'population' => 102403196]);

```

该示例在`countries`表中插入新行。

## 参数化查询

参数化查询可防止 SQL 注入攻击。 `execute()`方法采用第二个参数中要绑定的值和第三个参数中的值的类型。

`parametrized.php`

```php
<?php

require __DIR__ . '/vendor/autoload.php';

use Cake\Database\Connection;
use Cake\Database\Driver\Mysql;

$driver = new Mysql([
    'database' => 'mydb',
    'username' => 'root',
    'password' => 's$cret',
]);

$conn = new Connection([
    'driver' => $driver,
]);

$stm = $conn->execute('SELECT * FROM countries WHERE id = :id',
    ['id' => 1], ['id' => 'integer']);

$row = $stm->fetch();

echo "$row[0] $row[1] $row[2]\n";

```

该示例使用参数化查询选择特定行。

```php
$stm = $conn->execute('SELECT * FROM countries WHERE id = :id',
    ['id' => 1], ['id' => 'integer']);

```

`:id`是一个占位符，与第二个参数中指定的值绑定。 要绑定的参数的类型在第三个参数中给出。

```php
$ php parametrized.php
1 China 1382050000

```

This is the output.

## CakePHP 查询构建器

查询构建器为创建和运行数据库查询提供了方便，流畅的界面。 它是对运行 SQL 语句的低级详细信息的抽象。 它可以使程序员避免过程的复杂性。

`query_builder.php`

```php
<?php

require __DIR__ . '/vendor/autoload.php';

use Cake\Database\Connection;
use Cake\Database\Driver\Mysql;

$driver = new Mysql([
    'database' => 'mydb',
    'username' => 'root',
    'password' => 's$cret',
]);

$conn = new Connection([
    'driver' => $driver,
]);

$query = $conn->newQuery();
$query->select(['id', 'name']);
$query->from('countries');
$query->where(['id >' => 4])->andWhere(['id <' => 10]);

$rows = $query->execute();

foreach ($rows as $row) {
    echo "{$row[0]} {$row[1]}\n";
}

```

该示例从`countries`表中检索 ID 大于 4 且小于 10 的行。

```php
$query = $conn->newQuery();

```

使用`newQuery()`创建查询构建器。

```php
$query->select(['id', 'name']);
$query->from('countries');
$query->where(['id >' => 4])->andWhere(['id <' => 10]);

```

该查询是使用流利的方法调用构建的。

```php
$ php query_builder.php
5 Brazil
6 Pakistan
7 Nigeria
8 Bangladesh
9 Nigeria

```

This is the output.

## 计数行

可以使用`func()`方法创建许多常用功能。

`count_rows.php`

```php
<?php

require __DIR__ . '/vendor/autoload.php';

use Cake\Database\Connection;
use Cake\Database\Driver\Mysql;

$driver = new Mysql([
    'database' => 'mydb',
    'username' => 'root',
    'password' => 's$cret',
]);

$conn = new Connection([
    'driver' => $driver,
]);

$query = $conn->newQuery();
$query->select(['count'  => $query->func()->count('*')]);
$query->from('countries');

$stm = $query->execute();
$n = $stm->fetch()[0];

echo "There are {$n} countries in the table\n";

```

该示例计算表中的行数。

```php
$ php count_rows.php
There are 12 countries in the table

```

This is the output.

## CakePHP 的表达方式

`in()`表达式允许创建`IN` SQL 子句。

`in_expr.php`

```php
<?php

require __DIR__ . '/vendor/autoload.php';

use Cake\Database\Connection;
use Cake\Database\Driver\Mysql;

$driver = new Mysql([
    'database' => 'mydb',
    'username' => 'root',
    'password' => 's$cret',
]);

$conn = new Connection([
    'driver' => $driver,
]);

$query = $conn->newQuery();
$query->select(['id', 'name', 'population']);
$query->from('countries');

$query->where(function ($exp) {
    return $exp
        ->in('id', [2, 4, 6, 8, 10]);
});

$rows = $query->execute();

foreach ($rows as $row) {
    echo "{$row[0]} {$row[1]} {$row[2]}\n";
}

```

该示例使用`in()`表达式从给定的 ID 数组中选择行。

```php
$ php in_expr.php
2 India 1313210000
4 Indonesia 260581000
6 Pakistan 196626000
8 Bangladesh 162099000
10 Russia 146838000

```

This is the output.

您可能也对以下相关教程感兴趣： [PHP PDO 教程](/php/pdo/)， [Symfony 简介](/symfony/intro/)， [PHP 教程](/lang/php/)或列出[所有 PHP](/all/#php) 教程。

在本教程中，我们使用了 Doctrine QueryBuilder 和 PostgreSQL 数据库。