php一步一步实现mysql协议(四)——执行命令

时间:2022-07-25
本文章向大家介绍php一步一步实现mysql协议(四)——执行命令,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

执行命令消息

发送完认证请求之后,服务端返回 OK Response ,然后就可以发送执行命令消息了;报文结构为

例如

  其中前四位属于消息头,包含消息体的长度和消息id,消息体部分包括 命令id和执行参数。这里命令id=3表示该命令是 SQL查询请求,后面跟着的是具体执行命令 “select * from users”。命令id代表的含义如下:

类型值

命令

功能

关联函数

0x00

COM_SLEEP

(内部线程状态)

(无)

0x01

COM_QUIT

关闭连接

mysql_close

0x02

COM_INIT_DB

切换数据库

mysql_select_db

0x03

COM_QUERY

SQL查询请求

mysql_real_query

0x04

COM_FIELD_LIST

获取数据表字段信息

mysql_list_fields

0x05

COM_CREATE_DB

创建数据库

mysql_create_db

0x06

COM_DROP_DB

删除数据库

mysql_drop_db

0x07

COM_REFRESH

清除缓存

mysql_refresh

0x08

COM_SHUTDOWN

停止服务器

mysql_shutdown

0x09

COM_STATISTICS

获取服务器统计信息

mysql_stat

0x0A

COM_PROCESS_INFO

获取当前连接的列表

mysql_list_processes

0x0B

COM_CONNECT

(内部线程状态)

(无)

0x0C

COM_PROCESS_KILL

中断某个连接

mysql_kill

0x0D

COM_DEBUG

保存服务器调试信息

mysql_dump_debug_info

0x0E

COM_PING

测试连通性

mysql_ping

0x0F

COM_TIME

(内部线程状态)

(无)

0x10

COM_DELAYED_INSERT

(内部线程状态)

(无)

0x11

COM_CHANGE_USER

重新登陆(不断连接)

mysql_change_user

0x12

COM_BINLOG_DUMP

获取二进制日志信息

(无)

0x13

COM_TABLE_DUMP

获取数据表结构信息

(无)

0x14

COM_CONNECT_OUT

(内部线程状态)

(无)

0x15

COM_REGISTER_SLAVE

从服务器向主服务器进行注册

(无)

0x16

COM_STMT_PREPARE

预处理SQL语句

mysql_stmt_prepare

0x17

COM_STMT_EXECUTE

执行预处理语句

mysql_stmt_execute

0x18

COM_STMT_SEND_LONG_DATA

发送BLOB类型的数据

mysql_stmt_send_long_data

0x19

COM_STMT_CLOSE

销毁预处理语句

mysql_stmt_close

0x1A

COM_STMT_RESET

清除预处理语句参数缓存

mysql_stmt_reset

0x1B

COM_SET_OPTION

设置语句选项

mysql_set_server_option

0x1C

COM_STMT_FETCH

获取预处理语句的执行结果

mysql_stmt_fetch

当客户端发送查询请求后,在没有错误的情况下,服务器会返回结果集(Result Set)给客户端。

Result Set 消息分为五部分,结构如下:

结构

说明

[Result Set Header]

列数量

[Field]

列信息(多个)

[EOF]

列结束

[Row Data]

行数据(多个)

[EOF]

数据结束

Result Set Header 结构

字节

说明

1-9

Field结构计数(Length Coded Binary)

1-9

额外信息(Length Coded Binary)

示例:

Result Set Field 结构

字节

说明

n

目录名称(Length Coded String)

n

数据库名称(Length Coded String)

n

数据表名称(Length Coded String)

n

数据表原始名称(Length Coded String)

n

列(字段)名称(Length Coded String)

4

列(字段)原始名称(Length Coded String)

1

填充值

2

字符编码

4

列(字段)长度

1

列(字段)类型

2

列(字段)标志

1

整型值精度

2

填充值(0x00)

n

默认值(Length Coded String)

示例:

Result Row Data 结构:

字节

说明

n

字段值(Length Coded String)

...

(一行数据中包含多个字段值)

示例:

  header结构体和field结构体报文中由于每个参数的字段都含有固定的位数,所以获取数据的时候只要按照固定位数截取数据就可以获取到响应参数数值。但是 row data 结构体的数据并没有固定的位数所以获取方式与上面两种不同,其应该先获取消息体重的首位字节数据并将其转为整数,该字节后面的长度数据即为实际数据值。例如:

01 31 04 6c 69 73 61

应该分成两部分 01 31 和 04 6c 69 73 61 分别表示 “1” 和 “lisa” 两个字符

代码分享地址

  https://github.com/gphper/PHPMysql

参考文档:

  https://dev.mysql.com/doc/internals/en/client-server-protocol.html

  https://www.cnblogs.com/davygeek/p/5647175.html