程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> Magento 開發筆記5

Magento 開發筆記5

編輯:關於PHP編程

在任何一個快速迭代的工程下,如何保證開發和生產(現網)數據庫同步是一個很頭疼的事情。Magento提供了一個創建資源遷移版本的系統,可以幫助我們處理開發過程中不斷遇到的這個問題。www.2cto.com   上次我們創建了weblogpost的模型。這次,我們執行直接執行CREATE TABLE。我們將未我們的module創建一個Setup Resource,而該資源會創建一個表格。我們同時也會創建一個升級的腳本,它能升級已經安裝的module。總的來說   1.     在config裡增加SetupResource   2.    創建resourceclass文件   3.    創建installerscript   4.    創建升級script   增加Setup Resource 我們在<resource/>部分增加下面的   <resources>        <!-- ... -->        <weblog_setup>            <setup>                <module>XStarX_Weblog</module>             <class>XStarX_Weblog_Model_Resource_Mysql4_Setup</class>            </setup>            <connection>                <use>core_setup</use>            </connection>        </weblog_setup>        <!-- ... -->    </resources>   <weblog_setup>標簽是用來唯一表示SetupResource的。通常鼓勵使用modelname_setup。<module>XStarX_Weblog</modul>標簽下應該包含我們模塊的Pachagename_Modulename。最後<class>XStarX_Weblog_Model_Resource_Mysql4_Setup</class>應該包含我們要創建的Setup  Resource類的名字。對於基本的腳本來說,沒有必要創建自己的類,但是這麼做,以後可以更靈活。   增加完配置後,清除cache,並且加載Magento Site,你會發現出異常了   Fatalerror: Class 'XStarX_Weblog_Model_Resource_Mysql4_Setup' not found in    Magento試圖實例化我們在config裡聲明的類,但是沒有找到。我們需要創建這樣的類文件app/code/local/XStarX/Weblog/Model/Resource/Mysql4/Setup.php   classXStarX_Weblog_Model_Resource_Mysql4_Setup extendsMage_Core_Model_Resource_Setup { }    現在重新加載Magento網站,異常就消失了。                       創建安裝腳本               接下來,我們要創建安裝腳本。腳本包含了之前的CREATETABLE語句。   首先,先看一下config.xml   <modules>        <XStarX_Weblog>            <version>0.1.0</version>        </XStarx_Weblog>   </modules>   這個部分在配置文件中是必備的,標示了module的同時也告訴了版本。安裝腳本要基於版本好。在下列位置創建文件   app/code/local/XStarX/Weblog/sql/weblog_setup/mysql4-install-0.1.0.php   echo 'Running This Upgrade: '.get_class($this)."\n<br /> \n";    die("Exit for now");   路徑的weblog_setup部分匹配了config.xml文件<weblog_setup/>。0.1.0部分匹配了module的版本。清除緩存,加載頁面,可以看到   Running This Upgrade:Alanstormdotcom_Weblog_Model_Resource_Mysql4_Setup Exit for now  ...   這意味著我們的update腳本執行了。最終我們把SQL更新文件放在這裡,但是暫時我們把精力放在setup機制上。把die聲明去掉,   echo 'Running This Upgrade:'.get_class($this)."\n <br /> \n";    重新加載頁面,可以看到升級消息在頁面的首部分展示。重新加載,頁面將恢復正常。因為setup就一次嘛。不可能總setup。   創建安裝腳本 MagenoSetup Resources容許我們簡單的放置安裝腳本和升級腳本,然後系統就會自動執行。這容許我們系統中的數據遷移腳本保持一次。   使用database client,查看core_resroucetable   mysql> select * from core_resource;    +-------------------------+---------+ |code                    | version |+-------------------------+-----+    |adminnotification_setup | 1.0.0   |     | admin_setup             | 0.7.1   |     | amazonpayments_setup    | 0.1.2  |     | api_setup               | 0.8.1   |     | backup_setup            | 0.7.0   |     | bundle_setup            | 0.1.7   |     | catalogindex_setup      | 0.7.10 |     | cataloginventory_setup  | 0.7.5  |     | catalogrule_setup       | 0.7.7  |     | catalogsearch_setup     | 0.7.6  |     | catalog_setup           | 0.7.69  |     | checkout_setup          | 0.9.3   |     | chronopay_setup         | 0.1.0   |     | cms_setup               | 0.7.8   |     | compiler_setup          | 0.1.0   |     | contacts_setup          | 0.8.0   |     | core_setup              | 0.8.13  |     | cron_setup              | 0.7.1   |     | customer_setup          | 0.8.11  |     | cybermut_setup          | 0.1.0   |     | cybersource_setup       | 0.7.0  |     | dataflow_setup          | 0.7.4   |     | directory_setup         | 0.8.5   |     | downloadable_setup      | 0.1.14 |     | eav_setup               | 0.7.13  |     | eway_setup              | 0.1.0   |    | flo2cash_setup          | 0.1.1   |     | giftmessage_setup       |0.7.2   |    | googleanalytics_setup   | 0.1.0  |     | googlebase_setup        | 0.1.1   |     | googlecheckout_setup    | 0.7.3  |     | googleoptimizer_setup   | 0.1.2  |     | ideal_setup             | 0.1.0   |     | log_setup               | 0.7.6   |     | newsletter_setup        | 0.8.0   |     | oscommerce_setup        | 0.8.10  |     | paybox_setup            | 0.1.3   |     | paygate_setup           | 0.7.0   |     | payment_setup           | 0.7.0   |     | paypaluk_setup          | 0.7.0   |     | paypal_setup            | 0.7.2   |     | poll_setup              | 0.7.2   |     | productalert_setup      | 0.7.2  |     | protx_setup             | 0.1.0   |     | rating_setup            | 0.7.2   |     | reports_setup           | 0.7.7   |     | review_setup            | 0.7.4   |     | salesrule_setup         | 0.7.7   |     | sales_setup             | 0.9.38  |     | sendfriend_setup        | 0.7.2   |     | shipping_setup          | 0.7.0   |     | sitemap_setup           | 0.7.2   |     | strikeiron_setup        | 0.9.1   |     | tag_setup               | 0.7.2   |     | tax_setup               | 0.7.8   |     | usa_setup               | 0.7.0   |    | weblog_setup            | 0.1.0   |     | weee_setup              | 0.13    |     | wishlist_setup          | 0.7.4   |     +-------------------------+---------+ 59 rowsin set (0.00 sec)    這個表格包含了所有安裝module的list,同時還有對應的版本。在表的結尾部分看到了   | weblog_setup            | 0.1.0   |     這個就是Magento如何知道要不要重新執行腳本。如果都成功,頁面就會加載。Weblog_setup已經安裝了,所以不需要更新。如果想重裝腳本,需要刪除表裡的改行。我們現在可以刪除   DELETE from core_resource where code = 'weblog_setup';   然後刪除對應的table   DROP TABLE blog_posts;    接著在setup腳本裡增加   $installer = $this;    $installer->startSetup();    $installer->run("        CREATE TABLE `{   $installer->getTable('weblog/blogpost')}`(          `blogpost_id`int(11) NOT NULL auto_increment,          `title`text,          `post`text,          `date`datetime default NULL,          `timestamp`timestamp NOT NULL default CURRENT_TIMESTAMP,       PRIMARY KEY  (`blogpost_id`)     )    ENGINE=InnoDBDEFAULT CHARSET=utf8;         INSERTINTO `{$installer->getTable('weblog/blogpost')}` VALUES (1,'My NewTitle','This is a blog post','2009-07-01 00:00:00','2009-07-02 23:12:30');         ");    $installer->endSetup();   清除cache,加載頁面,你可以看到blog_posts又創建了,並且有一條數據。   創建安裝腳本---問題 上面的安裝可能不會那麼順利,在magento1.7下面會報錯   Mage_Eav_Exception: Can't create table: module_entity     如何解決呢?   Debug createEntityTables()方法,可以在結尾處看到   $connection->beginTransaction(); try {      foreach ($tables as $tableName => $table) {         $connection->createTable($table);     }     $connection->commit(); } catch (Exception $e) {    Zend_Debug::dump($e->getMessage());    $connection->rollBack();    throw Mage::exception('Mage_Eav', Mage::helper('eav')->__('Can\'t create table: %s', $tableName)); }     查看底層錯誤是:UserError: DDL statements are not allowed in transactions   然後跟進commit函數   /**  * Check transaction level in case of DDL query  *  * @param string|Zend_Db_Select $sql  * @throws Zend_Db_Adapter_Exception  */ protected function _checkDdlTransaction($sql) {     if (is_string($sql) && $this->getTransactionLevel() > 0) {         $startSql = strtolower(substr(ltrim($sql), 0, 3));         if (in_array($startSql, $this->_ddlRoutines)) {             trigger_error(Varien_Db_Adapter_Interface::ERROR_DDL_MESSAGE, E_USER_ERROR);         }     } }   結論是Mysql不支持DDL Transaction。   因此在app/code/local/{CompanyName}/{ModuleName}/Setup/Helper.php裡重寫createEntityTable方法   {         ...           /**          * Remove transaction code due to issues with errors.          */         //$connection->beginTransaction();         try {              foreach ($tables as $tableName => $table) {                 $connection->createTable($table);             }             $connection->commit();        } catch (Exception $e) {            //$connection->rollBack();            throw Mage::exception('Mage_Eav', Mage::helper('eav')->__('Can\'t create table: %s', $tableName));        }     } }     然後問題解決。   Setup腳本剖析 讓我們一行一行的解釋。首先   $installer = $this;    每個安裝腳本都是從SetResource類開始執行的(就是我們上面創建的)。這意味著腳本中的$this引用是這個類實例化的引用。如果不是必須,core系統裡大部分安裝腳本都是把$this命名未installer,此處我們也是這樣。   接下來我們看到了兩個方法   $installer->startSetup();    //...    $installer->endSetup();    如果查看Mage_Core_Model_Resource_Setup類(在目錄app/code/core/Mage/Core/Resource/Setup.php),你可以看到如下的內容   public function startSetup()        {                 $this->_conn->multi_query("                             SET SQL_MODE='';                              SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;                              SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO'; ");                      return $this;        }         public function endSetup()        {            $this->_conn->multi_query("                  SET SQL_MODE=IFNULL(@OLD_SQL_MODE,'');                 SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS,0); ");                     return $this;        }    最後我們執行   $installer->run(...);    這個接受了一個包含創建數據庫的SQL。你可定義任意的查詢,通過分號隔開就好。同時,也要注意   $installer->getTable('weblog/blogpost')    getTable方法容許我們把Magento Model URI傳入,然後得到它的表名。如果不是必要,就用次方法執行。Mage_Core_Model_Resource_Setup類包含了很多有用的Helper方法。最有效的學習是研究Magento core的installer scripts。   Module升級 上面講述了如何初始化數據表,但是如何改變現有墨香的結構呢?Magento的Setup Resources支持一個簡單的版本策略,可以讓我們自動的執行腳本來升級我們的模塊。   一旦Magento執行一個安裝腳本後,它就不會再次執行另外一個安裝腳本。這個時候,我們應該創建一個升級腳本。升級腳本跟安裝腳本非常類似,只有有些關鍵處不一樣。   作為開始,我們在下列位置創建一個腳本,   XStarX/Weblog/sql/weblog_setup/mysql4-upgrade-0.1.0-0.2.0.php   echo 'Testing our upgrade script (mysql4-upgrade-0.1.0-0.2.0.php) and halting execution to avoid updating the system version number <br />';    die();    升級腳本和安裝腳本在同一個目錄,但是略有不同。首先,文件名要包含upgrade。其次,要有兩個版本號,並用“-”分隔。第一個是升級的源版本,第二個是升級的目標版本。   清除cache後,重新加載頁面,但這個時候腳本並沒有執行。我們需要更新config.xml裡面的版本信息來觸發升級   <modules>              <Alanstormdotcom_Weblog>                                    <version>0.2.0</version>                  </Alanstormdotcom_Weblog>    </modules>   寫入新的版本號後,如果清除緩存,加載網站,就可以看到輸出了。這個時候還有一個關鍵點需要注意,所以先不慌做這一步。我們在同樣的目錄創建另外一個文件   XStarX/Weblog/sql/weblog_setup/mysql4-upgrade-0.1.0-0.1.5.php   echo 'Testing our upgrade script (mysql4-upgrade-0.1.0-0.1.5.php) and NOT halting execution <br />';    這個時候再清除緩存,加載頁面,可以看到兩個信息。當Magento發現版本號信息變更後,他會執行所有可執行的腳本來更新模塊。盡管我們從沒有創建0.1.5版本,但是Magento會看到升級腳本,然後嘗試執行。腳本一般按照從低到高的順序執行。下面的數據會說明這個   mysql> select * from core_resource where code = 'weblog_setup'; +--------------+---------+    | code         | version | +--------------+---------+    | weblog_setup | 0.1.5   |  +--------------+---------+    1 row in set (0.00 sec)    我們看到數據表裡的版本是1.5。這是因為我們從1.0到1.5升級,但是沒有執行1.0到2.0的升級。好了,說明了這個關鍵問題後,我們言歸正傳。回到腳本上來,先修改升級腳本0.1.0-0.2.0   $installer = $this;    $installer->startSetup();    $installer->run("                ALTER TABLE `{$installer->getTable('weblog/blogpost')}`               CHANGE post post text not null; ");    $installer->endSetup();    die("You'll see why this is here in a second");    刷新頁面,但是什麼也不會發生。升級腳本為什麼沒有執行?   1.     weblog_setup resource是版本0.1.0   2.     我們要升級模塊到0.2.0   3.     Magento看到升級模塊,有兩個腳本要執行,0.1.0-0.1.5 和0.1.0-0.2.0   4.     Magento載入隊列,然後執行   5.     Magento執行0.1.0到0.1.5的腳本   6.     Weblog_setup resource現在是0.1.5了   7.     Magento執行0.1.0到0.2.0的腳本,執行停止   8.     在下一個頁面加載的時候,Magento看到了weblog_set在版本0.1.5,但是並沒有看到任何從0.1.5開始執行的腳本(之前的都是0.1.0開始)   正確的方式如下,重新命名文件   mysql4-upgrade-0.1.0-0.1.5.php #This goes from 0.1.0 to 0.1.5    mysql4-upgrade-0.1.5-0.2.0.php #This goes 0.1.5 to 0.2.0   Magento是能夠完成一次加載兩次升級的。你可以清除core_resource表信息,來完成最後的test   update core_resource set version = '0.1.0' where code = 'weblog_setup';    Magento是根據配置文件來執行升級的,所以在協同開發時要注意腳本的添加。        

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved