6

我的数据库类中有一个 PDO 连接,最近我一直将它用作其他类的扩展,即class Users extends Database这允许我始终保持数据库连接,而不必在我的用户类中具有函数。

但是有人指出我不应该这样做是不好的做法,为什么这是不好的做法?以及如何在不扩展的情况下连接到我的用户类中的数据库类?

目前我在我的viewall()函数中调用了数据库我试图把它放在一个__construct()函数中但是它坚持有参数

我已经尝试了以下代码,但是我收到如下错误消息:

Fatal error: Call to undefined method Database::prepare() in E:\xampp\htdocs\attendance\class.Register.php on line 13

关于如何调用我的数据库的任何想法?

这是我的代码:

类.Connect.php

<?php

// Database connection PDO

class Database {

    public function __construct() {
        // Connection information
        $host   = 'localhost';
        $dbname = 'attendance';
        $user   = 'root';
        $pass   = '';

        // Attempt DB connection
        try
        {
            $this->pdo = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
            $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            //echo 'Successfully connected to the database!';
        }
        catch(PDOException $e)
        {
            echo $e->getMessage();
        }

    }

     public function __destruct()
    {
        // Disconnect from DB
        $this->pdo = null;
        //echo 'Successfully disconnected from the database!';
    }


}

?>

类.Register.php

<?php

require 'class.Connect.php';

class Register {

    public function viewall() {
        $pdo = new Database();

        $stmt = $pdo->prepare('SELECT * FROM users');
        $stmt->execute();

    $stmt->fetch();

    }
}

$run = new Register();
$run->viewall();

?>
4

3 回答 3

10

简单的经验法则:如果一个类是extends另一个类,那么那个类就是那个父类(只是稍微改变或扩展)。您可以传递此子类而不是父类。例子:

class Foo { }

class Bar extends Foo { }

function baz(Foo $foo) { }

baz(new Bar);

这有效,baz()期望 aFoo但也接受 a Bar,因为Bar a Foo

现在,你Users 一个Database?不,您的用户不是数据库。您的用户使用数据库。如果有的话,你应该使用composition

class User {

    protected $database;

    public function __construct(Database $database) {
        $this->database = $database;
    }

}

一个类应该它的职责所在。用户管理类的职责是管理用户数据。其中一部分可能涉及与数据库通信,但这并不意味着用户管理类数据库。如果User extends Database,这意味着它可以做Database类可以做的所有事情(以及更多)。这意味着您可以在任何地方使用类User不是Database类,这没有任何意义。保持职责分开。

现在,这是否是正确的结构仍然存在争议,但它朝着正确的方向发展。但是你可能真的想要一个User代表一个用户的类。然后,您有一个UserManageror UserORMor UserStorageor what,它与User在数据库中检索和存储对象有关。这个类反过来使用aDatabase来做到这一点。这样可以保持职责清晰和分离。类User代表用户数据,Database类与数据库交互,UserORM/Manager/whatever中间在两者之间进行协商。

于 2013-09-17T15:04:35.437 回答
0

扩展课程是好的做法吗?

好吧,是的,如果你做对了,并且出于正确的原因。

面向对象编程中的继承(类扩展)概念的工作方式就像您在现实世界中拥有这些对象一样。

在现实世界中,当您使用世界汽车时,按照惯例,您通常指的是所有汽车,并且您会考虑其中的共同属性,例如车轮、发动机、转向、油门、刹车等,但有些汽车具有这些属性还有一些额外的,例如一辆消防车也有一些额外的属性,如附加的梯子,一些用于投水的管子等。对于某些物体的“行为”也可以考虑,例如,汽车可以移动,并且我们的意思是您可以在道路上旋转车轮以移动(由 Car move 方法建模)。此外,救火车可能具有扩展行为,例如可以在其拥有的梯子上上下移动。这可以通过在 FireTruckCar 类中使用方法 moveLadder() 来建模。

如果您想在 PHP 类 (OOP) 中表示这些概念,您可以这样做:

class Car {

    protected $wheels;
    protected $engine;
    //Rest attributes of Car.

    public function __construct($wheels, $engine) {
        $this->wheels = $wheels;
        $this->engine = $engine;
        //Initialize more attributes.
    }
    function move(){
        $this->wheels->rotate();
    }
    //.....

}

class FireTruckCar extends car{

    //Additional Attributes.
    //The attributes of Car class belong to this 
    //one too and are accessible as private.
    protected $ladder;
    protected $tubes;


    public function __construct($wheels, $engine, $ladder, $tubes) {
        //Call the parent constructor, to initialize parent attributes
        parent::__construct($wheels, $engine);
        $this->ladder = $ladder;
        $this->tubes = $tubes;
    }
    function moveLadder($direction){
        $this->ladder->move($direction);
    }
    //...

}

当然,继承和OOP中还有很多额外的概念,比如方法重载/覆盖、抽象类等,但我不打算在这里解释,因为会漏掉重点。我建议你搜索面向对象编程原则虽然和了解他们很好。

于 2013-09-17T15:32:21.030 回答
-1

可能有几种方法可以连接到数据库,以便您在应用程序中的任何地方都有连接。作为一个好的实践,您可以通过使用另一个可以处理您的数据库操作的类来轻松地做到这一点,并且您可以扩展所有需要从该类进行数据库操作的类。

首先稍微更改一下您的 Database 类并传递数据库连接的参数,如下所示:

<?php

// Database connection PDO

class Database {

    public function __construct($host, $dbname, $user, $pass) {
        // Connection information


        // Attempt DB connection
        try
        {
            $this->pdo = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
            $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            //echo 'Successfully connected to the database!';
        }
        catch(PDOException $e)
        {
            echo $e->getMessage();
        }

    }

     public function __destruct()
    {
        // Disconnect from DB
        $this->pdo = null;
        //echo 'Successfully disconnected from the database!';
    }


}

?>

现在创建另一个类,我们将其称为 ObjectModel,如下所示

 class ObjectModel
    {

     protected $db

    public function __construct()
     {

       $this->db = new Database($host, $dbname, $user, $pass) //ofcourse you can get the db connections details and database name from a config file

   }

 // you can have more db operations functions like insert, update, delete etc

 } 

因此,ObjectModel 类将处理您的所有 CRUD 和其他数据库操作以及运行查询。现在如果你想使用 $db 对象,你可以直接在 ObjectModel 类中使用它,也可以在 OBjectModel 的子类中使用它,如下所示:

class Users extends ObjectModel
{

    public function getUsers()
    {
         //$this->db->  whatever operation you want to do you can do it using this db           object
     }
}

请记住,ObjectModel 有一个名为 $db 的 Database 类的对象,因此如果您的 Database 类使用 PDO,那么您的 ObjectModel $db 对象将具有所有这些操作,即使用 PDO。

我希望这对你也有帮助,因为我正在为我的课程使用这样的 ObjectModel 类,它为我节省了大量时间来一次又一次地编写代码:)。

快乐编码 ;)

于 2013-09-17T15:23:23.517 回答