2014-10-17 94 views
1

我遇到了一個似乎意味着我不瞭解Laravel中的架構如何正常工作的問題。我是Laravel新手,但我認爲我知道這一點。當客戶端請求頁面時,將調用一個Controller,它從Model中提取數據並將其傳遞給視圖。如果前面的說法是正確的,那麼爲什麼出現這樣的問題:Laravel應用程序體系結構問題。在Controller&View之間調用模型?

在我JourneyController

public function journey($id) { 

    // Find the journey and the images that are part of the journey from the db 
    $journey = Journey::find($id); 
    $imagesInJourney = Journey::find($id)->images->keyBy('id'); 

    // Perform some manipulation on the article. THE ERROR OCCURS HERE. 
    $journey->article = str_replace('[[ ' . $image . ' ]]', $html, $journey->article); 

    return View::make('journey', array(
     'journey' => $journey, 
     'title' => $journey->name, 
     'bodyClass' => 'article' 
    )); 
} 

該控制器被調用,並從我的Journey模型(下圖)中提取數據。特別是,我有一個屬性,我把它叫做article,那我送我的控制器之前操作:

class Journey extends Eloquent { 

    protected $table = 'journeys'; 
    protected $primaryKey = 'id'; 
    public $timestamps = false; 

    // Database relationship 
    public function images() { 
     return $this->hasMany('Image'); 
    } 

    // THIS IS THE PROBLEMATIC METHOD 
    public function getArticleAttribute($value) { 
     return file_get_contents($value); 
    } 

} 

正如你所看到的,我編輯article領域,這僅僅是一個鏈接一個文件,並使用PHP的file_get_contents()函數將其替換爲實際文件內容。所以我的理解是,當這回到上面的控制器時,$journey->article將包含文章本身,而不是URL到它

然而,出於某種原因,在我的控制器,在那裏我更換圖片文章文本的部分這一說法,是造成問題:

$journey->article = str_replace('[[ ' . $image . ' ]]', $html, $journey->article); 

在我看來比在journey.blade.php,我試圖輸出$journey->article ,期望它是文章的文本添加了圖像中的,但我收到錯誤消息:

ErrorException (E_UNKNOWN) file_get_contents(*entire article content here*): failed to open stream:  Invalid argument (View: app/views/journey.blade.php) 

爲什麼會發生這種情況時,我嘗試調用str_replace()?如果我將它評論出來,它可以很好地工作

回答

2

由於您第一次獲得時每次獲取/回顯此屬性時都會調用getArticleAttribute方法,所以沒有任何問題(這是執行str_replace函數的位置),但是當您嘗試再次獲取文章屬性時(這是你在視圖頁中回顯)你已經改變了屬性的值,所以你的函數試圖再次執行file_get_contents。

解決方案將在旅程類中設置一個標誌,並在執行file_get_contents時將其設置爲true,並將該屬性本身返回給其他調用。

贊;

class Journey extends Eloquent { 

    protected $table = 'journeys'; 
    protected $primaryKey = 'id'; 
    public $timestamps = false; 
    private $article_updated = false; 

    // Database relationship 
    public function images() { 
     return $this->hasMany('Image'); 
    } 

    // THIS IS THE PROBLEMATIC METHOD 
    public function getArticleAttribute($value) { 
     if($this->article_updated){ 
      return $value; 
     } 
     else { 
      $this->article_updated = true; 
      return file_get_contents($value); 
     } 

    } 

} 
+0

這似乎與MVC應該做的截然相反。有沒有關於這個「功能」的文檔? – ReactingToAngularVues 2014-10-17 23:09:37

+0

實際上這是關於OOP的,ORM對模型屬性使用了魔術__get函數,並且當您定義訪問器時,它會調用您的訪問器函數(https://github.com/illuminate/database/blob/master/Eloquent/Model)。在你的情況下,你有一個文章屬性的旅程模型(所有屬性在「protected」屬性數組中定義),並且每當你編寫'$ journey-> article'時,ORM的__get函數被調用,所以它是你的訪問者。你可以檢查「封裝」。 – engvrdr 2014-10-18 08:06:45