この記事では、PHPPHP で設定されるクエリ構造について紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。
$stmt = $pdo->prepare("select * from zyblog_test_user"); $stmt->execute(); $row = $stmt->fetch(); print_r($row); // Array // ( // [id] => 1 // [0] => 1 // [username] => aaa // [1] => aaa // [password] => aaa // [2] => aaa // [salt] => aaa // [3] => aaa // )返された結果から判断すると、PDO オブジェクトの PDO::ATTR_DEFAULT_FETCH_MODE 属性を指定しなかったため、返されたデフォルトの PDO::FETCH_BOTH 形式になります。つまり、フィールド名と添字は次の場所に存在します。同じ時間です。実際、このメソッドは必要な FETCH_STYLE を直接指定できます。 結果セット型の指定
$row = $stmt->fetch(PDO::FETCH_ASSOC); print_r($row); // Array // ( // [id] => 2 // [username] => bbb // [password] => bbb // [salt] => 123 // ) $row = $stmt->fetch(PDO::FETCH_LAZY); print_r($row); // PDORow Object // ( // [queryString] => select * from zyblog_test_user // [id] => 3 // [username] => ccc // [password] => bbb // [salt] => c3 // ) $row = $stmt->fetch(PDO::FETCH_OBJ); print_r($row); // stdClass Object // ( // [id] => 4 // [username] => ccc // [password] => bbb // [salt] => c3 // )
while($row = $stmt->fetch()){ print_r($row); } // Array // ( // [id] => 2 // [0] => 2 // [username] => bbb // [1] => bbb // [password] => bbb // [2] => bbb // [salt] => 123 // [3] => 123 // ) // ……MySQL はカーソルをサポートしていません前述したように、カーソル操作は PDO 拡張機能によってサポートされていますが、MySQL 拡張機能はこの操作をサポートしていないことに注意してください。したがって、使用するカーソル関連のプロパティは MySQL ライブラリには影響しません。
$stmt = $pdo->prepare("select * from zyblog_test_user", [PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL]); $stmt->execute(); $row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT); print_r($row); // Array // ( // [id] => 1 // [username] => aaa // [password] => aaa // [salt] => aaa // ) $stmt = $pdo->prepare("select * from zyblog_test_user", [PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL]); $stmt->execute(); $row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_LAST); print_r($row); // Array // ( // [id] => 1 // [username] => aaa // [password] => aaa // [salt] => aaa // )カーソル操作をサポートするデータベースおよびエクステンションの場合、上記コードの fetch() の第 2 パラメータを指定した後の結果は異なります。 PDO::FETCH_ORI_NEXT はカーソルの次のデータを取得し、PDO::FETCH_ORI_LAST はカーソルの最後のデータを取得します。しかし、MySQL でのテストでは、効果はなく、結果セット内の次のデータが引き続き取得されました。
$stmt = $pdo->prepare("select * from zyblog_test_user limit 2"); $stmt->execute(); $list = $stmt->fetchAll(); print_r($list); // Array // ( // [0] => Array // ( // [id] => 1 // [0] => 1 // [username] => aaa // [1] => aaa // [password] => aaa // [2] => aaa // [salt] => aaa // [3] => aaa // ) // [1] => Array // ( // [id] => 2 // [0] => 2 // [username] => bbb // [1] => bbb // [password] => bbb // [2] => bbb // [salt] => 123 // [3] => 123 // ) // )fetchAll() は内部で fetch() を使用して、結果セットを走査して配列に割り当てるのに役立ちます。したがって、re-execute() を行わずに fetchAll() を再度呼び出すと、空のデータが取得されます。カーソルが一番下まで来たからです。
$list = $stmt->fetchAll(); print_r($list); // Array // ( // )FETCH_STYLE の指定もサポートされており、fetch() メソッドと同様に、必要な型定数を最初のパラメーターに直接割り当てることができます。
// PDO::FETCH_ASSOC $stmt = $pdo->prepare("select * from zyblog_test_user limit 2"); $stmt->execute(); $list = $stmt->fetchAll(PDO::FETCH_ASSOC); print_r($list); // Array // ( // [0] => Array // ( // [id] => 1 // [username] => aaa // [password] => aaa // [salt] => aaa // ) // [1] => Array // ( // [id] => 2 // [username] => bbb // [password] => bbb // [salt] => 123 // ) // ) // PDO::FETCH_COLUMN $stmt = $pdo->prepare("select * from zyblog_test_user limit 2"); $stmt->execute(); $list = $stmt->fetchAll(PDO::FETCH_COLUMN, 1); print_r($list); // Array // ( // [0] => aaa // [1] => bbb // ) // PDO::FETCH_CLASS class User{ function __construct($a){ echo $a, PHP_EOL; } } $stmt = $pdo->prepare("select * from zyblog_test_user limit 2"); $stmt->execute(); $list = $stmt->fetchAll(PDO::FETCH_CLASS, 'User', ['FetchAll User']); print_r($list); // FetchAll User // FetchAll User // Array // ( // [0] => User Object // ( // [id] => 1 // [username] => aaa // [password] => aaa // [salt] => aaa // ) // [1] => User Object // ( // [id] => 2 // [username] => bbb // [password] => bbb // [salt] => 123 // ) // )ご存知ですか?ここでは詳しく説明しません。FETCH_STYLE の型指定については何度もお話してきました。使い方は fetch() メソッドや query() メソッドと同じです。 PDO オブジェクト内でもほぼ同じです。ただし、データセットを取得するためにコールバックでメソッドを呼び出す形式もサポートしています。
function getValue(){ print_r(func_get_args()); } // Array // ( // [0] => 1 // [1] => aaa // [2] => aaa // [3] => aaa // ) // Array // ( // [0] => 2 // [1] => bbb // [2] => bbb // [3] => 123 // ) $stmt = $pdo->prepare("select * from zyblog_test_user limit 2"); $stmt->execute(); $list = $stmt->fetchAll(PDO::FETCH_FUNC, 'getValue'); print_r($list); // Array // ( // [0] => // [1] => // )このコードでは PDO::FETCH_FUNC を使用しており、2 番目のパラメーターはメソッド名です。このようにして、各構造体セットは、トラバーサル中に指定されたメソッドを呼び出すためのメソッド パラメーターとして使用され、func_get_args() を通じてこれらのパラメーターの内容を取得できます。このコードでは、結果セットは fetchAll() メソッドの戻り値を通じて $list 変数に割り当てられません。データは指定された getValue() メソッドに渡されているためです。
// fetchColumn $stmt = $pdo->prepare("select * from zyblog_test_user"); $stmt->execute(); $column = $stmt->fetchColumn(2); echo $column, PHP_EOL; // aaa $column = $stmt->fetchColumn(3); echo $column, PHP_EOL; // 123
fetchObject() 就不用多解释了,它和 fetchColumn() 是类似的,只是返回的是下一行数据的对象格式。同样的,它也是可以传递构造参数的,这点和 PDO 对象的 query() 中指定的 PDO::FETCH_CLASS 格式的使用是一样的。我们在第一篇文章中就有讲解。
// fetchObject $stmt = $pdo->prepare("select * from zyblog_test_user"); $stmt->execute(); $user = $stmt->fetchObject('User', ['FetchObject User']); print_r($user); // FetchObject User // User Object // ( // [id] => 1 // [username] => aaa // [password] => aaa // [salt] => aaa // )
要获得查询的结果集行数就需要我们的 rowCount() 方法了。数据库中不管是查询还是增、删、改操作,都会返回语句执行结果,也就是受影响的行数。这些信息都是通过 rowCount() 这个方法获得的。
需要注意的是,在查询语句中,有些数据是可能返回此语句的行数的。但这种方式不能保证对所有数据有效,且对可移植的应用更不要依赖这种方式。我们如果需要知道当前查询结果的数量,还是通过遍历 fetch() 或者通过 count(fetchAll()) 来根据真实查询到的结果集数量确定这一次查询的真实行数。
其实它就像是 PDO 对象的 exec() 方法所返回的数据。在不使用预处理语句的情况下,直接使用 PDO 的 exec() 方法执行 SQL 语句后,返回的也是语句执行后受影响的行数。
$stmt = $pdo->prepare("select * from zyblog_test_user"); $stmt->execute(); $rowCount = $stmt->rowCount(); echo $rowCount, PHP_EOL; // 41
$stmt = $pdo->prepare("insert into zyblog_test_user(username, password, salt) values(?, ?, ?)"); $stmt->execute(['kkk','666','k6']); $rowCount = $stmt->rowCount(); echo $rowCount, PHP_EOL; // 1 $id = $pdo->lastInsertId(); echo $rowCount, PHP_EOL; // 1 $stmt = $pdo->prepare("update zyblog_test_user set username=? where username = ?"); $stmt->execute(['ccc','cccc']); $rowCount = $stmt->rowCount(); echo $rowCount, PHP_EOL; // 25 $stmt = $pdo->prepare("update zyblog_test_user set username=? where username = ?"); $stmt->execute(['ccc','cccc']); $rowCount = $stmt->rowCount(); echo $rowCount, PHP_EOL; // 0 $stmt = $pdo->prepare("delete from zyblog_test_user where username = ?"); $stmt->execute(['ddd']); $rowCount = $stmt->rowCount(); echo $rowCount, PHP_EOL; // 11 $stmt = $pdo->prepare("delete from zyblog_test_user where username = ?"); $stmt->execute(['ddd']); $rowCount = $stmt->rowCount(); echo $rowCount, PHP_EOL; // 0
更新和删除操作在数据不存在、没有更新、没有删除的情况下都返回的是 0 。这一点我们也在 PDO 相关的第一篇文章中就说过了,对于业务来说,这种更新或删除到底算是成功还是失败呢?还是大家根据自己的实际业务情况来确定吧!
关于 PDO 和 PDOStatement 相关的内容就学习到这里了。我们完整地梳理了一遍它们两个所有的方法,也都进行了相关的测试。大家在日常使用中可能接触到的并不多,框架都已经为我们封装好了。不过对于学习来说,平常的小测试、小调试完全可以自己手写来加深记忆和理解。在深入理解了这些扩展类的使用方法后,反过来又能帮助我们更加的清楚框架是如何去封装它们的。总之,学习就是不断的从高层到底层,再从底层返回高层,循环往复,才能更加的得心应手。
测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202009/source/PHP%E4%B8%AD%E7%9A%84PDO%E6%93%8D%E4%BD%9C%E5%AD%A6%E4%B9%A0%EF%BC%88%E5%9B%9B%EF%BC%89%E6%9F%A5%E8%AF%A2%E7%BB%93%E6%9E%84%E9%9B%86.php
推荐学习:php视频教程
以上がPHP で設定されたクエリ構造を 3 分で理解できますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。