这个 Mysql Helper 类有问题吗?
我的数据库类中有这个函数。 它接受 3 个参数:
- 执行查询的
- 服务器由存储在配置中的名称标识
- sql 查询示例调用中引用的参数数组
:
$toplist = MyDbClass->q('SELECT * FROM movies WHERE score > ?','slaveserver1',array(100));
这里是代码...
/*
* @param the sql query. may be pure sql or having ? as placeholders for variables that are passed in the 3rd param, not enquoted
* @param name of the link (slave or master server or other arbitrary database)
* @param optional array of vars that will be filled in where the ? signs in the query are
*/
public function q($sql,$name,$vars=false) {
// lets see if the link to the server with name $name has already been initialised, if not lets do it
if(!isset($this->links[$name])) {
$this->initialize($name);
}
// if variables have been passed, lets fill them into the query
if($vars !== false) {
// first real scape them all according to the correct link
for($i=0;$i<count($vars);$i++) {
$vars[$i] = mysql_real_escape_string($vars[$i],$this->links[$name]);
}
// now escape all actual % signs so they are not used as placeholders vor vsprintf
$sql = str_replace('%','%%', $sql);
// no add '' quotes arround every placeholder and fill in
$sql = str_replace('?','\'%\'', $sql);
$sql = vsprintf($sql,$args);
}
// now execute the parsed query on the correct server
return mysql_query($sql,$this->links[$name]) or die(mysql_error($this->links[$name]));
}
现在我的问题是:
我的代码有问题吗?特别是:
- 是否有任何情况下在查询中的参数周围放置
''
引号会导致查询不起作用? - 有没有一些优雅的方法来防止我的函数以双引号结束,例如
where Score > > ''100 ''
在我的查询中(如果我已经在输入查询中放入了 qutoes...)。 - 你觉得这个功能怎么样?这样做的好方法吗?
I have this function in my database class.
It accepts 3 parameters:
- The query
- the server to execute it on which is identified by name that is stored in a config
- an array of arguments that is quoted into the sql query
example call:
$toplist = MyDbClass->q('SELECT * FROM movies WHERE score > ?','slaveserver1',array(100));
here comes the code...
/*
* @param the sql query. may be pure sql or having ? as placeholders for variables that are passed in the 3rd param, not enquoted
* @param name of the link (slave or master server or other arbitrary database)
* @param optional array of vars that will be filled in where the ? signs in the query are
*/
public function q($sql,$name,$vars=false) {
// lets see if the link to the server with name $name has already been initialised, if not lets do it
if(!isset($this->links[$name])) {
$this->initialize($name);
}
// if variables have been passed, lets fill them into the query
if($vars !== false) {
// first real scape them all according to the correct link
for($i=0;$i<count($vars);$i++) {
$vars[$i] = mysql_real_escape_string($vars[$i],$this->links[$name]);
}
// now escape all actual % signs so they are not used as placeholders vor vsprintf
$sql = str_replace('%','%%', $sql);
// no add '' quotes arround every placeholder and fill in
$sql = str_replace('?','\'%\'', $sql);
$sql = vsprintf($sql,$args);
}
// now execute the parsed query on the correct server
return mysql_query($sql,$this->links[$name]) or die(mysql_error($this->links[$name]));
}
Now my questions are:
are there any problem with my code? espacially:
- are there any cases where putting
''
quotes around arguments in a query can make it not working? - is there some elegant way to prevent my function from ending up with double quoted stuff like
where score > ''100 ''
in my queries (if i already put qutoes in the input query...). - what you think of the function? good way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不认为允许一个类操作多个 SQL 连接是一个好主意。应允许此类的每个实例仅使用一个 SQL 连接。或者,如果您尝试实现某种手动负载平衡,则应该从用户透明地使用它,可能只允许“从属”和“主”选择。
也许,您应该将查询分为“读”和“写”查询,因为您可以从任何从属设备“读取”,但应该“写入”所有从属设备。
此外,如果查询调度是出于负载平衡的目的,则需要在类构造函数中打开连接,而不是在查询中延迟打开连接。一个脚本是一种非常短暂的生物。除非您为长期操作编写 CLI 脚本,否则无需延迟连接直到查询真正执行。
I do not think, that allowing one class to manipulate several SQL connections is a good idea. Every single instance of this class should be allowed to use only one SQL connection. Or, if you are trying to implement some kind of manual load balancing, this should be used transparently from user with, may be, only "slave" and "master" choices allowed.
Probably, you should separate your queries into "read" and "write" ones because you can "read" from any slave, but should "write" to all of them.
Also, if query dispatching is done for load balancing purposes, you need to open connections in class constructor instead of lazy-opening them in query. One script is a very short-living creature. There is no need to delay connections until query is really executing unless you write CLI script for long-term operations.