什么是使PHP网站接近数据库面向对象的好方法?

发布时间:2022-04-30 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了什么是使PHP网站接近数据库面向对象的好方法?脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
请注意我不是在寻找“使用框架”的答案.我正在尝试从结构上改进我编写网站和从 PHP处理数据库的方式.

我正在从头开始构建一个Web服务,没有任何框架.我正在使用LamP堆栈,而我正在努力学习一些PHP的OO功能.我以前只使用OO制作移动应用程序.

我已经好几个月了(按计划,不用担心).在此过程中,我遇到了一些结构性问题,让我想知道代码对象为导向的最佳方法是什么.

几乎所有问题都以某种方式涉及数据库.假设我们有一个类DB和一个类User.在大多数情况下,我只需要从数据库获取单个用户的信息.我认为处理它的一个方法是拥有一个全局$_db变量并让User对象查询数据库,如此(过于简化):

class User {
    function __construct($id) {
        global $_db;
        $q = $_db->query("SELECT name,mail From user WHERE id = ?",$id);
        $this->loadPRoPErties($q);
    }
}

现在说我们有一个显示用户列表的页面.我仍然想为每个用户创建User对象,但我不想为每个单独的用户查询数据库.

因此,我扩展User类以将对象作为参数:

class User {
    function __construct($id) {
        if(is_object($id))
            $q = $id;
        else {
            global $_db;
            $q = $_db->query("SELECT name,$id);
        }

        $this->loadProperties($q);
    }
}

现在我可以创建一个列表,例如,最近创建的100个帐户和活动帐户:

$user_list = [];

$q = $_db->query("SELECT name,mail From user WHERE banned = 0 ORDER BY date_created DESC LIMIT 100");

while($a = $_db->fetch($q))
    $user_list[] = new User($a);

这一切都很有效,除了一个很大的缺点:表用户数据库查询不再在一个地方,这有点制作意大利面条代码.这是我开始怀疑这是否可以更有效地完成的地方.

所以也许我需要扩展我的数据库对象而不是我的User对象,例如:

class DB {
    public function getUsers($where) {
        $q = $this->query("SELECT name,mail FROM user WHERE ".$where);

        $users = [];
        while($a = $this->fetch($q))
            $users[] = new User($a);
    }
}

现在我将创建用户列表,如下所示:

$user_list = $_db->getUsers("banned = 0 ORDER BY date_created DESC LIMIT 100");

但是现在我使用各种SQL查询在各个地方调用getUsers()方法,什么都不解决.我也不想每次都加载相同的属性,所以我的getUsers()方法必须将整个SQL查询作为参数.无论如何,你明白了.

说到加载不同的属性,还有另一件事让我在PHP中编写OO.假设我们的PHP对象至少包含数据库行的每个属性.假设我有一个方法User :: getName():

class User {
    public function getName() {
        return $this->name;
    }
}

函数将假定已从数据库加载了相应的字段.但是,每次创建对象时,预加载所有用户属性都是低效的.有时我只需要用户的名字.另一方面,此时进入数据库以加载这一属性也是低效的.

我必须确保对于我使用的每个方法,已经加载了适当的属性.从性能角度来看,这是完全合理的,但是从OO的角度来看,这意味着你必须事先知道你将要使用哪些方法,这使得它的动态性降低,并且再次允许意大利面条代码.

我碰到的最后一件事(至少目前为止)是如何将实际新用户新用户分开.我想我会使用一个名为Registration的单独类(再次,过度简化):

class Registration {
    function createUser() {
        $form = $this->getSubmitteDForm();

        global $_db;
        $_db->query("INSERT INTO user (name,mail) VALUES (?,?)",$form->name,$form->;mail);
        if($_db->hasError)
            return FALSE;

        return $_db->insertedID;
    }
}

但这意味着我必须为每个数据库表创建两个单独的类,并且我还有不同的类访问同一个表.更不用说还有一个第三类处理登录会话,它也访问用户表.

总之,我觉得上述所有方法都可以更有效地完成.最重要的是,我想要漂亮的代码.我觉得我错过了从OO角度来看数据库方法.但是,如何在不失去SQL查询的动态和强大的情况下这样做呢?

我期待着阅读你在这个领域的经验和想法.

更新

似乎你们大多数人都谴责我使用全局$_db.虽然你已经说服我这不是最好的方法,但对于这个问题的范围而言,我是通过参数,全局还是单例来提供数据库是无关紧要的.它仍然是一个独立的类DB,可以处理与数据库的任何交互.

解决方法

拥有一个单独的类来处理SQL查询并保留获取的数据是很常见的事情.事实上,它是单一责任原则的真正应用.

我通常做的是保留一个类,其中包含有关数据的所有信息,在您的情况下为User类,并将所有用户信息作为字段.

然后是业务层,例如UserDataManager(虽然不推荐使用“Manager”作为后缀,你最好在每个场景中找到一个更合适的名称),它在构造函数中使用pdo对象以避免使用全局变量并具有所有sql方法.因此,你有方法registerNewUser,findUserById,unsuscribeUser等(方法中使用“User”可以隐含类名并被省略).

希望能帮助到你.

脚本宝典总结

以上是脚本宝典为你收集整理的什么是使PHP网站接近数据库面向对象的好方法?全部内容,希望文章能够帮你解决什么是使PHP网站接近数据库面向对象的好方法?所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。