2012-03-01 3 views
0

Я работаю над модулем magento admin, и в настоящее время я выполняю запрос базы данных небрежно, непосредственно загружая 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

В вашей строке «Тип заполнения» это выглядит так: '$ resultArray' должно быть пустым, потому что каждая запись удаляется. Это действительно работает? – clockworkgeek

+0

Это действительно работает. Я просто хочу переместить его из этого php-файла и в пурпурный. Я вижу от wierdos ответ, что я на правильном пути, но я до сих пор не понимаю, как я тогда называю это, когда он находится в контроллере. – Zac

ответ

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 */ 
    } 
} 

Теперь, имея модель, мы можем установить контроллер. Мы будем вызывать контроллер test, поэтому в контроллерах/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? 
    } 

Учитывая, что определенный набор фактов, что URL-адрес в вопросе будет http://yourserver/example/test/foo и http://yourserver/example/test/bar. Если бы мы назвали файл контроллера IndexController.php, они были бы http://yourserver/example/index/foo и http://yourserver/example/index/bar.

Если у вас есть только одно действие, которое нужно сделать доступным, вы можете назвать файл контроллера IndexController.php и метод в контроллере indexAction и использовать URL http://yourserver/example/.

Я стреляю из бедра, поэтому не удивляйтесь, если где-то есть хотя бы один мозг или опечатка.

+0

Спасибо, wierdo. . Но я до сих пор не понимаю, как я тогда вызываю запрос. Например, я в настоящее время просто загружаю его из ajax, url: theurl.php, но если я это сделаю с помощью вашего метода, то каков был бы путь к его выполнению? Будет ли это/doAQuery? – Zac

+0

«Правильный» способ сделать это - добавить такой код в модель или, возможно, помощник и вызвать его из контроллера. В контроллере вы бы назвали метод вроде doQueryAction в indexController.php вашего модуля. Если frontName вашего модуля был установлен как 'theurl', вы получите доступ к нему, используя' http: // yoursite/theurl/index/doQueryAction' – wierdo

+0

Огромное спасибо за это, я очень ценю это. я теряюсь в этих пурпурных лесах, и это должно быть полезным ресурсом для меня. – Zac

Смежные вопросы