tommyknocker / pdo-database-class
PHP PDO 包装器,利用 PDO 和预编译语句
Requires
- php: >=5.5.0
- ext-pdo: *
Requires (Dev)
- phpunit/phpunit: ^5.0
This package is auto-updated.
Last update: 2024-09-20 09:58:51 UTC
README
PHP PDO 包装器,利用 PDO 和预编译语句
目录
- 初始化
- 插入查询
- 更新查询
- 选择查询
- 删除查询
- 分页
- 运行原始 SQL 查询
- 查询关键字
- WHERE 条件
- ORDER 条件
- GROUP 条件
- 属性共享
- 表连接
- 子查询
- EXISTS / NOT EXISTS 条件
- has 方法
- 辅助方法
- 事务辅助
- 错误辅助
支持我
这款软件是在我的业余时间开发的,如果有人支持我,我将非常高兴。
每个人的时间都应该很有价值,所以请考虑捐赠。
安装
要使用此类,请首先将 PDODb.php 导入到您的项目中,并要求它。PDODb 需要 PHP 5.5+ 才能工作。
require_once ('PDODb.php');
使用 composer 安装
还可以通过 composer 安装库
composer require tommyknocker/pdo-database-class
初始化
简单的初始化,默认设置 utf8 字符集
$db = new PDODb('host', 'username', 'password', 'databaseName');
高级初始化
$db = new PDODb(['type' => 'mysql', 'host' => 'host', 'username' => 'username', 'password' => 'password', 'dbname'=> 'databaseName', 'port' => 3306, 'prefix' => 'my_', 'charset' => 'utf8']);
表前缀、端口号和数据库字符集参数是可选的。如果不设置字符集,则将其设置为 null
还可以重用已经连接的 PDO 对象
$pdo = new PDO('mysql:dbname=test;host=localhost', 'user', 'password'); $db = new PDODb($pdo);
如果在创建对象期间没有设置表前缀,可以在单独的调用中设置它
$db->setPrefix('my_');
如果您需要从另一个类或函数中获取已经创建的 PDO 对象,请使用
function init() { // db staying private here $db = new PDODb('type', 'host', 'username', 'password', 'databaseName'); } ... function myfunс() { // obtain db object created in init() $db = PDODb::getInstance(); ... }
插入查询
简单示例
$data = ["login" => "admin", "firstName" => "John", "lastName" => 'Doe' ]; $id = $db->insert('users', $data); if($id) echo 'user was created. Id=' . $id;
使用函数插入
$data = [ 'login' => 'admin', 'active' => true, 'firstName' => 'John', 'lastName' => 'Doe', 'password' => $db->func('SHA1(?)',Array ("secretpassword+salt")), // password = SHA1('secretpassword+salt') 'createdAt' => $db->now(), // createdAt = NOW() 'expires' => $db->now('+1Y') // expires = NOW() + interval 1 year // Supported intervals [s]econd, [m]inute, [h]hour, [d]day, [M]onth, [Y]ear ]; $id = $db->insert('users', $data); if ($id) { echo 'user was created. Id=' . $id; } else { echo 'insert failed: ' . $db->getLastError(); }
使用 ON DUPLICATE KEY UPDATE 插入
$data = ["login" => "admin", "firstName" => "John", "lastName" => 'Doe', "createdAt" => $db->now(), "updatedAt" => $db->now(), ]; $updateColumns = ["updatedAt"]; $lastInsertId = "id"; $db->onDuplicate($updateColumns, $lastInsertId); $id = $db->insert('users', $data);
替换查询
Replace() 方法实现了与 insert() 相同的 API
更新查询
$data = ['firstName' => 'Bobby', 'lastName' => 'Tables', 'editCount' => $db->inc(2), // editCount = editCount + 2; 'active' => $db->not() // active = !active; ]; $db->where('id', 1); if ($db->update('users', $data)) { echo $db->getRowCount() . ' records were updated'; } else { echo 'update failed: ' . $db->getLastError(); }
update() 也支持 limit 参数
$db->update('users', $data, 10); // Gives: UPDATE users SET ... LIMIT 10
选择查询
在任何 select/get 函数调用之后,数量或返回的行数都存储在 $count 变量中
$users = $db->get('users'); //contains an Array of all users $users = $db->get('users', 10); //contains an Array 10 users
或选择自定义列。函数也可以使用
$cols = ["id", "name", "email"]; $users = $db->get("users", null, $cols); if ($users) { foreach ($users as $user) { print_r ($user); } }
或只选择一行
$db->where("id", 1); $user = $db->getOne("users"); echo $user['id']; $stats = $db->getOne("users", "SUM(id), COUNT(*) as cnt"); echo "total ".$stats['cnt']. "users found";
或选择一个列值或函数结果
$count = $db->getValue("users", "COUNT(*)"); echo "{$count} users found";
从多行中选择一个列值或函数结果
$logins = $db->getValue("users", "login", null); // select login from users $logins = $db->getValue("users", "login", 5); // select login from users limit 5 foreach ($logins as $login) { echo $login; }
您可以使用 php 5.5+ 生成器功能与 PDODb get()、rawQuery() 方法一起使用,只需调用 useGenerator(true) 方法即可
示例
$result = $db->useGenerator(true)->get('users'); // $result will contain Generator object if($result->current()) { foreach($result as $row) { print_r($row); } }
分页
使用 paginate() 而不是 get() 来获取分页结果
$page = 1; // set page limit to 2 results per page. 20 by default $db->pageLimit = 2; $products = $db->paginate("products", $page); echo "showing $page out of " . $db->totalPages;
定义返回类型
要选择返回类型,请使用 setReturnType() 方法。
// Array return type $= $db->getOne("users"); echo $u['login']; // Object return type $u = $db->setReturnType(PDO::FETCH_OBJ)->getOne("users"); echo $u->login;
运行原始 SQL 查询
$users = $db->rawQuery('SELECT * FROM users WHERE id >= ?', [10]); foreach ($users as $user) { print_r($user); } $users = $db->rawQuery('SELECT * FROM users WHERE name=:name', ['name' => 'user1']); foreach ($users as $user) { print_r($user); }
为了避免长 if 检查,有一些辅助函数可以与原始查询选择结果一起使用
获取 1 行结果
$user = $db->rawQueryOne('SELECT * FROM users WHERE id=:id', [id => 10]); echo $user['login']; // Object return type $user = $db->setReturnType(PDO::FETCH_OBJ)->rawQueryOne('SELECT * FROM users WHERE id=?', [10]); echo $user->login;
获取 1 个列值作为字符串
$password = $db->rawQueryValue('SELECT password FROM users WHERE id=? LIMIT 1', [10]); echo "Password is {$password}"; NOTE: for a rawQueryValue() to return string instead of an array 'limit 1' should be added to the end of the query.
获取多行中的 1 个列值
$logins = $db->rawQueryValue('SELECT login FROM users LIMIT 10'); foreach ($logins as $login) { echo $login; }
更高级的示例
$params = [1, 'admin']; $users = $db->rawQuery("SELECT id, firstName, lastName FROM users WHERE id = ? AND login = ?", $params); print_r($users); // contains Array of returned rows // will handle any SQL query $params = [10, 1, 10, 11, 2, 10]; $query = "( SELECT a FROM t1 WHERE a = ? AND B = ? ORDER BY a LIMIT ? ) UNION ( SELECT a FROM t2 WHERE a = ? AND B = ? ORDER BY a LIMIT ? )"; $result = $db->rawQuery($query, $params); print_r ($result); // contains array of returned rows
WHERE / HAVING 方法
where()、orWhere()、having() 和 orHaving() 方法允许您指定查询的 WHERE 和 HAVING 条件。where() 支持的所有条件都由 having() 支持。
警告:为了使用列与列的比较,只能使用原始 WHERE 条件作为列名或不能将函数作为绑定变量传递。
带有变量的常规 == 运算符
$db->where('id', 1); $db->where('login', 'admin'); $results = $db->get('users'); // Gives: SELECT * FROM users WHERE id=1 AND login='admin';
$db->where ('id', 1); $db->having ('login', 'admin'); $results = $db->get ('users'); // Gives: SELECT * FROM users WHERE id=1 HAVING login='admin';
列与列之间比较的常规 == 运算符
// WRONG $db->where('lastLogin', 'createdAt'); // CORRECT $db->where('lastLogin = createdAt'); $results = $db->get('users'); // Gives: SELECT * FROM users WHERE lastLogin = createdAt;
$db->where('id', 50, ">="); // or $db->where('id', ['>=' => 50]); $results = $db->get('users'); // Gives: SELECT * FROM users WHERE id >= 50;
BETWEEN / NOT BETWEEN
$db->where('id', [4, 20], 'BETWEEN'); $results = $db->get('users'); // Gives: SELECT * FROM users WHERE id BETWEEN 4 AND 20
IN / NOT IN
$db->where('id', [1, 5, 27, -1, 'd'], 'IN'); $results = $db->get('users'); // Gives: SELECT * FROM users WHERE id IN (1, 5, 27, -1, 'd');
OR CASE
$db->where('firstName', 'John'); $db->orWhere('firstName', 'Peter'); $results = $db->get('users'); // Gives: SELECT * FROM users WHERE firstName='John' OR firstName='peter'
$db->where('firstName', 'John'); $db->orWhere('firstName', 'Peter'); $results = $db->get('users'); // Gives: SELECT * FROM users WHERE firstName='John' OR firstName='peter'
NULL 比较
$db->where("lastName", NULL, 'IS NOT'); $results = $db->get("users"); // Gives: SELECT * FROM users where lastName IS NOT NULL
您还可以使用原始 WHERE 条件
$db->where("id != companyId"); $db->where("DATE(createdAt) = DATE(lastLogin)"); $results = $db->get("users");
或带有变量的原始条件
$db->where("(id = ? OR id = ?)", [6,2]); $db->where("login","mike") $res = $db->get ("users"); // Gives: SELECT * FROM users WHERE (id = 6 OR id = 2) AND login='mike';
查找匹配的总行数。简单的分页示例
$offset = 10; $count = 15; $users = $db->withTotalCount()->get('users', [$offset, $count]); echo "Showing {$count} from {$db->totalCount}";
查询关键字
可以将 LOW PRIORITY | DELAYED | HIGH PRIORITY | IGNORE 以及其余的 mysql 关键字添加到 INSERT ()、REPLACE ()、GET ()、UPDATE ()、DELETE() 方法或 FOR UPDATE | LOCK IN SHARE MODE 中 SELECT ()
$db->setQueryOption('LOW_PRIORITY')->insert($table, $param); // GIVES: INSERT LOW_PRIORITY INTO table ...
$db->setQueryOption('FOR UPDATE')->get('users'); // GIVES: SELECT * FROM USERS FOR UPDATE;
您还可以使用关键字数组
$db->setQueryOption(['LOW_PRIORITY', 'IGNORE'])->insert($table,$param); // GIVES: INSERT LOW_PRIORITY IGNORE INTO table ...
同样,关键字也可以用在 SELECT 查询中
$db->setQueryOption('SQL_NO_CACHE'); $db->get("users"); // GIVES: SELECT SQL_NO_CACHE * FROM USERS;
可选地,您可以使用方法链来多次调用 where 而不重复引用您的对象
$results = $db ->where('id', 1) ->where('login', 'admin') ->get('users');
删除查询
$db->where('id', 1); if($db->delete('users')) echo 'successfully deleted';
排序方法
$db->orderBy("id","ASC"); $db->orderBy("login","DESC"); $db->orderBy("RAND ()"); $results = $db->get('users'); // Gives: SELECT * FROM users ORDER BY id ASC,login DESC, RAND ();
按值排序示例
$db->orderBy('userGroup', 'ASC', ['superuser', 'admin', 'users']); $db->get('users'); // Gives: SELECT * FROM users ORDER BY FIELD (userGroup, 'superuser', 'admin', 'users') ASC;
如果您使用 setPrefix () 功能并且需要在 orderBy() 方法中使用表名,请确保表名被反引号 `` 包围。
$db->setPrefix("t_"); $db->orderBy("users.id","ASC"); $results = $db->get('users'); // WRONG: That will give: SELECT * FROM t_users ORDER BY users.id ASC; $db->setPrefix("t_"); $db->orderBy("`users`.id", "ASC"); $results = $db->get('users'); // CORRECT: That will give: SELECT * FROM t_users ORDER BY t_users.id ASC;
分组方法
$db->groupBy("name"); $results = $db->get('users'); // Gives: SELECT * FROM users GROUP BY name;
通过 tenantID 使用 LEFT JOIN 将产品表与用户表连接
JOIN 方法
$db->join("users u", "p.tenantID=u.tenantID", "LEFT"); $db->where("u.id", 6); $products = $db->get("products p", null, "u.name, p.productName"); print_r($products);
属性共享
也可以复制属性
$db->where("agentId", 10); $db->where("active", true); $customers = $db->copy(); $res = $customers->get("customers", [10, 10]); // SELECT * FROM customers where agentId = 10 and active = 1 limit 10, 10 $cnt = $db->getValue("customers", "COUNT(id)"); echo "total records found: " . $cnt; // SELECT COUNT(id) FROM users WHERE agentId = 10 AND active = 1
子查询
子查询初始化
子查询初始化,不带别名用于插入/更新/where。例如:(select * from users)
$sq = $db->subQuery(); $sq->get("users");
指定别名的子查询,用于 JOIN。例如:(select * from users) sq
$sq = $db->subQuery("sq"); $sq->get("users");
子查询在 SELECT 中的使用
$ids = $db->subQuery (); $ids->where("qty", 2, ">"); $ids->get("products", null, "userId"); $db->where("id", $ids, 'in'); $res = $db->get("users"); // Gives SELECT * FROM users WHERE id IN (SELECT userId FROM products WHERE qty > 2)
子查询在 INSERT 中的使用
$userIdQ = $db->subQuery (); $userIdQ->where("id", 6); $userIdQ->getOne("users", "name"); $data = ["productName" => "test product", "userId" => $userIdQ, "lastUpdated" => $db->now() ]; $id = $db->insert("products", $data); // Gives INSERT INTO PRODUCTS (productName, userId, lastUpdated) values ("test product", (SELECT name FROM users WHERE id = 6), NOW());
子查询在 JOIN 中的使用
$usersQ = $db->subQuery("u"); $usersQ->where("active", 1); $usersQ->get("users"); $db->join($usersQ, "p.userId=u.id", "LEFT"); $products = $db->get("products p", null, "u.login, p.productName"); print_r($products); // SELECT u.login, p.productName FROM products p LEFT JOIN (SELECT * FROM t_users WHERE active = 1) u on p.userId=u.id;
EXISTS / NOT EXISTS 条件
$sub = $db->subQuery(); $sub->where("company", 'testCompany'); $sub->get ("users", null, 'userId'); $db->where (null, $sub, 'EXISTS'); $products = $db->get ("products"); // Gives SELECT * FROM products WHERE EXISTS (select userId from users where company='testCompany')
has 方法
一个方便的函数,如果存在至少一个满足之前调用 "where" 方法的 where 条件的元素,则返回 TRUE。
$db->where("user", $user); $db->where("password", md5($password)); if($db->has("users")) { return "You are logged"; } else { return "Wrong user/password"; }
辅助方法
获取最后执行的 SQL 查询:请注意,此函数仅用于调试目的,因为它返回的 SQL 查询由于缺少字符变量的引号而可能无法执行。
$db->get('users'); echo "Last executed query was ". $db->getLastQuery();
检查表是否存在
if ($db->tableExists('users')) { echo "hooray"; }
pdo::quote() 包装器
$escaped = $db->escape("' and 1=1");
事务辅助函数
请注意,事务是在 innoDB 表上运行的。如果插入失败,则回滚事务
$db->startTransaction(); ... if (!$db->insert('myTable', $insertData)) { //Error while saving, cancel new record $db->rollback(); } else { //OK $db->commit(); }
错误辅助函数
在执行查询后,您可以选择检查是否发生错误。您可以获取最后一个执行的查询的 MySQL 错误字符串或错误代码。
$db->where('login', 'admin')->update('users', ['firstName' => 'Jack']); if ($db->getLastErrNo() === 0) { echo 'Update succesfull'; } else { echo 'Update failed. Error: '. $db->getLastError(); }