← PHP删除MySQL数据记录:DELETE语句 PHP数据排序:ORDER BY子句 →

PHP查询MySQL数据:SELECT语句

原创 2026-05-21 PHP 已有人查阅

数据库里存了一堆数据,你总得把它捞出来用。PHP里捞数据就靠SELECT语句,配合MySQLi或者PDO这两个扩展。

老规矩,mysql_query()那一套别用了。PHP 5.5开始就标记过时,后面直接砍了。现在正经干活就用MySQLi(面向过程或面向对象)和PDO。

本文用到的两个函数:

  • mysqli_num_rows() — 查查查出来多少条记录

  • mysqli_fetch_assoc() — 把当前行转成关联数组,数组的键就是表的字段名,没有更多行的时候返回NULL

SELECT语句长啥样

SELECT 字段1, 字段2 FROM 表名;

想把所有字段都捞出来,用星号:

SELECT * FROM 表名;

一个真实建议: 实际项目里尽量别用SELECT *。字段多了影响查询效率,而且你根本用不到所有字段。我们之前有个接口,一张表50多个字段,前端只用了5个,DBA找过来骂了一顿。明确写字段名,性能更好,代码也更清晰。

示例数据表

演示用的两张表:

表1:employees(员工表)

id name salary
1 张明 9000
2 李芳 40000
3 王磊 90000

表2:MyGuests(访客表)

id firstname lastname
1 Peter Parker
2 John Rambo
3 Clark Kent

MySQLi面向过程查询

这是最基础的写法,适合小型脚本和快速测试。

<?php
$host = 'localhost:3306';
$user = 'root';
$pass = '123456';
$dbname = 'company_db';

$conn = mysqli_connect($host, $user, $pass, $dbname);

if (!$conn) {
    die('连不上数据库:' . mysqli_connect_error());
}

$sql = 'SELECT id, name, salary FROM employees';
$result = mysqli_query($conn, $sql);

if (mysqli_num_rows($result) > 0) {
    while ($row = mysqli_fetch_assoc($result)) {
        echo "工号:" . $row['id'] . "<br>";
        echo "姓名:" . $row['name'] . "<br>";
        echo "工资:" . $row['salary'] . "<br>";
        echo "-------------------<br>";
    }
} else {
    echo "没有查到数据";
}

mysqli_close($conn);
?>

输出结果:

工号:1
姓名:张明
工资:9000
-------------------
工号:2
姓名:李芳
工资:40000
-------------------
工号:3
姓名:王磊
工资:90000
-------------------

原始表数据:

id name salary
1 张明 9000
2 李芳 40000
3 王磊 90000

查询后得到的数据和原表一样,因为是全量查询。

个人经验: 面向过程写法简单直接,但多人协作时容易出问题。比如你和同事都定义了$conn变量,后面的人可能不知道前面已经用过。面向对象和PDO在这一点上更清晰。

MySQLi面向对象查询

<?php
$servername = "localhost";
$username = "root";
$password = "123456";
$dbname = "company_db";

$conn = new mysqli($servername, $username, $password, $dbname);

if ($conn->connect_error) {
    die("连接失败:" . $conn->connect_error);
}

$sql = "SELECT id, firstname, lastname FROM MyGuests";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    echo "<table border='1'>";
    echo "<tr><th>ID</th><th>姓名</th></tr>";
    while ($row = $result->fetch_assoc()) {
        echo "<tr>";
        echo "<td>" . $row["id"] . "</td>";
        echo "<td>" . $row["firstname"] . " " . $row["lastname"] . "</td>";
        echo "</tr>";
    }
    echo "</table>";
} else {
    echo "没有查到数据";
}
$conn->close();
?>

原始表(MyGuests):

id firstname lastname
1 Peter Parker
2 John Rambo
3 Clark Kent

输出表格:

ID 姓名
1 Peter Parker
2 John Rambo
3 Clark Kent

说一下区别: 面向对象的写法更接近自然语言,$conn->query()一眼就知道是执行查询。而且面向对象可以配合命名空间、自动加载这些现在PHP特性,大型项目里更好维护。

PDO方式查询

PDO较大的优势是数据库抽象层。你的代码写成这样,以后从MySQL换成PostgreSQL或者SQLite,改一行连接字符串就行。

<?php
$servername = "localhost";
$username = "root";
$password = "123456";
$dbname = "company_db";

try {
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $stmt = $conn->prepare("SELECT id, firstname, lastname FROM MyGuests");
    $stmt->execute();
    
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    echo "<table border='1'>";
    echo "<tr><th>ID</th><th>名</th><th>姓</th></tr>";
    
    foreach ($result as $row) {
        echo "<tr>";
        echo "<td>" . $row['id'] . "</td>";
        echo "<td>" . $row['firstname'] . "</td>";
        echo "<td>" . $row['lastname'] . "</td>";
        echo "</tr>";
    }
    echo "</table>";
    
} catch (PDOException $e) {
    echo "查询出错:" . $e->getMessage();
}

$conn = null;
?>

原始表(MyGuests):

id firstname lastname
1 Peter Parker
2 John Rambo
3 Clark Kent

输出结果:

ID
1 Peter Parker
2 John Rambo
3 Clark Kent

个人见解: 新项目我基本都用PDO。不是说MySQLi不好,而是PDO的错误处理更优雅。上面的try-catch可以统一捕获异常,不需要每个查询都写if判断。另外PDO支持12种数据库驱动,万一公司哪天要换数据库,代码改动量很小。

fetch模式说明:

模式 作用
PDO::FETCH_ASSOC 返回关联数组,键是字段名
PDO::FETCH_NUM 返回索引数组,键是数字
PDO::FETCH_BOTH 同时返回关联和索引(默认)
PDO::FETCH_OBJ 返回对象,属性名是字段名

WHERE条件过滤数据

项目开发中很少查全表,更多是按条件筛选。WHERE子句就是干这个的。

SELECT * FROM employees WHERE salary > 30000;

原始表(employees):

id name salary
1 张明 9000
2 李芳 40000
3 王磊 90000

执行查询后:

id name salary
2 李芳 40000
3 王磊 90000

工资低于30000的张明被过滤掉了。

代码号学习编程示例 - 带WHERE条件的PDO查询:

<?php
try {
    $pdo = new PDO("mysql:host=localhost;dbname=company_db", "root", "123456");
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $min_salary = 30000;
    $stmt = $pdo->prepare("SELECT id, name, salary FROM employees WHERE salary > :min_salary");
    $stmt->bindParam(':min_salary', $min_salary);
    $stmt->execute();
    
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    foreach ($results as $emp) {
        echo $emp['name'] . " - " . $emp['salary'] . "<br>";
    }
    
} catch (PDOException $e) {
    echo "查询失败:" . $e->getMessage();
}
?>

常见WHERE条件组合:

-- 等值条件
SELECT * FROM users WHERE status = 'active';

-- 范围条件
SELECT * FROM orders WHERE amount BETWEEN 100 AND 500;

-- 模糊匹配
SELECT * FROM products WHERE name LIKE '%手机%';

-- 多条件
SELECT * FROM employees WHERE department = '技术部' AND salary > 15000;

-- 日期条件
SELECT * FROM logs WHERE created_at > '2026-01-01';

为什么SELECT查询如此重要

大部分应用的核心功能就是展示数据。管理后台的列表页、前端的商品展示、报表系统的统计图表、API接口的JSON输出,背后都是SELECT语句在支撑。

不同场景选不同的技术栈:

  • 简单脚本或WordPress插件开发 → MySQLi面向过程

  • 中型项目、团队协作 → MySQLi面向对象

  • 跨数据库项目、注重安全性 → PDO

  • 微服务架构 → PDO + 连接池

本节课程知识要点

  1. 明确字段名代替SELECT *** —— 减少不必要的数据传输,提高查询效率

  2. WHERE条件要加索引 —— 如果经常用某个字段做过滤条件,记得建索引。我们有个订单表,一开始没在status字段建索引,全表扫描200万条数据,接口响应3秒多。加了索引之后降到50毫秒。

  3. fetch模式按需选择 —— 不需要数字索引就用PDO::FETCH_ASSOC,省内存

  4. 预处理语句不仅用于写入 —— SELECT同样可以用预处理,配合WHERE条件防止SQL注入

  5. 结果集数量限制 —— 查大量数据时用LIMIT分页,别一次全查出来

// 分页查询示例
$page = 1;
$limit = 20;
$offset = ($page - 1) * $limit;
$stmt = $pdo->prepare("SELECT * FROM logs ORDER BY id DESC LIMIT :limit OFFSET :offset");

调试技巧

查不到数据的时候,先做这几步:

  1. 直接在数据库客户端跑一遍SQL,确认语句没问题

  2. 检查连接参数(主机、用户名、密码、库名)

  3. 打印SQL语句看看变量替换后的实际内容

  4. 用errorInfo()获取PDO的详细错误信息

if (!$stmt->execute()) {
    print_r($stmt->errorInfo());
}
← PHP删除MySQL数据记录:DELETE语句 PHP数据排序:ORDER BY子句 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号