2012-03-01 50 views
0

我正在研究一個magento管理模塊,目前我正在通過直接加載一個php文件並在模塊外部連接一個php文件來以馬虎的方式運行數據庫查詢:直接從控制器運行SQL查詢

<?php 
header("Content-type: text/xml"); 
$host   = "localhost"; 
$user   = "root"; 
$pw    = "foo"; 
$database  = "db"; 
$link   = mysql_connect($host,$user,$pw) or die ("Could not connect."); 
$db_selected = mysql_select_db($database, $link); if (!$db_selected) { 
    die ('Can\'t use ' . $database . ' : ' . mysql_error()); } 


// connect to database 
$link = mysql_connect($host . ":" . $port,$user,$pw) or die ("Could not connect."); 

// Select DB 
$db_selected = mysql_select_db($database, $link); if (!$db_selected) { 
    die ('Can\'t use ' . $database . ' : ' . mysql_error()); } 

// Database query 
$query = ("SELECT cpsl.parent_id AS 'foo' 
    , cpe.type_id AS 'bar' 
    , LEFT(cpe.sku, 10) AS 'color' 
    .... 
GROUP BY 1,2,3,4,5,6,7,8,9 
ORDER BY 1,2,3,4,5,6,7,8,9 
;"); 

// Execute query 
$result = mysql_query($query, $link) or die("Could not complete database query"); 

// Populate array 
while(($resultArray[] = mysql_fetch_assoc($result)) || array_pop($resultArray)); 

    $doc = new DOMDocument(); 
    $doc->formatOutput = true; 

    $r = $doc->createElement("DATA"); 
    $doc->appendChild($r); 

    foreach($resultArray as $product) 
    { 
    $b = $doc->createElement("ITEM"); 

    // MagentoID 
    $magento_id = $doc->createElement("MAGENTO_ID"); 
    $magento_id->appendChild(
    $doc->createTextNode($product['MagentoID']) 
); 
    $b->appendChild($magento_id); 
.... 

} 

// Save XML 
    echo $doc->saveXML(); 

// Close connection 
mysql_close($link); 

?> 

有人可以請解釋一個更好的方式來寫入模塊?我知道我可以使用magentos方法使連接更容易(更安全?)。我可以將整個查詢直接放在模塊的控制器中嗎?像這樣? :

public function queryAction() 
    { 
$readConnection = $resource->getConnection('core_read'); 
$query = ("SELECT cpsl.parent_id AS 'foo' 
... 
} 
+0

在你的「Populate array」行中,它看起來像'$ resultArray'應該是空的,因爲每個記錄都被彈出。這實際上工作嗎? – clockworkgeek 2012-03-01 20:05:42

+0

它確實有效。我只是想將它從這個php文件移動到magento中。我從維爾多斯的回答中看到,我正處在正確的軌道上,但是我仍然不明白我是如何在控制器中調用它的。 – Zac 2012-03-02 01:02:36

回答

3

是的,你可以做你的建議。

我有類似如下:

class Foo { 
    protected $db; 

    public function _construct() { 
     /* Change core_write to core_read if you're just reading */ 
     $this->db = Mage::getSingleton('core/resource')->getConnection('core_write'); 
    } 

    private function doAQuery() { 
     $sql = "SELECT * FROM foobar f;"; 
     $data = $this->db->fetchAll($sql); 
     /* do something with the data here */ 
    } 

    private function doAQueryADifferentWay() { 
     $sql = $this->db->select(); 
     $sql->from(array('f' => 'foobar')); 
     $data = $this->db->fetchAll($sql); 
     /* do something with the data */ 
    } 
} 

編輯追加

您可以通過定義方法在控制器和喜歡的東西$this->doAQuery();稱他們直接撥打電話從控制器不過,我很樂意將事情放在正確的位置,以便於維護,所以我將概述實現這一點所需的步驟。

我打算假設你知道如何/可以閱讀有關如何創建骨架模塊的文檔,但我最終可能會討論一下。提前道歉。

爲了說明方便,我打算打電話給我們的示例模塊Zac_Example。所以我們假裝我們在app/code/local/Zac/Example中有一個模塊。任何進一步的路徑將假設我們在該目錄中開始。

首先,你需要定義一個模型(我想如果你願意,你可以使用一個輔助)和控制器,因此我們定義那些等/ config.xml中

... 
    <frontend> 
    <routers> 
     <zac_example> 
     <use>standard</use> 
     <args> 
      <module>Zac_Example</module> 
      <!-- Mind the capital N, it gets me every time --> 
      <frontName>example</frontName> 
     </args> 
     </zac_example> 
    </routers> 
    </frontend> 
    <global> 
    <models> 
     <zac_example> 
     <class>Zac_Example_Model</class> 
     </zac_example> 
    </models> 
    </global> 
... 

現在我們在定義我們的模型型號/ Query.php,這是從上面Foo,但使用Magento的命名約定:

class Zac_Example_Model_Query extends Mage_Core_Model_Abstract { 
    protected $db; 

    /* you don't have to do this, as you can get the singleton later if you prefer */ 
    public function __construct() { 
     $this->db = Mage::getSingleton('core/resource')->getConnection('core_write'); 
    } 

    public function doAQuery() { 
     /* If you chose not to do this with the constructor: 
     * $db = Mage::getSingleton('core/resource')->getConnection('core_write'); 
     */ 

     $sql = "SELECT * FROM foobar f;"; 
     /* or $db->fetchAll($sql); */ 
     $this->db-fetchAll($sql); 
     /* do something with the data here */ 
     return $response 
    } 

    public function doAQueryADifferentWay($somerequestdata) { 
     $sql = $this->db->select(); 
     $sql->from(array('f' => 'foobar')); 
     $sql->where('f.somedata', array('eq' => $somerequestdata)); 

     $data = $this->db->fetchAll($sql); 
     /* do something with the data */ 
    } 
} 

現在,有模型,我們可以建立一個控制器。我們將調用控制器測試,因此以下控制器/ TestController.php。這些行爲,我們會撥打foo

class Zac_Example_TestController extends Mage_Core_Controller_Front_Action { 

    public function fooAction() { 
     $model = Mage::getModel('zac_example/query'); 
     $result = $model->doAQuery(); 
     $this->getResponse()->setBody(Zend_Json::encode($result)); 
     $this->getResponse()->sendResponse(); 
     exit; // We're done, right? 
    } 

    /* This assumes the request has a post variable called 'whatever' */ 
    public function barAction() { 
     $model = Mage::getModel('zac_example/query'); 
     $param = $this->getRequest()->getParam('whatever'); 
     $result = $model->doAQueryADifferentWay($param); 
     $this->getResponse()->setBody(Zend_Json::encode($result)); 
     $this->getResponse()->sendResponse(); 
     exit; // We're done, right? 
    } 

鑑於事實的特定集合,相關網址是http://yourserver/example/test/foohttp://yourserver/example/test/bar。如果我們已經命名控制器文件IndexController.php,它們將是http://yourserver/example/index/foohttp://yourserver/example/index/bar

如果你只有一個動作你需要做用,你能說出控制器文件IndexController.php和控制器的indexAction的方法和使用URL http://yourserver/example/

我是從臀部開始拍攝的,所以如果至少有一個布賴諾或錯別字,請不要感到驚訝。

+0

謝謝維爾多。但我仍然沒有真正知道我是如何調用查詢的。例如,我目前只是從ajax,url:theurl.php加載它,但如果我用你的方法來做,那麼執行這個的路徑是什麼?會是/ doAQuery? – Zac 2012-03-02 00:59:48

+0

這樣做的「正確」方法是將這樣的代碼放入模型或可能的幫助器中,並從控制器調用它。在控制器中,您可以在模塊的IndexController.php中爲doQueryAction命名一個方法。如果你的模塊的frontName被設置爲'theurl',你可以使用'http:// yoursite/theurl/index/doQueryAction'來訪問它。 – wierdo 2012-03-02 05:08:47

+0

非常感謝,我真的很感激它。我迷失在這些magento樹林中,這對我來說應該是一個有用的資源。 – Zac 2012-03-02 14:03:46