zblog链式sql不支持 ESCAPE ,但是sqlite 必须要用ESCAPE ,硬改sql不优雅了

zblog1年前zblog问题解答80

image.png



/zb_system/function/lib/zblogphp.php

通过用户名获取用户实例(不区分大小写). public function GetMemberByName($name)

$sql = $this->db->sql->Select($this->table['Member'], '*', array(array($like, 'mem_Name', $name)), array('mem_ID' => 'ASC'), 1, null);

# SELECT * FROM zbp_member WHERE mem_Name LIKE '!_!_!_!_!_!_!_!_' ESCAPE '!' ORDER BY mem_ID ASC LIMIT 1;


sqlite 测试用例

SELECT * FROM zbp_member WHERE mem_Name LIKE '!_!_!_!_!_!_!_!_' ESCAPE '!'  # ok

SELECT * FROM zbp_member WHERE mem_Name LIKE '\\_\\_\\_\\_\\_\\_\\_\\_' # 不允许

SELECT * FROM zbp_member WHERE mem_Name LIKE '\_\_\_\_\_\_\_\_'  # 不允许

SELECT * FROM zbp_member WHERE mem_Name LIKE '________' # 通配符


mysql:都ok

SELECT * FROM zbp_member WHERE mem_Name LIKE '!_!_!_!_!_!_!_!_' ESCAPE '!' 

SELECT * FROM zbp_member WHERE mem_Name LIKE '\\_\\_\\_\\_\\_\\_\\_\\_' 

SELECT * FROM zbp_member WHERE mem_Name LIKE '\_\_\_\_\_\_\_\_' 

SELECT * FROM zbp_member WHERE mem_Name LIKE '________' 


我的修复方案

/zb_system/function/lib/zblogphp.php   

public function GetMemberByName($name)

# 修复用户名含有 _ like 查询默认通配符问题

        if (false !== strpos($name, '_')) {

            if (preg_match('/like\s+\'[\D\d]*\'\s+/i', $sql, $regs)) {

                $sql = str_replace($regs[0], str_replace('_', '!_', $regs[0]) . " ESCAPE '!' ", $sql);

            }

        }


或者简写为 

$sql = (false !== strpos($name, '_') &&  preg_match('/like\s+\'[\D\d]*\'\s+/i', $sql, $regs)) ? str_replace($regs[0], str_replace('_', '!_', $regs[0]) . " ESCAPE '!' ", $sql) : $sql;

 

image.png

目前用户名规则是:用户名只能用中文、数字、字母、“.”与“_”,且长度限制为2-50位。
如只有一个用户名是admin ,如果再添加 admi_ a_min __min a____ _____ 等,都会提示"存在同名用户,请修改用户名。"

追踪:/zb_system/function/lib/zblogphp.php GetMemberByName 函数
如新增用户名字为: admi_ 生成的sql:
SELECT * FROM zbp_member WHERE mem_Name LIKE 'admi_' ORDER BY mem_ID ASC LIMIT 1;
_在mysql和sqlite中是通配符(即_可以匹配任何字符),因此 LIKE 'admi_' 会搜索到 admin字段,故提示同名,添加失败。

mysql可以加反斜杠可以转义为普通字符,而sqlite需要强制显示使用ESCAPE 转义
即 sql 优化为 SELECT * FROM zbp_member WHERE mem_Name LIKE 'admi!_' ESCAPE '!' ORDER BY mem_ID ASC LIMIT 1;

本机修复 GetMemberByName函数
$sql = $this->db->sql->Select($this->table['Member'], '*', array(array($like, 'mem_Name', $name)), array('mem_ID' => 'ASC'), 1, null);
下增加 $sql 的ESCAPE支持处理。
$sql = (false !== strpos($name, '_') && preg_match('/like\s+\'[\D\d]*\'\s+/i', $sql, $regs)) ? str_replace($regs[0], str_replace('_', '!_', $regs[0]) . " ESCAPE '!' ", $sql) : $sql;
这样原有的sql 可以自动转义_ 兼容mysql sqlite 。

个人观点,仅供参考


相关文章

【此方案收费】阿里云服务器同账号的文件互传 -私网互传-【VPC对等连接】私网ip互通【阿里云套路收费!闭坑!】

【此方案收费】阿里云服务器同账号的文件互传 -私网互传-【VPC对等连接】私网ip互通【阿里云套路收费!闭坑!】

同一个阿里云账号 怎么用私网传输?【VPC对等连接】!跨地域私网确定收费!! 这个就是收费项目哦哦哦对等连接可以在两台 阿里云服务器使用 私网传输,但流量有限制。CDT 赠送200 GB/月公网流量,...

brotli 命令行工具 在centos 和 Ubuntu 分别怎么安装

在CentOS和Ubuntu上安装brotli命令行工具,可以按照以下步骤进行:在CentOS上安装brotli更新系统(可选但推荐):首先,确保你的CentOS系统已经更新到最新状态。bash复制代...

Storage engine MylSAM is disabled (Table creation is disallowed). mysql8++  MyISAM 或 InnoDB(8默认)数据库

Storage engine MylSAM is disabled (Table creation is disallowed). mysql8++ MyISAM 或 InnoDB(8默认)数据库

Storage engine MylSAM is disabled (Table creation is disallowed). mysql8++  MyISAM 或 InnoDB(8默认...

【蜘蛛蜘蛛蜘蛛】 搜索引擎蜘蛛大全 网站蜘蛛样本 bot spider 垃圾蜘蛛 屏蔽蜘蛛

蜘蛛样本 bingbot PetalBot Amazonbot  BLEXBot  MJ12bot  Googlebot&...

array_values 数组的值 使用 array_values 函数获取数组的所有值 array_values 函数返回数组中所有的值,不包含键。

使用 array_values 函数获取数组的所有值array_values 函数返回数组中所有的值,不包含键。...