daidesarano / embryo-pdo
Embryo PDO 是一个使用 PDO 的 PHP SQL 查询构建器。
Requires
- php: >=7.1
- davidecesarano/embryo-http: dev-master
Requires (Dev)
- phpstan/phpstan: ^0.12.40
README
一个快速轻量级的 PHP 查询构建器,使用 PDO。
$users = $pdo->table('users') ->where('country', 'Italy') ->and('city', 'Naples') ->and(function($query) { $query ->where('age', 20) ->or('age', 30) }) ->andIsNotNull('updated_at') ->andIn('roles', [1, 2, 3]) ->get();
要求
- PHP >= 7.1
安装
使用 Composer
$ composer require davidecesarano/embryo-pdo
用法
连接
通过在 Database
对象中创建一个多维数组形式的数据库参数,然后使用 connection
方法建立连接。
$database = [ 'local' => [ 'engine' => 'mysql', 'host' => '127.0.0.1', 'name' => 'db_name', 'user' => 'user', 'password' => 'password', 'charset' => 'utf8mb4', 'options' => [ \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION ] ] ]; $database = new Embryo\PDO\Database($database); $pdo = $database->connection('local');
检索结果
您可以创建一个简单的查询
$users = $pdo->table('users')->get();
table
方法返回一个针对给定表的流畅查询构建器实例。这将构建以下查询
SELECT * FROM users
要从选择中获取数据,我们可以遍历返回的对象数组
foreach ($users as $user) { echo $user->name; }
检索单行
如果您只需要从数据库表中检索单行,您可以使用相同的 (get
) 方法。
$user = $pdo->table('users') ->where('id', 1) ->get(); echo $user->name;
如果您甚至不需要整行,您可以使用 select
方法从记录中提取一个或多个值。
$user = $pdo->table('users') ->select('name, surname') ->where('id', 1) ->get(); echo "Hi, i am $user->name $user->surname";
强制数组
如果您想强制返回对象数组,可以使用 all
方法
$user = $pdo->table('users') ->where('id', 1) ->all(); foreach ($users as $user) { echo $user->name; }
聚合
查询构建器还提供各种聚合方法,如 count
、max
、min
、avg
和 sum
。
$avg = $pdo->table('orders')->avg('price'); echo $avg;
WHERE 条件
简单 WHERE
您可以使用 where
方法向查询添加 WHERE 子句。where 方法的最基本调用需要三个参数。第一个参数是列名。第二个参数是一个运算符,可以是数据库支持的任何运算符。最后,第三个参数是要与列进行比较的值。
$users = $pdo->table('users') ->where('id', '>', 1) ->get();
为了方便起见,如果您想验证列是否等于某个给定的值,您可以直接将值作为第二个参数传递给 where 方法
$user = $pdo->table('users') ->where('id', 1) ->get();
在编写 WHERE 子句时,您可以使用各种其他运算符
$user = $pdo->table('users') ->where('country', 'Italy') ->and('name', 'LIKE', 'David%') ->get();
OR 条件
您还可以将 WHERE 约束链接在一起,以及向查询添加 "or" 子句。
$user = $pdo->table('users') ->where('country', 'Italy') ->or('country', 'Spain') ->get();
AND/OR 闭包
如果您需要在括号内分组 "or" 或 "and" 条件,您可以传递一个闭包作为方法的第一参数
$user = $pdo->table('users') ->where('country', 'Italy') ->and(function($query){ $query ->where('country', 'Spain') ->or('country', 'France') }) ->get();
这将构建以下查询
SELECT * FROM users WHERE country = 'Italy' AND ( country = 'Spain' OR country = 'France' )
BETWEEN 条件
whereBetween
/ whereNotBetween
方法验证列的值是否在两个值之间
$user = $pdo->table('users') ->whereBetween('age', [20, 30]) ->get(); $user = $pdo->table('users') ->whereNotBetween('age', [20, 30]) ->get();
IN 条件
whereIn
/ whereNotIn
方法验证给定列的值是否包含在给定的数组中
$user = $pdo->table('users') ->whereIn('age', [20, 30]) ->get(); $user = $pdo->table('users') ->whereNotIn('age', [20, 30]) ->get();
IS NULL 条件
whereNull
/ whereNotNull
方法验证给定列的值是否为 NULL
或不是 NULL
$user = $pdo->table('users') ->whereNull('updated_at') ->get(); $user = $pdo->table('users') ->whereNotNull('updated_at') ->get()
原始 WHERE
rawWhere
方法可以将原始 WHERE 条件注入到您的查询中。此方法接受一个绑定参数的数组。
$users = $pdo->table('users') ->rawWhere('WHERE age = :age AND role = :role', [ 'age' => 20, 'role' => 1 ]) ->get();
方法别名
以下是一个表格,列出了所有 WHERE 条件的方法和它们的别名。
连接
查询构建器还可以使用 leftJoin
、rightJoin
、crossJoin
、innerJoin
或 rawJoin
方法编写简单的连接语句
// left join $users = $pdo->table('users') ->leftJoin('roles ON roles.id = users.role_id') ->select('users.*', 'roles.name') ->get(); // right join $users = $pdo->table('users') ->rightJoin('roles ON roles.id = users.role_id') ->select('users.*', 'roles.name') ->get(); // cross join $users = $pdo->table('users') ->crossJoin('roles ON roles.id = users.role_id') ->select('users.*', 'roles.name') ->get(); // inner join $users = $pdo->table('users') ->innerJoin('roles ON roles.id = users.role_id') ->select('users.*', 'roles.name') ->get(); // raw join $users = $pdo->table('users') ->rawJoin('LEFT JOIN roles ON roles.id = users.role_id') ->select('users.*', 'roles.name') ->get();
插入
您可以使用insert
方法向数据库中插入行。
$lastInsertedId = $pdo->table('users') ->insert([ 'name' => 'Name', 'surname' => 'Surname' ]) ->lastId();
这将返回最后插入的ID。insert方法还接受exec()
方法,成功时返回true,失败时返回false。
更新
您可以使用update
方法更新行。
$update = $pdo->table('users') ->where('id', 1) ->update([ 'name' => 'Name', 'surname' => 'Surname' ]) ->exec(); // $update return TRUE or FALSE
删除
您可以使用delete
方法删除行。
$delete = $pdo->table('users') ->where('id', 1) ->delete() ->exec(); // $delete return TRUE or FALSE
排序、分组、限制和偏移
您可以使用groupBy
方法对查询结果进行分组。
$users = $pdo->table('users') ->groupBy('role') ->get();
orderBy
方法允许您按给定列对查询结果进行排序
$users = $pdo->table('users') ->orderBy('id DESC') ->get();
您可以使用limit
方法限制查询返回的结果数量
$users = $pdo->table('users') ->limit('0,10') ->get();
要跳过查询中的给定数量的结果,您可以使用limit
和offset
方法
$users = $pdo->table('users') ->limit('10') ->offset(5) ->get();
原始查询
有时您可能需要在查询中使用原始表达式。要创建原始表达式,您可以使用query
方法
$users = $pdo->query(" SELECT users.*, roles.name FROM users LEFT JOIN roles ON roles.id = users.role_id WHERE users.city = :city ORDER BY users.id DESC ")->values([ 'city' => 'Naples' ])->get();
values
方法将值绑定到参数。将值绑定到SQL语句中用于准备语句的对应命名占位符。
分页
分页意味着将所有获取的结果显示在多个页面上,而不是在一页上显示所有内容。要更改页面编号,请使用URI中的page
查询参数(http://example.com/?page=1
)。
$perPage = 15; $users = $pdo->table("users")->paginate($perPage);
我们将得到以下结果
{ "total": 50, "per_page": 15, "current_page": 1, "last_page": 4, "first_page": 1, "next_page": 2, "prev_page": null, "from": 1, "to": 15, "data":[ { // Record... }, { // Record... } ] }
如果您想从记录中检索特定字段,可以使用
$perPage = 15; $users = $pdo->table("users")->select('id, first_name, last_name')->paginate($perPage);
安全性
Embryo PDO使用PDO参数绑定
来保护您的应用程序免受SQL注入攻击。不需要清理作为绑定传递的字符串。
调试
您可以使用debug
方法将预处理语句包含的信息直接输出到输出。
$fruits = $pdo->table('fruit') ->where('calories', '<', 30) ->and('colour', 'red') ->select('name', 'colour', 'calories') ->debug()
这将构建以下输出
SQL: [96] SELECT name, colour, calories FROM fruit WHERE calories < :calories AND colour = :colour Params: 2 Key: Name: [9] :calories paramno=-1 name=[9] ":calories" is_param=1 param_type=1 Key: Name: [7] :colour paramno=-1 name=[7] ":colour" is_param=1 param_type=2
如果您只想显示查询,您可以打印对象
echo $pdo->table('fruit') ->select('name', 'colour', 'calories') ->where('calories', '<', 30) ->and('colour', 'red') ->print();
这将构建以下输出
SELECT name, colour, calories FROM fruit WHERE calories < :calories AND colour = :colour