2009-10-31 81 views
3

我試圖寫有CakePHP的web應用程序,像大多數web應用,我想創建檢測數據庫是否已初始化安裝程序,如果沒有,執行安裝過程。自動化數據庫表的創建

此過程將完全自動化(假定數據庫本身已存在,並且通過匿名帳戶授予完全管理訪問權限,不需要密碼......這是針對沙箱環境的,因此不用擔心安全問題) ,所以如果數據庫表已經被創建和初始化,它就需要能夠檢測到(不管請求!),如果沒有,則透明地執行初始化,然後提供用戶的原始請求。

我認爲寫了一種Bootstrap控制器,通過它來路由所有的請求,並且運行一個SQL查詢來確定數據庫表是否存在,但這看起來很麻煩(並且控制器需要一個相應的模型,這裏就是這種情況)。另一種可能性是重寫AppModel並在其中放置相同的測試,但我不確定如何執行此操作,因爲這些行中沒有任何文檔。

在此先感謝!

tl; dr版本:什麼是J2EE servlet的「init()」方法的CakePHP等價物(或者如何編寫用於CakePHP的等價物)?

回答

3

退房的AppError類 - 可能是有,你可以重寫,並從那裏運行創建數據庫表的SQL缺少數據庫表的錯誤?

+0

這實際上正是我正在研究的內容 - 要麼將錯誤頁面中的鏈接提供給將自動填充表格的腳本,要麼只是在錯誤類中進行,如果這是生成的錯誤。謝謝! – Magsol 2009-10-31 20:52:24

+0

@Magsol你究竟是怎麼實現這個的?我很好奇。 – khany 2014-05-30 09:38:14

+0

很難確定 - 這是前一段時間 - 但我確信我創建了一個AppError類,並用代碼覆蓋missingTable錯誤函數以生成數據庫模式。拿一點鹽吧:我懷疑CakePHP在5年內發生了很大變化! – Magsol 2014-05-30 15:37:09

2

你真的想數據庫存在每個請求覈查?這似乎非常浪費。

它會檢查它會建立數據庫,然後下一個萬個請求它將再次,即使該數據庫具有當然的這個時候,設立了檢查每個人的第一次!

這是一個更好的主意,要求任何人安裝您的應用程序做一些設置。您應該在每次請求期間提供一個單獨的腳本,該腳本的執行時間爲,而不是,但在安裝期間由該人員手動運行。


重新您對使用CakePHP做到這一點的最好辦法評論,有你看着蛋糕的數據庫架構遷移的支持?

http://book.cakephp.org/view/734/Schema-management-and-migrations

+0

我非常喜歡那個;我想我正在尋找一個J2EE servlet的「init()」方法的CakePHP等價物,如果這樣的事情存在或可以寫的話。儘管單獨的腳本也可以工作,但是仍然需要在主應用程序中檢查數據庫表是否存在,如果不存在,則建議用戶運行該腳本。 – Magsol 2009-10-31 04:55:50

+0

我認爲針對不存在的表的任何查詢都會很好地揭示這一事實。 – 2009-10-31 05:21:21

+0

看,我這裏的重點是我不熟悉CakePHP框架。我瞭解網絡編程的原則和範例;我只是不確定如何在CakePHP環境中實現它們。在這方面的任何建議是我正在尋找的。 – Magsol 2009-10-31 14:40:31

2

像這樣的事情可能會做你要找的東西,但確實需要每個模型的額外查詢。

<?php 
class AppModel extends Model { 
    var $create_query = false; 

    function __construct($id = false, $table = null, $ds = null) { 
     parent::__construct($id, $table, $ds); 

     if (!empty($this->create_query)) { 
      $this->query($this->create_query); 
     } 
    } 
} 
?> 

然後,您只需要在模型中添加var $create_query = 'CREATE TABLE IF NOT EXISTS ...;`。 MySQL CREATE TABLE documentation有關於IF NOT EXISTS的更多信息。

但是,我不確定這是不是試圖調用查詢()太早。或前檢查,看看錶已經存在,它會是。否則,CakePHP會出錯而不是創建表。關於這個主題沒有太多的文檔,你最好直接去看看cake/libs/model/model.php的更多信息。

更新:上面的代碼所寫是行不通的。

在深入研究Model類後,Model :: __構造調用Model :: setSource()。 Model :: setSource()檢查表是否存在,如果不存在則拋出錯誤。要使用此方法,那就是您必須重寫並插入查詢的位置。下面的代碼可能需要不同,具體取決於您使用的CakePHP版本。

<?php 
function setSource($tableName) { 
    // From Model::setSource(). I believe this is needed to make query() work. 
    $this->setDataSource($this->useDbConfig); 

    // Create our table if we have a create query 
    if (!empty($this->create_query)) { 
     $this->query($this->create_query); 
    } 

    // Now call the parent 
    parent::setSource($tableName); 
} 
?> 
1

我曾想過在某個時間點做這件事,並提出了一個很好的方法來做到這一點。

首先,注意:我相信你的應用程序需要寫訪問app/config/database.php,所以你可以寫出正確的信息。我有一個解決方法,但讓我解釋安裝程序的工作方法。

PHP腳本可以自己重寫自己(或刪除自己)。由於腳本被加載到內存中,並且字節碼被執行,所以一旦它完成工作,它就不依賴於文件。所以理論上你可以擁有一些重寫AppError類來運行一個特定的控制器(比如你的SetupWizardController)和所有常規CakePHP的東西。一旦你經歷了整個嚮導,寫下其他所需的database.php文件/設置,覆蓋AppError和AppController文件(我可以看到你需要AppController以不同的方式工作,如果應用程序未在某些情況下安裝)那些存儲在app/vendors/myapp中的地方。該腳本已完成執行,現在您的檢查不會在後續運行中發生。

這將擺脫比爾卡爾文提出的問題,利用AppError,並使安裝程序。

另一種方法是在應用程序中包含環境的概念。假設你將你的環境存儲在app/config/environment.php中。該文件將被授予寫入權限(並且該權限將在安裝結束時被刪除),或者可能被覆蓋。無論如何,只要有人試圖部署應用程序,它就會存在,並且database.php會自動從environment.php文件導入數據庫。然後,database.php類的構造函數將使用environment.php中指定的那個覆蓋它的$ default數據庫。 database.php中的$ default將引用一個NoDB數據源,您可以在AppController中檢查它(我認爲您可以實例化一個虛擬模型並檢查它的數據源),然後推送所需的安裝程序。顯然你也可以在這之後覆蓋AppController。