PHP: Real world OOP example
我正在努力学习OOP。我正在读的书中所谓的"现实世界"的例子没有帮助。
像
一个例子:
1 2 3 | $user->userName = $_POST['userName'];//save username $user->password = $_POST['password'];//save password $user->saveUser();//insert in database |
我也看到了:
1 |
哪里:
1 |
将所有信息保存在一个数组中。
在同一个阶级里
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(); |
现在,我知道你在想什么,"但是彼得,我不需要这些大树来做这个!"但是,如果你认为这一点,那么你就错失了重点,就像我怀疑你曾经用过"汽车"和"人"的例子一样。不要把重点放在这个例子的细节上,而是试着理解这里发生了什么。
我们创建了两个类树,其中一个(
为什么?因为我们是这样设计的。他们只是互相插电工作。这是行动中的OOP。
购买一本书,比如"PHP和MySQL日常应用程序的傻瓜"。
它的旧版i know[2005]但是它显示了用户登录、论坛、购物车等概念,无论是程序化的还是面向对象的mysqli。
它帮助我学习面向对象的PHP,我学习了很多。很值得。
OOP非常类似于将程序的一些位组合成可重用的部分。老实跟你说并不难,这只是把你的函数打包成类的想法。
下面是OOP内容的真实世界迷你示例:
类数据库
上课时间
类webforms
课堂电子邮件
类帐户(下面的示例函数)
函数selectaccount
函数检查密码
函数检查用户名
函数createCount
我希望你能坚持下去,PHP6将被重新设计以比以往更支持OOP。
祝你好运!
虽然我知道这个问题已经被回答了,但我觉得我可以在这里增加价值。
我不认为您应该使用PHP作为编程语言来学习OOP。如果你想学习Web应用程序的面向对象编程,你就应该真正地研究C语言或Java语言。一旦您学习了OOP,那么您就可以将这些知识应用到PHP。我学习OOP的一本书的一个例子是
我为什么这么说????因为从字面上讲,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。创建模型时,可以进行雄辩的扩展。这意味着您已经在代码中使用了多态性。您将看到通过使用类,它们被封装,并且您将看到每个类都有一个特定的角色。
当您想要与数据库交互时,您首先将在控制器方法中创建一个
一本关于初学者学习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 |
然后
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 |
检查这个合并方法(或其他)如何在引擎盖下工作。
我认为这是一个很好的例子,它显示了几乎所有可以用OOP代码替换的功能代码,就像在这个库中一样。但是有了OOP,你可以得到更多,你也可以检查函数式编程和OOP问题来了解更多细节,它的优点和缺点是什么。