mysqli_fetch_all()需加MYSQLI_ASSOC参数才能返回关联数组;Python需手动zip字段名转字典;未释放结果集或大结果集全加载易致内存溢出与数据错乱。
PHP 中用
直接转数组,但要注意第二个参数
查完数据库后想直接拿到 php 数组?
是最省事的选择,但它默认返回的是二维索引数组(每行是数字下标),不是你写 sql 时字段名那种关联数组。
常见错误现象:
看到全是
,没法用
访问。
加第二个参数
:得到关联数组,字段名作键
加
:保持纯数字下标(默认行为)
加
:同时有数字和字符串键 —— 冗余,占内存,别用
示例:
Python 的
返回元组,转字典要自己配字段名
Python 的 DB-API(比如
或
)里,
默认返回的是
套
,没有字段名信息。不像 PHP 那样一个参数就能切模式。
使用场景:你想导出成
这种结构,而不是
。
立即学习
“
PHP免费学习笔记(深入)
”;
先取字段名:
再 zip 每行数据:
注意:如果用
,可以设
,之后
可直接用,但导出仍需手动转成 dict(
)
导出前没清空结果集缓存,下次查询会拿错数据
很多同学在循环中反复执行查询、导出,结果发现第二次导出的内容和第一次一样,或者报错
—— 这是因为上一次查询的结果集没读完或没释放。
典型错误操作:
后没做任何处理,又立刻执行新
。
MySQLi:必须调用
,或让变量自动销毁(函数内局部变量一般没问题)
Python:确保
/
把结果全取完;若只取部分,要用
跳过剩余结果集(尤其存储过程多结果集时)
不释放的后果:连接被占住,后续查询可能返回旧数据、报错,甚至影响并发
大结果集直接
会爆内存,得流式处理
导出几万行还行,几十万行以上还用
,PHP 报
,Python 也一样卡死 —— 不是语法问题,是设计误用。
性能影响:一次性加载所有数据进内存,GC 压力大,响应延迟高,服务容易抖动。
PHP:改用
边取边处理
Python:用
或
分批拉取
别想着“先全取再导出”,导出动作本身就可以是流式的(比如边查边写 CSV)
真正麻烦的从来不是怎么转数组,而是没想清楚数据量级和生命周期 —— 缓存没清、内存没控、字段名没对齐,三个点踩中一个,导出来的就不是“数组”,是隐患。
mysqli_fetch_all()mysqli_fetch_all()var_dump($result)[0] => "张三", [1] => 25$row['name']MYSQLI_ASSOCMYSQLI_NUMMYSQLI_BOTH$rows = mysqli_fetch_all($result, MYSQLI_ASSOC);cursor.fetchall()mysql-connector-pythonpymysqlfetchall()tupletuple[{"id": 1, "name": "李四"}, ...][(1, "李四"), (2, "王五")]columns = [col[0] for col in cursor.description][dict(zip(columns, row)) for row in cursor.fetchall()]sqlite3conn.row_factory = sqlite3.Rowrow['name']dict(row)Commands out of syncfetchall()execute()mysqli_free_result($result)fetchall()fetchone()cursor.nextset()fetchall()fetchall()Fatal error: Allowed memory size exhaustedwhile ($row = mysqli_fetch_assoc($result)) { ... }for row in cursor:fetchmany(size=1000)