扩展课堂是一种好习惯吗? [英] Is extending classes good practice?

查看:70
本文介绍了扩展课堂是一种好习惯吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的数据库类中有一个PDO连接,最近我一直使用它作为其他类的扩展,即class Users extends Database,这使我可以始终保持数据库连接而不必在我的Users类中具有功能. /p>

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

当前,我在viewall()函数中调用了数据库,我试图将其放在__construct()函数中,但是它坚持要有参数

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

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

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

这是我的代码:

class.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!';
    }


}

?>

class.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();

?>

解决方案

简单的经验法则:如果某个类extends是另一个类,则该类是该父类(仅稍作改动或扩展) ).您可以传递此子类而不是父类.示例:

class Foo { }

class Bar extends Foo { }

function baz(Foo $foo) { }

baz(new Bar);

这可行,baz()期望Foo但也接受Bar,因为Bar Foo.

现在, 是您的Users a Database ?否.您的用户不是数据库.您的用户使用数据库.如果有的话,您应该使用 composition :

class User {

    protected $database;

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

}

一个类应该承担其的职责.用户管理类的职责是管理用户数据.其中的一部分可能涉及与数据库对话,但这并不意味着用户管理类数据库.如果为User extends Database,则意味着它可以执行Database类可以执行的所有操作(以及更多操作).这意味着您可以在各处而不是Database类使用User类,这没有任何意义.将职责分开.

现在,这是否是正确的结构仍值得商,,但它朝着正确的方向发展.但是您可能真的想拥有一个User类,该类表示一个用户.然后,您有一个UserManagerUserORMUserStorage或其他任何与在数据库中检索和存储User对象有关的内容.此类依次使用 执行此操作.这样可以使责任明确和分离. User类表示用户数据,Database类与数据库交互,中间的UserORM/Manager/whatever在两者之间进行协商.

I have a PDO connection in my database class and recently I have been using this as an extension for other classes i.e. class Users extends Database this allows me to always keep a Database connection without having to have a function in my Users class.

However somebody pointed out that I shouldn't be doing this as its bad practice, why exactly is this bad practice? And how can I connect to my database class in my user class without extending?

Currently I have the call to the database inside my viewall() function I tried to put this in a __construct() function however it insisted on having parameters

I've tried the below code however I get the error message as follows:

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

Any ideas on how I can call on my database?

This is my code:

class.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!';
    }


}

?>

class.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();

?>

解决方案

Simple rule of thumb: if a class extends another, then that class is that parent class (only slightly altered or extended). You can pass this child class instead of the parent class. Example:

class Foo { }

class Bar extends Foo { }

function baz(Foo $foo) { }

baz(new Bar);

This works, baz() expects a Foo but also accepts a Bar, because Bar is a Foo.

Now, is your Users a Database? No. Your users are not a database. Your users use a database. If at all, you should use composition:

class User {

    protected $database;

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

}

A class should be what its responsibilities are. The responsibility of a user management class is to manage user data. Part of that may involve talking to a database, but that doesn't mean the user management class is a database. If User extends Database, that means it can do everything the Database class can do (and more). That means you could use the User class everywhere instead of the Database class, and that doesn't make any sense. Keep responsibilities separate.

Now, it's still debatable whether that is the right structure or not, but it goes into the right direction. But you may really want to have a User class, which represents one user. You then have a UserManager or UserORM or UserStorage or whatever, which is concerned with retrieving and storing User objects in a database. This class in turn uses a Database to do just that. That keeps responsibilities clear and separated. The User class represents user data, the Database class interacts with the database, the UserORM/Manager/whatever in the middle negotiates between the two.

这篇关于扩展课堂是一种好习惯吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆