PHP:真实世界的OOP例子

我正在学习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(); 

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

在同一个class级内

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

在许多不同的PHP应用程序(注册,login,用户帐户等)中是否有真实世界的示例实现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 } } 

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

但是这个故事还没有结束 – 请记住我说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(); 

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

我们创build了两个类树,其中一个( *DirectoryRenderer )以预期的方式使用另一个( *DirectoryIterator ) – 这通常被称为合同*DirectoryRenderer一个实例不关心它接收的*DirectoryIterator的实例types, *DirectoryIterator的实例也不关心它们如何被渲染。

为什么? 因为我们是这样devise的 他们只是插在一起工作。 这是OOP的行动

购买像“PHP和Mysql日常应用傻瓜”的书。

它的老我知道[2005],但它展示了用户login,论坛,购物车等与Mysqli程序和面向对象的概念。

它帮助我学习面向对象的PHP,我研究了很多。 非常值得的钱。

OOP就像把你的程序分成可复用的部分一样。 对你来说,要把你的函数打包成类是不难的。

下面是面向对象的东西的真实世界的小例子:

类数据库
class级会议
CLASS WEBFORMS
CLASS EMAIL

class级帐户(下面的示例function)
functionSELECTACCOUNT
functionCHECKPASSWORD
FUNCTION CHECKUSERNAME
functionCREATEACCOUNT

我希望你继续这样做,PHP 6将被重新devise,以支持OOP比以往更多。

祝你好运!

astropanic说,你可以看看一个好的PHP框架或库的源代码。 我推荐Zend Framework ,它是非常模块化的,有一个伟大的,专业的devise。 我会说这是一个很好的面向对象的PHP代码。

不过,我认为从大量的生产代码中学习并不是那么容易,因为它不是真正教你什么。 但是如果你想要真实世界的面向对象的PHP代码,Zend Framework(或者Symfony,或者CakePHP)可能是最好的select。

我build议你暂时不要使用任何框架,如果你不知道面向对象,挖入zend或者其他任何框架都是太过分了。

PHP的OOP退出有趣…像哈哈有趣的,因为它支持,但PHP不是像Java或C#的OOP语言。

简短的例子只是为了强调我的陈述:

 // 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”,你可以做以下的事情:

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

接着

 $user->name; 

但是你可以像使用java或者c#一样使用OOP,但是不能使用相同的扩展方式 – 而且要记住,像wordpress和drupal这样的stream行系统并不是纯粹的OOP! 但是你也可以在PHP中做inheritance和其他的OOP类。

在PHP OOP中,我并没有走得太远,但越是越容易变得越简单。 这些对象的例子只是为了了解OOP的工作原理。 我了解并通过这之前,OOP只是属性和方法(正常variables和函数)。 我在真实的OOP中编写了自己的应用程序,并不一定要在真实的世界中。 这就像勺子喂,你永远不会理解面向对象,并会很容易忘记。 我的build议学会理解。 如果你明白,你可以做任何事情,并意识到面向对象的力量。 我下载了这本书,我想你也应该。 但是,就像有人为你build立你的应用程序…

这里有一本PHP和Mysql日常应用傻瓜书的链接

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

我不相信你应该使用PHP作为编程语言来学习OOP。 如果你想学习面向Web应用程序的OOP,你应该真的在看C#或Java。 学习完OOP后,就可以将这些知识应用到PHP中。 我曾经学习OOP的一本书的例子是Big Java by Cay S. Horstmann撰写的Big Java by Cay S. Horstmann

我为什么这么说? 因为在PHP上有几百万个关于如何做东西的例子,但是没有多less例子是如何正确编程的。 除此之外,PHP允许您使用许多快捷方式,这对于Java而言是不可接受的。 因此,如果你使用Java头来编程PHP,那么我相信你将成为一个更强大的程序员。 OOP不是语言特定的,它是一个编程范例。

如果您必须使用PHP学习OOP,那么我build议您查看一下github公共仓库中的一些真正的源代码。 你可以在packagist.org上search它们。 如果他们是一个体面的公共存储库,他们将包含一个readme.md文件,它会告诉你如何使用composer包。 例如https://github.com/moltin/laravel-cart是一个购物车包的例子,你可以在你的应用程序中使用它。; 请注意,您无需查看软件包源代码即可了解软件包的function。 这个软件包已经写好了,你不关心它们是如何工作的,但是你使用它们,所以你只需要知道如何使用它们。 这正是OOP的意思。

我不在乎购物车类如何将物品添加到购物车,我只是想创build一个新的购物车并添加一些东西。

不过,你在做的是深入的源代码作为一个工具,了解如何OOP的作品。

除此之外,也许更重要的是,对于Web应用程序开发,我将研究MVCdevise模式。

MVCdevise模式代表模型,视图,控制器。 在Web应用程序的情况下,模型负责build模数据库,视图负责向用户显示内容。 控制器负责与模型交互并处理用户input。

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

有许多教程将告诉你如何在laravel中构buildWeb应用程序。 立即,你会看到,当你创build一个控制器,你扩展一个BaseController。 当你创build一个模型时,你扩展了Eloquent。 这意味着你将已经在你的代码中使用多态。 你会看到,通过使用类,它们被封装,你会看到,每个类都有一个特定的angular色。

当您想要与数据库进行交互时,您最初将在控制器方法内创build一个new Model对象。 当你开始学习更多东西的时候,你将开始学习如何在控制器中注入依赖关系,然后学习如何转储你的模型,创build存储库和程序到接口。

对于初学者来说,一本关于学习Laravel的书籍应该是Dale Rees的https://leanpub.com/codebright 。 大约两周前,我在Laravel聚会上遇到了戴尔。

除此之外,随着您更加精通构buildWeb应用程序,您将开始学习如何将以下原则应用于您的编程:

  • 单一责任原则
  • 开放封闭原则
  • Liskov替代原则
  • 接口集成原则
  • 依赖倒置原则

我build议也看到我的包装Arrayzy 。 这是一个原生的PHP数组在OOP方式简单的操作库。

所以,如果你使用原生的PHP数组函数 – 你可以在OOP中做同样的事情,Arrayzy可以帮助你,例如:

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

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

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

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

检查这个mergeWith方法(或其他)如何工作。

我认为这是一个很好的例子,它表明几乎所有的function代码都可以用OOP代码来代替,就像在这个库中一样。 但是通过OOP,你可以获得更多 ,你也可以检查函数式编程和OOP问题,了解更多细节,它的缺点和道具。