PHP怎么注释SQL语句_PHPSQL语句注释【防注入】

8次阅读

php注释在sql中无效,mysql仅识别–(后跟空格)、#、/ /三种注释;防注入唯一可靠方式是参数化查询,禁用字符串拼接。

PHP怎么注释SQL语句_PHPSQL语句注释【防注入】

SQL 语句里写 PHP 注释根本没用

PHP 的 ///* */ 注释只在 PHP 解析器执行时起作用,一旦拼接到 SQL 字符串里发给数据库,这些注释就变成普通文本——MySQL、postgresql 等压根不认 PHP 风格的注释。更危险的是,如果用户输入里混进 --#/* */,反而可能被数据库当真,干扰原有逻辑甚至绕过条件检查。

MySQL 支持的合法 SQL 注释语法只有三种

真正能被 MySQL 执行器识别并忽略的注释,必须符合其协议规范:

  • -- (注意后面必须跟一个空格):单行注释,从 -- 开始到行尾
  • #:单行注释,从 # 开始到行尾(仅 MySQL 支持,非标准 SQL)
  • /* ... */:多行注释,但不能嵌套;若写成 /*! ... */,MySQL 会执行其中内容(用于条件兼容性指令)

例如这段 SQL 是有效的:

SELECT id, name FROM users  WHERE status = 1 -- 过滤启用状态   AND deleted = 0; /* 跳过回收站数据 */

想“注释掉”SQL 片段?别手拼,用参数化或条件组装

开发中常想临时禁用某段 WHERE 条件,比如把 AND created_at > '2024-01-01' 注释掉。手动加 -- 极易出错,且容易遗留测试代码到生产。正确做法是让 PHP 控制逻辑分支:

立即学习PHP免费学习笔记(深入)”;

  • 用布尔变量控制是否追加条件:if ($needDateFilter) { $sql .= " AND created_at > ?"; }
  • 使用 pdo/mysqli 的预处理语句,把值绑定进去,而非字符串拼接
  • 避免用 mysql_real_escape_string(已废弃)或简单 addslashes() 做“防注入”,它们对注释类攻击无效

错误示范(看似注释,实则危险):

$sql = "SELECT * FROM posts WHERE id = " . $_GET['id'] . " -- "; // 用户传入 id=1 OR 1=1 /* 就会闭合注释! */

真正的防注入只靠参数化,和注释无关

SQL 注释本身不是安全机制,也不是防注入手段。所谓“用注释防注入”是典型误解。唯一可靠的方式是彻底分离 SQL 结构与数据:

  • PDO:用 prepare() + bindValue() 或问号占位符
  • MySQLi:用 prepare() + bind_param()
  • 绝不把用户输入直接拼进 SQL 字符串,无论你加了多少 --#

哪怕你写满十行 -- 注释,只要用户输入进了字符串拼接,就可能破坏 SQL 结构。注释只是写给人看的,数据库只信语法树。

最常被忽略的一点:ORM 或查询构建器(如 laravel Query Builder、Doctrine DBAL)默认启用参数化,但一旦调用 whereRaw()DB::raw() 或拼接 CONCAT() 类函数,就退回高危模式——那里才是注释真正该消失的地方。

text=ZqhQzanResources