我要求社区的智慧,因为我想避免错误的编码习惯和/或错误。 我有一个php类,它是一个对象管理器。它完成数据库的所有工作:插入新数据,更新数据,获取数据并删除它(我已经读过它,称为CRUD ......)。所以它有一个通过id获取元素的函数。
我想写的是一个从表中获取对象列表的函数。 然后我将使用类似
的mysql查询SELECT * FROM mytable WHERE column1='foo'
然后是一些顺序和限制/偏移。
但是,在我的应用程序中,有不同的情况我将需要此表中的不同列表。然后WHERE子句会有所不同。
我应该编写不同的功能,每种类型的列表一个吗? 或者我应该写一个通用函数,我将发送参数,然后动态创建查询?如果是这样,你对如何正确地做这个有任何建议吗?
修改 谢谢你的所有答案!我应该告诉我,我没有使用任何框架(也许并不是最好的主意......),所以我对查询构建器一无所知。我将调查一下(要么找到一个独立的uery构建器,要么迁移到一个框架或编写我自己的,我还不知道)。每当我需要执行mysql查询时,这将非常有用: - )
虽然我仍然感到困惑: 让我们说我需要几个客户端(对象)列表,例如所有客户端,18岁以上的客户端,当前在线的客户端...... 检索这些列表最好的方法是什么?我可以在我的客户经理中有3个功能
allClients() {//execute a specific query and return list of objects}
allClientsOver18() {//execute specific query and return list of objects}
allClientsOnline() {//execute specific query and return list of objects}
或者我可以使用一个函数来构建基于参数的查询
listClients($some, $parameters)
{
//Build the query based on the parameters (definitely need a query builder!)
//Execute the query
//return list of objects
}
哪种方法最好(我猜这取决于具体情况),主要是为什么?
提前致谢! 肉粒
答案 0 :(得分:2)
感谢查询构建器的所有信息,我甚至都不知道它存在! :-)然而,我仍然感到困惑,我应该为每个案例编写一个特定的函数(该函数仍然可以使用查询构建器来编写其特定的查询),或者编写一个基于onf参数动态构建查询的泛型函数。在哪种情况下哪个更好?我在我的问题中添加了一个例子,希望它能让它更清晰!
这取决于您使用这些孤立查询的频率,条件的复杂程度以及我需要将条件与其他查询相结合的频率。对于eaxample,如果“online”和“over18”都只是简单的条件,那么你可以使用我的例子中的普通findBy
逻辑:
$table = new MyTable($db);
$onlineOnly = $table->findBy(array('is_online' => true), null, null);
$over18Only = $table->findBy(array('is_over_18' => true), null, null);
$onlineOver18 = $table->findBy(array('is_over_18' => true, 'is_online' => true), null, null);
如果查询更复杂 - 例如,要获得超过18个客户端,您必须这样做:
select client.*, (YEAR(CURDATE()) - YEAR(client.birthdate)) as age
FROM client
WHERE age >= 18
然后最好将它变成一个单独的方法或者创建方法来直接处理Query
个对象以添加复杂的条件 - 特别是如果你在app中的几个不同的查询中需要这个条件:
$table = new MyTable($db);
// creates a basic query defaulted to SELECT * FROM table_name
$query = $table->createQuery();
// adds the complex condition for over 18 resulting in
// SELECT table_name.*, (YEAR(CURDATE()) - YEAR(table_name.birthdate)) as age WHERE age >= 18
$over18 = $table->applyOver18Query($query)->execute();
通过这种方式,您可以轻松地将超过18条件应用于任何查询,而无需手动操作构建器,确保您的18岁以上条件一致。但为简单起见,您还可以使用以下方便的方法:
public function findOver18By(array $criteria, $limit = null, $offest = null) {
$query = $this->findBy($criteria, $limit, $offset);
$this->applyOver18Query($query);
return $query->execute();
}
通常你会在较低级别使用某种查询构建器,如:
$query = $db->createQuery()
->select($fields)
->from($tableName)
->where($fieldName, $value);
$results = $query->execute();
然后你可能会有一个使用它的类:
class MyTable
{
protected $tableName = 'my_table';
protected $db;
public function __construct($db) {
$this->db = $db;
}
public function findBy(array $criteria, $limit = null, $offset = null) {
$query = $this->db->createQuery();
$query->select('*')->from($this->tableName);
foreach ($criteria as $col => $value) {
// andWhere would determine internally whether or not
// this is the initial WHERE clause or an AND clause
// something similar would happen with an orWhere method
$query->andWhere($col, $value);
}
if (null !== $limit) {
$query->limit($limit);
}
if (null !== $offset) {
$query->offset($offset);
}
return $query->execute();
}
}
用法如下:
$table = new MyTable($db);
$result = $table->findBy(array('column1' => 'foo'), null, null);
这是你自己实施的很多东西。大多数人使用ORM或DBAL来提供这些功能,这些功能通常包含在Eloquent with Laravel或Doctrine with Symfony等框架中。
答案 1 :(得分:0)
我想一开始你应该需要一些主要的数据,比如
$main = [
'from' = '`from_table`',
]
然后你应该添加选择,如果有
$selects = ['fields1','field2'];
$where = ['some condition', 'other condition'];
然后你可以
$query = "SELECT ".implode(',', $selects ." FROM ".$main['from']."
WHERE ".implode('AND ', $where .";";
这是简单的一个表查询的一些方法。
如果你需要联接,那么$selects
会更好地使用别名,所以如果它们没有不同就不会丢失任何字段,比如
select temp.id as temp_id , temp2.id temp2_id from temp
left join temp2 on temp2.temp_id = temp.id
随意问一些问题,也许我还没有告诉过,但你也应该用一些函数检查绑定参数以避免sql注入
答案 2 :(得分:-1)
我建议您的数据库使用 CLASS ,它可以保存您的所有数据库访问功能,因为它可以让您的代码更清晰,从而更容易查看错误或修改。
class Database
{
public function connect() { }
public function disconnect() { }
public function select() { }
public function insert() { }
public function delete() { }
public function update() { }
}
示例连接功能,用于连接到选定的数据库。
private db_host = ‘’;
private db_user = ‘’;
private db_pass = ‘’;
private db_name = ‘’;
public function connect()
{
if(!$this->con)
{
$myconn = mysqli_connect($this->db_host,$this->db_user,$this->db_pass);
if($myconn)
{
$seldb = mysqli_select_db($this->db_name,$myconn);
if($seldb)
{
$this->con = true;
return true;
} else
{
return false;
}
} else
{
return false;
}
} else
{
return true;
}
}
使用这种方法可以更轻松地创建CRUD函数。下面是一个示例插入函数。
public function insert($table,$values,$rows = null)
{
if($this->tableExists($table))
{
$insert = 'INSERT INTO '.$table;
if($rows != null)
{
$insert .= ' ('.$rows.')';
}
for($i = 0; $i < count($values); $i++)
{
if(is_string($values[$i]))
$values[$i] = '"'.$values[$i].'"';
}
$values = implode(',',$values);
$insert .= ' VALUES ('.$values.')';
$ins = @mysql_query($insert);
if($ins)
{
return true;
}
else
{
return false;
}
}
}
继续快速了解如何使用它。
;<?php;
$db->insert('myDataBase',array(3,"Name 4","this@wasinsert.ed")); //this takes 3 paramteres
$result = $db->getResult(); //Assuming you already have getResult() function.
print_r($result);
?>
修改强>
处理数据库操作的方法更为纯粹。我强烈建议,因为处理信息非常微妙,应该采用许多安全措施,但它需要更深入的PHP知识。在预备语句及其重要性上尝试使用PDO for php和this article matt bango 。