PHP:真实世界的 OOP 示例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1343619/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 02:07:09  来源:igfitidea点击:

PHP: Real world OOP example

phpoop

提问by BDuelz

I am trying to learn OOP. The so called 'real world' examples in the books I am reading aren't helping.

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

All the examples like Pet, Car, Humanaren't helping me anymore. I need REAL LIFE examples that like registration, user profile pages, etc.

所有的例子一样PetCarHuman不能帮助我了。我需要真实的例子,比如注册、用户个人资料页面等。

An example:

一个例子:

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

I've also seen:

我也看过:

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

where :

在哪里 :

private $user = array();

Holds all the information in an array.

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

And within that same class lies

在同一个班级中

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

Are there any real world examples implementing OOP in the many different php applications (registration, login, user account, etc)?

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

回答by Peter Bailey

OOP is not only about how a single class looks and operates. It's also about how instances of one or more classes work together.

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

That's why you see so many examples based on "Cars" and "People" because they actually do a really good job of illustrating this principle.

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

In my opinion, the most important lessons in OOP are encapsulationand polymorphism.

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

Encapsulation:Coupling data and the logic which acts on that data together in a concise, logical manner Polymorphism:The ability for one object to look-like and/or behave-like another.

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

A good real-world example of this would be something like a directory iterator. Where is this directory? Maybe it's a local folder, maybe it's remote like an FTP server. Who knows!

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

Here's a basic class tree that demonstrates encapsulation:

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

<?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
    }
}

Each class/object is responsible for its own method of retrieving a directory listing. The data (variables) are coupled to the logic (class functions i.e, methods) that use the data.

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

But the story is not over - remember how I said OOP is about how instances of classes work together, and not any single class or object?

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

Ok, so let's do something with this data - print it to the screen? Sure. But how? HTML? Plain-text? RSS? Let's address that.

好的,让我们用这些数据做点什么——把它打印到屏幕上?当然。但是如何?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>";
    }
}

Ok, now we have a couple class trees for traversing and rendering directory lists. How do we use them?

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

// 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();

Now, I know what you're thinking, "But Peter, I don't need these big class trees to do this!" but if you think that then you're missing the point, much like I suspect you have been with the "Car" and "People" examples. Don't focus on the minutiae of the example - instead try to understand what's happening here.

现在,我知道你在想什么,“但是彼得,我不需要这些大类树来做这件事!” 但如果你认为那你就没有抓住重点,就像我怀疑你一直在使用“汽车”和“人”的例子一样。不要专注于示例的细节 - 而是尝试了解这里发生的事情。

We've created two class trees where one (*DirectoryRenderer) uses the other (*DirectoryIterator) in an expected way - this is often referred to as a contract. An instance of *DirectoryRendererdoesn't care which type of instance of *DirectoryIteratorit receives, nor do instances of *DirectoryIteratorcare about how they're being rendered.

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

Why? Because we've designed them that way. They just plug into each other and work. This is OOP in action.

为什么?因为我们就是这样设计的。他们只是互相插入并工作。这是 OOP 的作用

回答by RockyBalboa

Purchase a book like "PHP and Mysql everyday apps for Dummies".

购买一本书,例如“傻瓜的 PHP 和 Mysql 日常应用程序”。

Its old I know [2005] but it shows concepts of User Logins, Forum, Shopping Carts, etc in both Procedural and Object Oriented with Mysqli.

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

It helped me learn Object Oriented PHP, I studied it a lot. Well worth the money.

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

OOP is much like grouping bits of your program into reuseable pieces. Its not that hard to be honest with you its just the idea of packing your functions into classes.

OOP 很像将程序的一部分分组为可重用的部分。老实说,这只是将函数打包到类中的想法。

Real world mini example of OOP stuff below:

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

CLASS DATABASE
CLASS SESSIONS
CLASS WEBFORMS
CLASS EMAIL

班级数据库
班级
课程
班级网络表格班级电子邮件

CLASS ACCOUNTS (Example Functions below)
FUNCTION SELECTACCOUNT
FUNCTION CHECKPASSWORD
FUNCTION CHECKUSERNAME
FUNCTION CREATEACCOUNT

类帐户(以下示例函数)
FUNCTION SELECTACCOUNT
FUNCTION CHECKPASSWORD
FUNCTION CHECKUSERNAME
FUNCTION CREATEACCOUNT

I hope you keep at it, PHP 6 will be re-engineered to support OOP more than ever.

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

Good Luck!

祝你好运!

回答by Gravy

Whilst I know that this question has been answered already, I feel as though I can add value here.

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

I don't believe that you should use PHP as a programming language to learn OOP. If you wish to learn OOP for web applications, you should really be looking at C# or Java. Once you have learned OOP, then you can apply this knowledge to PHP. One example of a book I used to learn OOP was Big Java by Cay S. Horstmann

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

Why do I say this??? Because there are literally millions of examples on PHP of how to do stuff, however not many are examples of how to program properly. Further to this, PHP allows you to take many shortcuts, which would not be acceptable with the likes of Java. As such, if you program PHP with a Java head, then I believe that you will be a stronger programmer. OOP is not language specific, it is a programming paradigm.

我为什么要说这个???因为在 PHP 上有数百万个关于如何做事的例子,但是关于如何正确编程的例子并不多。此外,PHP 允许您采取许多捷径,这对于 Java 之类的程序来说是不可接受的。因此,如果您用Java 头编写PHP,那么我相信您会成为一个更强大的程序员。OOP 不是特定于语言的,它是一种编程范式。

If you must learn OOP using PHP, then I would recommend that you take a look at some real source code in public repositories of github. You can search them in packagist.org. If they are a decent public repository, they will contain a readme.md file which would show you how to use the composer packages. e.g https://github.com/moltin/laravel-cartis an example of a shopping cart package which you would be able to use in your application. Notice how you don't need to look at the package source code to understand what the packages do. The package has been written, and you don't care about how they work, but you use them so you only need to know how to use them. This is exactly what OOP is about.

如果你一定要使用 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.

我不在乎购物车类如何将商品添加到购物车中,我只想创建一个新购物车并向其中添加一些东西。

What you are doing however is diving into the source code as a tool to understand how OOP works.

然而,您正在做的是深入研究源代码,作为了解 OOP 工作原理的工具。

Further to this, and probably more importantly, for web application development, I would research the MVC design pattern.

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

The MVC design Pattern stands for Model, View, Controller. Where in the case of a web application, The Model is responsible for modelling the database, the view is responsible for displaying content to the user. The controller is responsible for interacting with the model and handling user input.

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

I then think you should try to install the Laravel Frameworkor other "decent modern framework" on your local machine. Why do I say modern, because modern frameworks require a minumum PHP version of 5.3+ which mean that the PHP on your machine would support real OOP similar to that which you would get from the likes of Java.

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

There are many tutorials which will show you how to build web applications in laravel. Immediately, you will see that when you create a controller, you extend a BaseController. When you create a Model, you extend Eloquent. This means that you will already be using Polymorphism in your code. You will see that by using classes, they are being encapsulated, and you will see that each class has a specific role.

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

When you would like to interact with the database, you will initially create a new Modelobject within the controller methods. As you start to learn more, you will start learning how to inject dependencies into the controller, then learning how to dump your models and create repositories and program to interfaces instead.

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

A decent book on learning Laravel for beginners would be https://leanpub.com/codebrightby Dale Rees. I met Dale at a Laravel meetup about 2 weeks ago.

一本适合初学者学习 Laravel 的书是 Dale Rees 的https://leanpub.com/codebright。大约两周前,我在 Laravel 聚会上遇到了 Dale。

Further to this, as you become more proficient building web applications, you will start to learn how to apply the following principles to your programming:

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

  • Single Responsibility Principle
  • Open Closed Principle
  • Liskov Substitution Principle
  • Interface Segragation Principle
  • Dependency Inversion Principle
  • 单一职责原则
  • 开闭原则
  • 里氏替换原则
  • 接口隔离原则
  • 依赖倒置原则

回答by blakroku

I haven't gone far in PHP OOP, but the more i get into it the more easier it becomes. The objects examples are just there for you to understand how OOP works. I understand and been through this before, OOP is just about properties and methods ( normal variables and functions). I programed in real OOP myself applying the examples from my tutorials and didn't necessarily have to be in real world. That is just like been spoon fed and you would never understand OOP and would be easy to forget. My advice learn to understand. If you understand, you can do anything and would realize the power of OOP. I downloaded this book and i think you should too. But that is just like someone building your apps for you...

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

Herea link to the book PHP and Mysql everyday Apps For Dummies

这里是 PHP 和 Mysql 日常 Apps For Dummies 一书的链接

回答by mooware

As astropanic said, you could take a look at the source code of a good PHP framework or library. I recommend Zend Framework, it's very modular and has a great, professional design. I would say it is a very good piece of object-oriented PHP code.

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

Still, I think it's not that easy to learn from a huge piece of production code, since it wasn't really made to teach you anything. But if you want real-world object-oriented PHP code, the Zend Framework (or Symfony, or maybe CakePHP) is probably the way to go.

尽管如此,我认为从大量生产代码中学习并不是那么容易,因为它并不是真正用来教你任何东西的。但是,如果您想要真实世界的面向对象的 PHP 代码,Zend Framework(或 Symfony,或 CakePHP)可能是您要走的路。

回答by kristian nissen

I'd advise you to stay away from any framework at this moment, if you do not know OOP, digging into zend or any other framework would be too much.

我建议你此时远离任何框架,如果你不了解 OOP,深入研究 zend 或任何其他框架就太多了。

PHP OOP is quit funny... like ha ha funny, because it's supported, but PHP is not an OOP language like java or c#.

PHP OOP 很有趣......就像哈哈有趣,因为它被支持,但 PHP 不是像 java 或 c# 这样的 OOP 语言。

Short example just to underline my statement:

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

// 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;

but if you want to do OOP "on the fly" you can do the following:

但如果您想“即时”执行 OOP,您可以执行以下操作:

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

and then

进而

$user->name;

but you can use OOP like you would in java or c# but not to the same extend - and have in mind, popular systems like wordpress and drupal are not pure OOP! but you can do inheritance and other classing OOP stuff in PHP as well.

但是您可以像在 java 或 c# 中一样使用 OOP,但扩展范围不同 - 请记住,像 wordpress 和 drupal 这样的流行系统不是纯 OOP!但是你也可以在 PHP 中进行继承和其他类 OOP 的东西。

回答by Victor Bocharsky

I suggest also to see my wrapper Arrayzy. It's a native PHP arrays easy manipulation library in OOP way.

我还建议看看我的包装器Arrayzy。它是一个以 OOP 方式进行的原生 PHP 数组简单操作库。

So if you work with native PHP array functions - you could do the same things in OOP and Arrayzy helps you with it, for example:

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

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

and

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

In both cases the result array will be:

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

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

Check how does this mergeWithmethod (or other) works under the hood.

检查此mergeWith方法(或其他方法)在幕后如何工作。

I think this is a nice example which shows that almost everything functionalcode you could replace with OOPcode like in this library. But with OOP you get much moreand you could also check Functional programming vs OOPquestion to learn more details what's a cons and props of it.

我认为这是一个很好的例子,它表明几乎所有的功能代码都可以用这个库中的OOP代码替换。但是使用 OOP,您可以获得更多,您还可以查看函数式编程与 OOP问题以了解更多详细信息,它的缺点和优点是什么。