PHP:真实的 OOP 示例

2022-08-30 10:29:50

我正在尝试学习 OOP。我正在读的书中所谓的“现实世界”的例子无济于事。

所有像 、 这样的例子都不再对我有帮助了。我需要现实生活中的例子,如注册,用户个人资料页面等。PetCarHuman

例如:

$user->userName = $_POST['userName'];//save username
$user->password = $_POST['password'];//save password
$user->saveUser();//insert in database

我还看到:

$user->user = (array) $_POST;

哪里:

private $user = array();

保存数组中的所有信息。

在同一个阶级中,有

$user->getUser($uid);
// which sets the $this->user array equal to mysqli_fetch_assoc() using 
//the user id.

是否有任何在许多不同的php应用程序(注册,登录,用户帐户等)中实现OOP的真实示例?


答案 1

OOP不仅仅是关于单个类的外观和操作。它还涉及一个或多个类的实例如何协同工作。

这就是为什么你会看到这么多基于“汽车”和“人”的例子,因为它们实际上在说明这一原则方面做得很好。

在我看来,OOP中最重要的教训是封装多态性

封装:以简洁,逻辑的方式将数据与作用于该数据的逻辑耦合在一起 多态性:一个对象看起来像和/或行为类似于另一个对象的能力。

一个很好的现实世界的例子是类似于目录迭代器的东西。此目录在哪里?也许它是一个本地文件夹,也许它像FTP服务器一样是远程的。谁知道呢!

下面是演示封装的基本类树:

<?php

interface DirectoryIteratorInterface
{
    /**
     * @return \Traversable|array
     */
    public function listDirs();
}

abstract class AbstractDirectoryIterator implements DirectoryIteratorInterface
{
    protected $root;

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

class LocalDirectoryIterator extends AbstractDirectoryIterator
{
    public function listDirs()
    {
        // logic to get the current directory nodes and return them
    }
}

class FtpDirectoryIterator extends AbstractDirectoryIterator
{
    public function listDirs()
    {
        // logic to get the current directory nodes and return them
    }
}

每个类/对象负责自己的检索目录列表的方法。数据(变量)耦合到使用数据的逻辑(类函数即方法)。

但故事还没有结束 - 还记得我说过OOP是关于类的实例如何协同工作,而不是任何单个类或对象吗?

好吧,让我们用这些数据做点什么 - 把它打印到屏幕上?确定。但是如何做到呢?HTML?纯文本?RSS?让我们来解决这个问题。

<?php

interface DirectoryRendererInterface
{
    public function render();
}

abstract class AbstractDirectoryRenderer implements DirectoryRendererInterface
{
    protected $iterator;

    public function __construct(DirectoryIteratorInterface $iterator)
    {
        $this->iterator = $iterator;
    }

    public function render()
    {
        $dirs = $this->iterator->listDirs();
        foreach ($dirs as $dir) {
            $this->renderDirectory($dir);
        }
    }

    abstract protected function renderDirectory($directory);
}

class PlainTextDirectoryRenderer extends AbstractDirectoryRenderer
{
    protected function renderDirectory($directory)
    {
        echo $directory, "\n";
    }
}

class HtmlDirectoryRenderer extends AbstractDirectoryRenderer
{
    protected function renderDirectory($directory)
    {
        echo $directory, "<br>";
    }
}

好了,现在我们有几个类树用于遍历和呈现目录列表。我们如何使用它们?

// Print a remote directory as HTML
$data = new HtmlDirectoryRenderer(
  new FtpDirectoryIterator('ftp://example.com/path')
);
$data->render();

// Print a local directory a plain text
$data = new PlainTextDirectoryRenderer(
  new LocalDirectoryIterator('/home/pbailey')
);
$data->render();

现在,我知道你在想什么,“但是彼得,我不需要这些大类树来做这件事!”但是如果你认为这一点,那么你就错过了重点,就像我怀疑你一直在使用“汽车”和“人”的例子一样。不要把注意力集中在例子的细节上,而是试着去理解这里发生了什么。

我们创建了两个类树,其中一个 () 以预期的方式使用另一个 () - 这通常称为协定。的实例不关心它接收哪种类型的实例,也不关心它们是如何呈现的实例。*DirectoryRenderer*DirectoryIterator*DirectoryRenderer*DirectoryIterator*DirectoryIterator

为什么?因为我们以这种方式设计了它们。他们只是相互插入并工作。这就是 OOP 的实际应用


答案 2

购买一本像“PHP和Mysql日常应用程序傻瓜书”这样的书。

我知道它很旧[2005],但它显示了Mysqli在程序和面向对象中的用户登录,论坛,购物车等概念。

它帮助我学习了面向对象的PHP,我研究了很多。物有所值。

OOP很像将程序的片段分组到可重用的片段中。说实话并不难,它只是将你的函数打包成类的想法。

下面是 OOP 内容的现实世界迷你示例:

班级 数据库
班级 会话
课程 网络
表单 课程 电子邮件

类帐户(下面的示例函数)
函数 SELECTACCOUNT
函数 CHECKPASSWORD
函数 CHECKUSERNAME
函数 CREATEACCOUNT

我希望你坚持下去,PHP 6将被重新设计为比以往任何时候都更支持OOP。

祝你好运!


推荐