簡體   English   中英

在CakePHP框架內自動創建數據庫表

[英]Automate database table creation from within CakePHP framework

我正在嘗試使用CakePHP編寫一個Web應用程序,並且像大多數Web應用程序一樣,我想創建一個安裝程序來檢測數據庫是否已初始化,如果沒有,則執行安裝過程。

此過程將完全自動化(假定數據庫本身已經存在,並且通過無密碼的匿名帳戶被授予了完全管理訪問權限...這是針對沙盒環境的,因此無需擔心安全性),因此需要以便能夠檢測(無論請求是什么!)是否已經創建並初始化了數據庫表,如果沒有,則透明地執行該初始化,然后仍然滿足用戶的原始請求。

我考慮編寫一種引導所有請求都通過其進行引導的Bootstrap控制器,並運行一個SQL查詢來確定數據庫表是否存在,但這似乎很麻煩(並且該控制器需要一個相應的模型,而事實並非如此)這里)。 另一種可能性是重寫AppModel並將其放置在同一測試中,但是我不確定如何執行此操作,因為這些方面沒有任何文檔。

提前致謝!

tl; dr版本 :J2EE Servlet的“ init()”方法的CakePHP等效項(或如何為CakePHP編寫等效項)?

檢出AppError類-可能存在丟失的數據庫表錯誤,您可以覆蓋該錯誤並從那里運行創建數據庫表SQL?

您是否真的要使每個請求都檢查數據庫是否存在? 這似乎非常浪費。

它第一次檢查將建立數據庫,然后即使在此之前已經建立了數據庫的情況下,接下來的每百萬個請求也將再次檢查!

最好要求安裝應用程序的任何人進行一些設置。 您應該提供一個單獨的腳本,該腳本不會在每個請求期間運行,而是由人員在安裝過程中手動運行。


關於您使用CakePHP做到這一點的最佳方法的評論,您是否看過Cake對數據庫模式遷移的支持?

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

這樣的事情可能會滿足您的需求,但確實需要針對每個模型進行額外的查詢。

<?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文檔包含有關“ IF NOT EXISTS”的更多信息。

但是 ,我不確定這不是嘗試過早調用query()。 或者在檢查表是否已經存在之前( 必須存在)。 否則,CakePHP會出錯,而不是創建表。 關於該主題的文檔並不多,最好的選擇是獲取更多信息,直接查看cake / libs / model / model.php。

更新:上面的代碼無法正常工作。

在深入研究Model類之后,Model :: __ construct調用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);
}
?>

我考慮過在某個時間點這樣做,並想出了一種很好的方法來做到這一點。

首先,請注意:我認為您的應用程序需要對app / config / database.php的寫權限,因此您可以編寫正確的信息。 我有一個解決方法,但讓我解釋一下安裝程序的工作方法。

PHP腳本可以即時重寫(或刪除自身)。 由於腳本已加載到內存中,然后執行了字節碼,因此一旦完成工作,它就不再依賴於文件。 因此,從理論上講,您可以使用某些東西來覆蓋AppError類,以在加載了所有常規CakePHP東西的情況下運行特定的控制器(例如SetupWizardController)。 完成整個向導后,編寫database.php文件/進行任何其他設置,覆蓋AppError和AppController文件(如果某些情況下未安裝該應用程序,我將看到您需要AppController以不同的方式工作)存儲在app / vendors / myapp中的文件。 該腳本已執行完畢,現在您的檢查將不會在后續運行中進行。

這樣可以消除Bill Karwin提出的問題,利用AppError並安裝程序。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM