我创建了一个类来更轻松地处理 CRUD,但遇到了问题。我当前的课程以这种语法运行一个杂物:
$crud = Core::Db()->builder();
$userData =$crud
->select("city,adress")
->from('users')
->where('name')
->like(':name')
->read(array(':name','%stefan'));
当你调用 crud 方法时,会自动创建 sql 语句并将其插入到私有变量 $this->sql 中。write() 准备数据并绑定准备好的语句(如果存在)。
最后一个示例生成以下 SQL:
$this-sql = "SELECT city
, address
FROM users
WHERE name
LIKE :name";
一切都很完美。绑定 :name 并添加 '%stefan'。一切都好。
这是我的问题。如果我添加:
$userData =$crud
->select("city,adress")
->from('users')
->where('name')
->like('%stefan')
->read();
返回:
//bad syntax
$this->sql = "SELECT `city`,`address` FROM `users` WHERE `name` LIKE %stefan";
如果我在数据中添加引号,第二个示例将正常工作,但第一个示例将失败:
// First example, bad sintax
$this-sql = "SELECT `city`,`address` FROM `users` WHERE `name` LIKE ':name'";
// Second example, good
$this-sql = "SELECT `city`,`address` FROM `users` WHERE `name` LIKE '%stefan' ";
我想到了一个解决方案...在 like() 方法调用中添加引号并在名称等于 write() 中绑定的绑定参数的名称时对其进行条带化:
private function write(array $input_parameters=array(),$style=NULL)
{
// clean possible errors in holders
foreach($input_parameters as $key => $value):
if(strpos($this->sql,"'".$key."'") !== FALSE)
$this->sql = str_replace("'".$key."'",$key,$this->sql);
if(strpos($this->sql,'"'.$key.'"') !== FALSE)
$this->sql = str_replace('"'.$key.'"',$key,$this->sql);
endforeach;
// .... code ....//
}
这个解决方案在这种情况下工作正常,但如果你有这样的事情:
$userData =$crud
->select("id")
->from('blog')
->where('content')
->like(':word')
->_or('something')
->like(':word')
->read(array(':word','something'));
返回:
$this->sql = "SELECT `id` FROM `blog` WHERE `name` LIKE :word or `something` LIKE :word ";
这不是一个现实生活中的例子,但它只是为了说明为什么我认为它是一个糟糕的解决方案,可能会成为安全风险。
我找不到在没有安全问题或损坏 sql 的情况下绑定数据的方法,我在这里错过了一些东西。
你能想到别的吗?我忘记了什么?我偏执?现在我的头很痛,我不能像人一样思考。
欢迎您的帮助,谢谢