2009-08-27 120 views
43

我正在嘗試學習OOP。我正在閱讀的書中所謂的「真實世界」例子並沒有幫助。PHP:真實世界的OOP示例

所有的例子,如Pet,Car,Human不再幫助我。我需要現實生活中的例子,像註冊,用戶個人資料頁等

一個例子:

$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任何現實世界的例子(註冊,登錄,用戶帳戶等)?

+0

**請參閱:**「無行爲比較OOP vs程序」: http://stackoverflow.com/questions/1530868 – dreftymac 2009-12-04 18:26:34

回答

77

面向對象不僅僅是一個類的外觀和操作方式。這也是關於一個或多個類的實例如何一起工作。

這就是爲什麼你看到很多基於「汽車」和「人」的例子,因爲他們真的很好地闡明瞭這個原理。

在我看來,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。

+11

+2如果我可以! – 2009-08-27 22:08:11

+0

是否有一些用戶示例?我希望有一個管理和身份驗證的例子。如果有人知道某處,我會很感激。 – iLevi 2013-01-08 17:38:45

+0

@Peter Bailey不幸的是我的問題已經被關閉了,但是如果你能幫助我[這個問題(鏈接這裏)],我會很高興的(http://stackoverflow.com/questions/14221240/practical-way-to-implement -oop功能於PHP-對用戶#comment19725375_14221240) – iLevi 2013-01-08 19:07:21

1

正如astropanic所說,你可以看看一個好的PHP框架或庫的源代碼。我推薦Zend Framework,它非常模塊化,並有一個偉大的專業設計。我會說這是一個非常好的面向對象的PHP代碼。

儘管如此,我認爲從一段巨大的產品代碼中學習並不是那麼容易,因爲它不是真正教你什麼。但是如果你想要真實世界的面向對象的PHP代碼,Zend Framework(或者Symfony,或者CakePHP)可能是一種可行的方法。

1

我建議你暫時不要使用任何框架,如果你不知道面向對象,挖入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不是純粹的OOP!但是您也可以在PHP中進行繼承和其他類別的OOP操作。

+13

對不起,但'$ user =(object)array( 'name'=>'Peter');'*不是* OOP - 或者甚至像您所說的「即時OOP」。那只是一個對象。使用對象!= OOP。顯然,對象的使用是面向對象的一個​​組成部分,但它的* WAY *比這更多。 – 2009-08-27 22:33:28

7

購買一本像「PHP和Mysql日常應用傻瓜」的書。

它的老我知道[2005],但它顯示了用戶登錄,論壇,購物車等與Mysqli程序和麪向對象的概念。

它幫助我學習面向對象的PHP,我研究了很多東西。非常值得的錢。

OOP非常類似於將您的程序的各個部分組合成可重複使用的部分。對你來說,它並不難以誠實地把你的函數打包成類。

現實世界的下面面向對象的東西迷你例如:

級數據庫
CLASS SESSIONS
CLASS web表單
級電子郵件

CLASS帳目(下面的實施例的功能)
FUNCTION SELECTACCOUNT
FUNCTION CHECKPASSWORD
FUNCTION CHECKUSERNAME
FUNCTION CREATEACCOUNT

我希望你繼續努力,PHP 6將被重新設計,以支持OOP比以往更多。

祝你好運!

1

我在PHP OOP中並沒有走得太遠,但我越是越容易變得越簡單。對象示例僅供您瞭解OOP如何工作。我之前瞭解並經歷了這個,OOP只是關於屬性和方法(正常變量和函數)。我在真實的OOP中編程,自己應用了我的教程中的示例,並不一定非要在真實世界中。這就像勺子喂,你永遠不會理解面向對象,並會很容易忘記。我的建議學會理解。如果你明白,你可以做任何事情,並會意識到OOP的力量。我下載了這本書,我想你也應該。但是,這就像一個人構建的應用程序爲你...

Here書PHP和MySQL的日常應用傻瓜

1

雖然我知道這個問題已經已經回答一個鏈接,我覺得好像我可以在這裏增加價值。

我不認爲你應該使用PHP作爲編程語言來學習OOP。如果你想爲Web應用程序學習OOP,你應該看看C#或Java。一旦你瞭解了OOP,那麼你可以將這些知識應用到PHP中。我用來學習面向對象的一本書的一個例子是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的意思。

我不在乎購物車類如何將商品添加到購物車,我只是想創建一個新購物車併爲其添加內容。

但是你正在做的是深入瞭解源代碼作爲了解OOP如何工作的工具。

除此之外,也許更重要的是,對於Web應用程序開發,我將研究MVC設計模式。

MVC設計模式代表模型,視圖,控制器。在Web應用程序的情況下,模型負責建模數據庫,視圖負責向用戶顯示內容。控制器負責與模型交互並處理用戶輸入。

然後,我認爲你應該嘗試在本地機器上安裝Laravel Framework或其他「體面的現代框架」。爲什麼我要說現代化,因爲現代框架需要5.3以上的最小PHP版本,這意味着您的機器上的PHP將支持真實的OOP,類似於您將從Java中獲得的類似內容。

有許多教程將告訴你如何在laravel中構建Web應用程序。立即,你會看到當你創建一個控制器時,你擴展了一個BaseController。當你創建一個模型時,你擴展了Eloquent。這意味着你已經在你的代碼中使用了多態性。你會看到,通過使用類,它們被封裝,你會看到每個類都有一個特定的角色。

當您想與數據庫交互時,您最初將在控制器方法內創建一個new Model對象。隨着您開始學習更多,您將開始學習如何向控制器注入依賴關係,然後學習如何轉儲模型並創建存儲庫和編程接口。

Dale Rees爲初學者提供了一本關於學習Laravel的書籍,內容是https://leanpub.com/codebright。大約兩週前,我在拉拉維爾的聚會上遇到戴爾。

而且到這一點,因爲你變得更加熟練構建Web應用程序,你會開始學習如何運用以下原則編程:

  • 單一職責原則
  • 開閉原則
  • Liskov替代原則
  • 界面分割原理
  • 依賴倒置原理
0

我建議也看看我的包裝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方法(或其他)在引擎蓋下工作。

我覺得這是一個很好的例子表明,幾乎所有功能代碼,你可以用OOP取代像這個庫代碼。但隨着OOP你,你也可以檢查Functional programming vs OOP問題,以瞭解更多詳細信息,什麼是缺點和它的道具。