php / mysql选择项目的最佳实践

时间:2015-01-22 14:42:54

标签: php mysql

我要求社区的智慧,因为我想避免错误的编码习惯和/或错误。 我有一个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
}

哪种方法最好(我猜这取决于具体情况),主要是为什么?

提前致谢! 肉粒

3 个答案:

答案 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 LaravelDoctrine 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