PHP:真实世界的OOP示例

PHP: Real world OOP example

我正在努力学习OOP。我正在读的书中所谓的"现实世界"的例子没有帮助。

PetCarHuman这样的例子都不再帮助我了。我需要现实生活中的例子,比如注册、用户配置文件页面等。

一个例子:

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

我也看到了:

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

哪里:

1
private $user = array();

将所有信息保存在一个数组中。

在同一个阶级里

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

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


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

这就是为什么你看到这么多以"汽车"和"人"为基础的例子,因为它们确实很好地说明了这一原则。

在我看来,OOP中最重要的课程是封装和多态性。

封装:以简洁、逻辑的方式将数据和作用于该数据的逻辑耦合在一起。多态性:一个对象看起来和/或表现得像另一个对象的能力。

一个很好的实际例子是类似于目录迭代器的东西。这个目录在哪里?可能是本地文件夹,也可能是远程文件夹,就像FTP服务器。谁知道呢!

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?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?我们来解决这个问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?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,"
"
;
    }
}

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

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

1
2
3
4
5
6
7
8
9
10
11
// 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。


购买一本书,比如"PHP和MySQL日常应用程序的傻瓜"。

它的旧版i know[2005]但是它显示了用户登录、论坛、购物车等概念,无论是程序化的还是面向对象的mysqli。

它帮助我学习面向对象的PHP,我学习了很多。很值得。

OOP非常类似于将程序的一些位组合成可重用的部分。老实跟你说并不难,这只是把你的函数打包成类的想法。

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

类数据库
上课时间
类webforms
课堂电子邮件

类帐户(下面的示例函数)
函数selectaccount
函数检查密码
函数检查用户名
函数createCount

我希望你能坚持下去,PHP6将被重新设计以比以往更支持OOP。

祝你好运!


虽然我知道这个问题已经被回答了,但我觉得我可以在这里增加价值。

我不认为您应该使用PHP作为编程语言来学习OOP。如果你想学习Web应用程序的面向对象编程,你就应该真正地研究C语言或Java语言。一旦您学习了OOP,那么您就可以将这些知识应用到PHP。我学习OOP的一本书的一个例子是Big Java by Cay S. Horstmann

我为什么这么说????因为从字面上讲,PHP上有数百万个关于如何做事情的例子,但是很少有人是关于如何正确编程的例子。此外,PHP允许您采取许多快捷方式,这将是不可接受的Java之类的。这样,如果你用Java头编程PHP,那么我相信你会成为一个更强大的程序员。OOP不是特定于语言的,它是一种编程范式。

如果您必须使用PHP学习OOP,那么我建议您看看Github公共存储库中的一些真正的源代码。您可以在packagist.org中搜索它们。如果它们是一个不错的公共存储库,那么它们将包含一个readme.md文件,该文件将向您展示如何使用composer包。例如,https://github.com/moltin/laravel-cart就是一个购物车包的例子,您可以在应用程序中使用它。请注意,您不需要查看包源代码来了解包的作用。这个包已经写好了,你不关心它们是如何工作的,但是你使用它们,所以你只需要知道如何使用它们。这正是OOP的意义所在。

I don't care how the shopping cart class adds an item to the cart, I just want to create a new cart and add something to it.

但是,您正在做的是将源代码作为一个工具深入了解OOP是如何工作的。

除此之外,可能更重要的是,对于Web应用程序开发,我将研究MVC设计模式。

MVC设计模式代表模型、视图、控制器。在Web应用程序的情况下,模型负责对数据库建模,视图负责向用户显示内容。控制器负责与模型交互并处理用户输入。

然后我认为您应该尝试在本地机器上安装Laravel框架或其他"体面的现代框架"。为什么我要说现代,因为现代框架需要一个MUMUM PHP版本5.3 +,这意味着你的机器上的PHP将支持真正的OOP,类似于你从Java中得到的。

有许多教程将向您展示如何在Laravel中构建Web应用程序。立即,您将看到当您创建一个控制器时,您扩展了一个basecontroller。创建模型时,可以进行雄辩的扩展。这意味着您已经在代码中使用了多态性。您将看到通过使用类,它们被封装,并且您将看到每个类都有一个特定的角色。

当您想要与数据库交互时,您首先将在控制器方法中创建一个new Model对象。当您开始了解更多信息时,您将开始学习如何将依赖项注入控制器,然后学习如何将模型转储并创建存储库和程序到接口。

一本关于初学者学习Laravel的好书是:dale rees的https://leanpub.com/codebright。大约两周前我在拉拉维尔的一次聚会上遇见了戴尔。

此外,随着您越来越熟练地构建Web应用程序,您将开始学习如何将以下原则应用于编程:

  • 单一责任原则
  • 开闭原理
  • Liskov替换原则
  • 接口隔离原理
  • 依赖倒置原则

我在php oop方面做得并不远,但是我越是深入到其中,它就越容易。对象示例只是供您了解OOP是如何工作的。我理解并在之前已经经历过,OOP只是关于属性和方法(普通变量和函数)。我自己用我的教程中的例子编写了真正的OOP程序,不一定要在现实世界中。这就像用汤匙喂你一样,你永远也不会理解OOP,也很容易忘记。我的建议是学会理解。如果你理解,你可以做任何事情,并且会意识到OOP的力量。我下载了这本书,我想你也应该下载。但这就像是有人在为你构建应用程序…

这里有一个链接到书php和mysql的傻瓜日常应用程序


我建议您现在不要使用任何框架,如果您不了解OOP,那么深入了解Zend或任何其他框架就太多了。

PHP OOP很有趣…哈哈哈,很有趣,因为它是支持的,但是PHP不是像Java或C语言那样的OOP语言。

简单的例子只是在我的陈述下面加下划线:

1
2
3
4
5
6
7
8
// define class
class User {
// define properties and methods
public $name ="";
}
// instantiate class
$user = new User; // or new User() or new user, it's all the same
echo $user->name;

但是,如果你想在"飞行中"进行OOP,你可以执行以下操作:

1
$user = (object) array('name' => 'Peter');

然后

1
$user->name;

但是你可以像你在Java或者C语言中那样使用OOP,但不能使用相同的扩展,并且记住,像WordPress和Drupal这样的流行系统不是纯OOP!但您也可以在PHP中执行继承和其他OOP类的工作。


正如Astropanic所说,您可以查看一个好的PHP框架或库的源代码。我推荐Zend框架,它是非常模块化的,有一个伟大的,专业的设计。我会说这是一段非常好的面向对象的PHP代码。

不过,我认为从一个巨大的生产代码中学习并不是那么容易,因为它不是真正用来教你任何东西的。但是,如果您想要真实世界的面向对象的PHP代码,Zend框架(或者symfony,或者cakephp)可能是解决问题的方法。


我还建议看看我的包装器排列。它是一个本地的PHP数组,以OOP方式轻松操作库。

因此,如果您使用本机PHP数组函数-您可以在OOP中执行相同的操作,而arrayzy可以帮助您使用它,例如:

1
2
3
// Functional programming:
$array = ['a', 'b', 'c'];
$resultArray = array_merge($array, ['c', 'd']);

1
2
3
4
// Object-oriented programming:
$obj = Arrayzy\MutableArray::create(['a', 'b', 'c']);
$obj->mergeWith(['c', 'd']);
$resultArray = $obj->toArray();

在这两种情况下,结果数组都是:

1
2
3
4
5
6
7
Array(
    0 => 'a'
    1 => 'b'
    2 => 'c'
    3 => 'c'
    4 => 'd'
)

检查这个合并方法(或其他)如何在引擎盖下工作。

我认为这是一个很好的例子,它显示了几乎所有可以用OOP代码替换的功能代码,就像在这个库中一样。但是有了OOP,你可以得到更多,你也可以检查函数式编程和OOP问题来了解更多细节,它的优点和缺点是什么。