【问题标题】:Do I really need a class for MySQL Queries?我真的需要一个 MySQL 查询类吗?
【发布时间】:2014-03-02 13:37:48
【问题描述】:

我有一个简单的登录和注册表单,还有一些针对各种不同事物的额外插入和选择查询。

我已经完成了本教程 (http://code.tutsplus.com/tutorials/real-world-oop-with-php-and-mysql--net-1918),该教程将创建一个 PHP 类,据说可以更轻松地选择、插入、断开连接、更新到 MySQL 服务器。

问题是,现在我已经完成了教程并开始实现从静态选择和插入查询到引用类内函数的新查询的一些更改,我看到新代码是更长更复杂,我觉得这超出了课程的目标。

有什么想法和建议吗?

例如,一般的插入查询如下:

mysqli_query("INSERT INTO statuses(User_ID, Status)VALUES('$userid', '$statusupdate')") or die(myself_error());

然而,上面提到的教程需要以下内容:

$db->insert('mysqlcrud',array(3,"Name 4","this@wasinsert.ed<script type="text/javascript">
/* <![CDATA[ */
(function(){try{var s,a,i,j,r,c,l,b=document.getElementsByTagName("script");l=b[b.length-1].previousSibling;a=l.getAttribute('data-cfemail');if(a){s='';r=parseInt(a.substr(0,2),16);for(j=2;a.length-j;j+=2){c=parseInt(a.substr(j,2),16)^r;s+=String.fromCharCode(c);}s=document.createTextNode(s);l.parentNode.replaceChild(s,l);}}catch(e){}})();
/* ]]> */
</script>"));

类文件显示:

    <?php
/**
 * Created by PhpStorm.
 * User: marshall
 * Date: 01/03/14
 * Time: 21:34
 */

namespace MySQL\lib;


class Database {


        private $db_host = 'localhost';
        private $db_user = 'root';
        private $db_pass = 'pass';
        private $db_name = 'database';


    public function connect() {
        if(!$this->con) {
            $myconn = mysql_connect($this->db_host, $this->db_user, $this->db_pass);
            if(myconn) {
                $seldb = mysql_select_db($this->db_name,$myconn);
                if($seldb) {
                    $this->con = true;
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } else {
            return true;
        }
        }

    public function disconnect() {
        if($this->con)
        {
            if(mysql_close())
            {
                $this->con = false;
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    private $result = array();

    private function tableExists($table)
    {
        $tablesInDb = mysql_query('SHOW TABLES FROM '.$this->db_name.' LIKE "'.$table.'"');
        if($tablesInDb)
        {
            if(mysql_num_rows($tablesInDb)==1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }


    public function select($table, $rows = '*', $where = null, $order = null)
    {
        $q = 'SELECT '.$rows.' FROM '.$table;
        if($where != null)
            $q .= ' WHERE '.$where;
        if($order != null)
            $q .= ' ORDER BY '.$order;
        if($this->tableExists($table))
       {
        $query = mysql_query($q);
        if($query)
        {
            $this->numResults = mysql_num_rows($query);
            for($i = 0; $i < $this->numResults; $i++)
            {
                $r = mysql_fetch_array($query);
                $key = array_keys($r);
                for($x = 0; $x < count($key); $x++)
                {
                    // Sanitizes keys so only alphavalues are allowed
                    if(!is_int($key[$x]))
                    {
                        if(mysql_num_rows($query) > 1)
                            $this->result[$i][$key[$x]] = $r[$key[$x]];
                        else if(mysql_num_rows($query) < 1)
                            $this->result = null;
                        else
                            $this->result[$key[$x]] = $r[$key[$x]];
                    }
}
}
return true;
}
else
    {
        return false;
    }
}
else
return false;
}
    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;
            }
        }
    }



    public function delete($table,$where = null)
    {
        if($this->tableExists($table))
        {
            if($where == null)
            {
                $delete = 'DELETE '.$table;
            }
            else
            {
                $delete = 'DELETE FROM '.$table.' WHERE '.$where;
            }
            $del = mysql_query($delete);

            if($del)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }


    public function update($table,$rows,$where)
    {
        if($this->tableExists($table))
        {
            // Parse the where values
            // even values (including 0) contain the where rows
            // odd values contain the clauses for the row
            for($i = 0; $i < count($where); $i++)
            {
                if($i%2 != 0)
                {
                    if(is_string($where[$i]))
                    {
                        if(($i+1) != null)
                            $where[$i] = '"'.$where[$i].'" AND ';
                        else
                            $where[$i] = '"'.$where[$i].'"';
                    }
                }
            }
            $where = implode('=',$where);


            $update = 'UPDATE '.$table.' SET ';
            $keys = array_keys($rows);
            for($i = 0; $i < count($rows); $i++)
            {
                if(is_string($rows[$keys[$i]]))
                {
                    $update .= $keys[$i].'="'.$rows[$keys[$i]].'"';
                }
                else
                {
                    $update .= $keys[$i].'='.$rows[$keys[$i]];
                }

                // Parse to add commas
                if($i != count($rows)-1)
                {
                    $update .= ',';
                }
            }
            $update .= ' WHERE '.$where;
            $query = mysql_query($update);
            if($query)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }

    public function getResult()
    {
        return $this->result;
    }

}

【问题讨论】:

  • 类的代码可能会更长更复杂,但是当你真正开始在代码中使用类对象时,这肯定会简化过程
  • 请分享您的代码。也许您需要在现有类中创建新方法...而且,是的,面向对象的方法应该在更复杂的事情中显示其优势...
  • 第二个 sn-p 中的 JavaScript 是什么?是不是偶然出现的?
  • 这只是在教程中,我不知道教程中的插入方法是如何工作的,但我确实了解普通的 MySQLi 插入查询是如何工作的。

标签: php mysql class


【解决方案1】:

这完全取决于您的应用程序的大小:如果它很简单,则无需抽象数据库查询,您只需使用 PDO 或类似的库来访问您的数据库。

但是,如果代码库变得更大,您可能需要一个 ORM 来为您处理记录及其关系。

一个著名的 PHP ORM 是Doctrine。它遵循存储库模式,这意味着您的记录只不过是 getter 和 setter 的集合,所有逻辑(查询、插入等)都是使用另一个对象完成的。例如:

$user = new User();
$user
  ->setName('John Doe')
  ->setUsername('j.doe')
  ->setPassword('random123')
;

$em = $doctrine->getEntityManager();

$em->persist($user);
$em->flush();

另一方面,Propel 使用 Active Record 模式,您的实体类也用于处理查询和持久性。例如:

$user = new User();
$user
  ->setName('John Doe')
  ->setUsername('j.doe')
  ->setPassword('random123')
;
$user->save();

选择哪种模式主要是主观偏好问题。

【讨论】:

  • 您好,感谢您的回答,我已经编辑了我原来的问题。正如你所看到的代码差异,我仍然很好奇我最初遵循的教程是否是 MySQL 查询类的一个很好的例子。
  • 为了完整起见,在这里可能值得补充的是,Doctrine 只是一种语言的 ORM 的一个示例。在 PHP 中,Propel 是另一种,许多框架(例如 Cake 和 Laravel)都提供了自己的集成 ORM。
  • @Marshiewooooooo:至于 Database 类的正确性,我不是 OOP 专家,但在我看来,这只是将一堆可疑的有用函数放在同一个类中。另外,它使用了已弃用的 mysql 扩展。
【解决方案2】:

为数据库使用类将减少编写代码从表中获取记录的额外代码,但是不必使用类函数从表中插入和检索数据。

您可以在 PHP 中使用 mysqli_fetch_assoc()mysqli_query() 从表中插入和检索数据。两种情况都没有性能问题。

【讨论】:

  • mysql 扩展是旧的,从 PHP 5.5 起已被弃用。新应用程序不应依赖它。
【解决方案3】:

你为什么不简单地使用一些简单的 ORM 库?

您知道 ORM 概念是如此简单,以至于我现在可以在此回答期间即时编写 ORM 库。 : D

那么让我们试试吧。

但是在我们写它之前,我们必须知道一些基本概念或一些基本术语 关于ORM相关的科目。在这个例子中,我们将有:

  1. ORM 库 - ORM 库负责处理服务器连接和服务器连接抽象。 (ORM 的主要目标是将类映射到实际的表,但我们稍后会回到这一点。

  2. 数据层 - 这是本例中 ORM 的实际部分,我们将把它与 ORM 分开来看看它的作用。这部分负责将类映射到表。 例如,数据访问层知道如何将特定的类对象保存到实际的表中,以及如何将特定的表加载到特定的类对象中。 (注意:几乎任何最近的 ORM 都可以避免您进入这一层。例如 http://dbphp.net 或 Doctrine 将支持这一层的各个方面以及关系甚至自动表生成)。

  3. 业务层 - 该层包含您的实际工作类业务层通常代表模型或模型包含业务层。但在现实世界中,如果您使用的是 ORM 库业务,那么您开发其他功能所需的唯一层已经捆绑在 ORM 中。

让我们从业务层或模型开始我们的示例。我们保存和加载用户的非常简单的项目将有一个类业务层:

<?php
class user
{
    public $id;
    public $name
    public function __construct ($name=null)
    {
        $this->name = $name;
    }
}
?>

如您所见,您的业务层或模型对保存或加载的位置和方式一无所知。它只处理与项目相关的业务。这就是图层名称的来源。

其次,让我们做一个简单的ORM库:

<?php

//The connection link which can be changed any time
class link
{
    public $link;
    public function __construct ($hostname, $database, $username, $password)
    {
        $this->link = new \PDO ('mysql:host='.$hostname.';dbname='.$database, $username, $password);
        $this->link->query('use '.$database);
    }
    public function fetch ($query)
    {
        $result = $this->link->query($query)->fetch();
    }
    public function query ($query)
    {
        return $this->link->query($query);
    }
    public function error ()
    {
        return $this->link->errorInfo();
    }
}

//A structure which collects all link(s) and table/class handlers togather
class database
{
    public $link;
    public $tables = array ();
    public function __construct ($link)
    {
        $this->link = $link;
        table::$database = $this;
    }
}

//A basic table handler class
//Note: Every modern ORM automatically maps your classes to tables
class table
{
    public static $database;
}
?>

您注意到我们的 ORM 中的表类似乎很差。但如果这是一个 复杂的 ORM 库,它还支持数据层,并具有处理任何表的所有功能。

但是因为我们需要知道 ORM 在这种情况下是如何工作的,所以我们将创建数据层 我们业务层中每个类的处理程序。

所以这是您的数据层。它是如此自我描述,以至于我认为它没有 需要任何文件:

请注意,下面的类名是 users 而不是 user。 'user' 类对象表示用户的单个实体,而 'users' 类对象表示用户类的处理程序。

<?php
class users extends table
{
    public function create ($row)
    {
        $return = new user ();
        $return->id = $row[0];
        $return->name = $row[1];
        var_export($row);
        return $return;
    }
    public function load ($id=null)
    {
        if ($id==null)
        {
            $result = self::$database->link->fetch("select * from users");
            if ($result)
            {
                $return = array();
                foreach ($result as $row)
                {
                    $return[$row[0]] = $this->create($row);
                }
                return $return;
            }
        }
        else
        {
            $result = self::$database->link->fetch("select * from users where id='".$id."'");
            if ($result)
            {
                return $this->create(reset($result));
            }
            else
            {
                echo ("no result");
            }
        }
    }
    public function save ($user)
    {
        if (is_array($save))
        {
            foreach ($save as $item) $this->save ($item);
        }
        if ($user->id==null)
        {
            return self::$database->link->query("insert into users set
                                                 name='".$user->name."'");
        }
        else
        {
            return self::$database->link->query("update users set name='".$user->name."'
                                                 where id='".$user->id."'");
        }
    }
    public function delete ($user)
    {
        self::$database->link->query ("delete from users where id='".$user->id."'");
    }
}
?>
  1. 最后让我们初始化 $database 对象
  2. 建立一些到一些 sql server 的链接。
  3. 将用户类处理程序添加到数据库。
  4. 使用它。

这是在工作中:

<?
$database = new database (new link('127.0.0.1', 'system_db', 'root', '1234'));
$database->tables['users'] = new users();

if (!$database->tables['users']->save (new user('Admin')))
{
    var_export($database->link->error());
}

var_export($database->tables['users']->load(2));
?>

如果您需要深入了解 php ORM 的其他概念,请随时访问

  1. Doctrine - http://www.doctrine-project.org/ - 功能齐全的复杂 php ORM 框架
  2. db.php - http://dbphp.net/ - 功能齐全但非常简单的 php ORM 框架。

看到了吗? ORM 不吃开发人员:P

如果您想轻松开始 - 请从 http://github.com/hazardland/db.php 开始

【讨论】:

    猜你喜欢
    • 2014-01-31
    • 1970-01-01
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    • 2014-12-24
    • 2020-02-05
    • 1970-01-01
    • 2021-02-01
    相关资源
    最近更新 更多