3.2 - 严重 - 未处理
根据手册上的说法“ThinkPHP的数据库连接的惰性的,所以并不是在实例化的时候就连接数据库,而是在有实际的数据操作的时候才会去连接数据库(额外的情况是,在系统第一次实例化模型的时候,会自动连接数据库获取相关模型类对应的数据表的字段信息)“。db.class.php里面select方法是这样的:
public function select($options=array()) {
$this->model = $options['model'];
$sql = $this->buildSelectSql($options);
$result = $this->query($sql,$this->parseBind(!empty($options['bind'])?$options['bind']:array()));
return $result;
}当第二次使用select方法去加载数据的时候,数据库连接在调用query方法前并未连接。PDO驱动类的escapeString覆盖了DB类的对应方法。
所以在buildSelectSql执行时PDO类的escapeString方法就会被执行(调用顺序是select->buildSelectSql->parseSql->parseWhere->parseWhereItem->parseValue->escapeString)。
然而PDO类的escapeString方法是完全依赖dbType属性的,缺少dbType属性escapeString方法会返回空。
而dbType属性是在查询发生的时候,通过PDO类的connect方法赋值(调用顺序是query->initConnect->connect->_getDsnType)。
这就产生了一个逻辑错误,当使用PDO类去转义sql语句时候,转义结果无法正确返回,导致了生成的SQL语句where部分只有键,而值是空的。
