2009-07-16 45 views
10

我想知道在php類中使用self/method()和parent :: method()是否可接受/首選。

可以使用這 - $>方法(),但$這 - >也可以指一類變量,父類變量,或從父類的方法。有自我::

是自::貶值和/或是否有任何警告或缺點,使用這種風格不會產生歧義?

據我所知,自::和家長::引用類的靜態實例,但在Kohana中,除非你專門定義的方法靜態的,似乎沒有成爲一個差異。

謝謝。

添加了一個例子:從多個網站 假設這個應用商店論壇...

class Forum_Controller extends Controller { 

    function __construct() 
    { 
     parent::__construct(); 
    } 

    function index() 
    { 
     echo self::categories(); 
    } 

/* 
* get a list of categories from a specific site. 
*/ 
    private function categories() 
    { 
     $db = new Database; 
     $categories = $db->query(" 
      SELECT * FROM 
      forum_categories 
      WHERE fk_site = '$this->site_id' 
     "); 
     $view = new View('categories_view'); 
     $view->categories = $categories; 
     return $view; 
    } 

} 

這個例子工程的Kohana與錯誤報告設置爲: 的error_reporting(E_ALL &〜E_STRICT);

$ this-> site_id在主Controller_Core類(kohana中的一個庫)中定義。

據我所知,$這不應該是可用的,因爲我以靜態方式調用self :: categories(),但它只是當我將類()定義爲靜態,它會拋出一個錯誤。

但正如我所說,我更寧可選擇使用自::因爲從可讀性的角度來看,我確切地知道這個功能是應該的,而不是使用$這引起歧義,對我來說那是。

+1

該代碼工作的原因是因爲你永遠指的是$在靜態調用的類方法的對象實例中。 – null 2009-07-16 11:59:53

回答

6

控制器在Kohana中不是靜態的,儘管它們可以包含靜態成員變量/方法或常量。

self::是寫ClassName::

class Animal 
{ 
    public static $arms = 0; 
} 

class Dog extends Animal 
{ 
    public static $leg = 0; 
    const NAME = 'dog'; 

    public static function bark() 
    { 
     echo 'Woof'; 
    } 
} 

要調用靜態函數或從我們使用範圍解析操作::一類得到的常數的簡便方法。靜態功能是每類不是每個對象。說::是指一個類的靜態實例是錯誤的,它只是一種訪問靜態方法的方法 - 沒有一個具有這些方法的對象實例。

這樣:

Dog::bark(), 
Dog::$leg, 
Dog::NAME, 

我們還可以用

Animal::$arms 

在類犬,我們可以使用self::parent::,使我們不必輸入完整的類名(因爲它可以是很長的!)

回答你的問題,雖然:否 - self::不被棄用,並且不是不好的做法是使用它。它在kohana核心中沒有使用的原因是一個非常不同的原因....(透明類擴展eval閱讀下面的更多信息...)。

P.S調用非靜態方法靜態是錯誤如果設置error_reporting(E_ALL | E_STRICT)不應該准予(像你應該在開發過程中),你會看到正在引發錯誤。

基本上發生的事情是:

核心有一個文件名爲:

class Controller_Core { 
    public function someMethod(){} 
} 

創建:

// We can use someMethod of Controller_Core 
Index_Controller extends Controller {} 

這真是延長Controller_Core除非您已經創建MY_Controller .php這將是class Controller extends Controller_Core

//MY_Controller.php 
class Controller extends Controller_Core 
{ 
     // overloads Controller_Core::someMethod without us having to change the core file 
     public function someMethod(){} 
} 
0

我認爲self ::通常用於靜態函數和屬性。

我使用Kohana,也許控制器是靜態的。

16

有區別。

$this引用對象的一個​​實例。

parentself用於靜態調用方法。

This page of PHP's manual解釋它更好的細節比我有時間的時刻來寫。第一個例子特別應該有助於突出一些差異。我鼓勵你複製粘貼第一個例子並且把它弄糊塗,因爲如果你不知道其中的差別,我認爲它是一個重要的概念。

+0

謝謝你的回覆。文檔鏈接非常有幫助。否則,我無法拿出正確的詞語來找到它。 – superjadex12 2009-07-16 11:35:43

+0

父項不是(僅)用於靜態調用方法。如果從Object上下文中調用它,它將使用對象上下文在父類中調用該函數。 – 2013-12-06 14:36:50

0

我不能添加評論(顯然我沒有必要的代表!)

class Forum_Controller extends Controller { 

public function __construct() 
{ 
    parent::__construct(); 
} 

public function index() 
{ 
    echo self::categories(); 
} 

/* 
* get a list of categories from a specific site. 
*/ 
private static function categories() 
{ 
    $db = new Database; 

    // You cannot use $this in a static function, because static functions are per class 
    // and not per object it doesnt know what $this is :) (make private static $site_id and use self::$site_id) if this is what you want 

    $categories = $db->query(" 
      SELECT * FROM 
      forum_categories 
      WHERE fk_site = '$this->site_id' 
    "); 
    $view = new View('categories_view'); 
    $view->categories = $categories; 
    return $view; 
} 

}

就像我說的,你應該使用的error_reporting(E_ALL | E_STRICT) ; (在Kohana的文件更改)

調用私有函數類別()靜態工作由於PHP的錯誤,你不應該是能夠做到這一點:)

0

另一件事情的方式需要注意的是這是不是很好的MVC設計使靜態控制器函數返回類別列表。

控制器用於處理請求,模型用於處理數據(這是什麼)和視圖用於顯示。

做個模型!

class Category_Model extends Model 
{ 
     public function categories($site_id) 
     { 
      $categories = $this->db->from('forum_categories')->where('fk_site',$site_id)->get(); 

       return new View('categories_view', array('categories' => $categories)); 
     } 
} 

...

$cat = new Category_Model; 

echo $cat->categories(1); 
0

我嚴格使用自::僅適用於靜態變量和靜態成員函數

相關問題