直接从控制器运行SQL查询

时间:2012-03-01 17:05:47

标签: php mysql sql magento

我正在研究一个magento管理模块,目前我正在以一种草率的方式运行数据库查询,直接加载一个php文件并连接模块外的php文件:

<?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'
...
}

1 个答案:

答案 0 :(得分: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中有一个模块。任何进一步的路径都会假设我们从该目录开始。

首先,你需要定义一个模型(我想你可以使用一个帮助器,如果你愿意)和控制器,所以我们在etc / 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>
...

现在我们在Model / 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 ,因此以下内容将在controllers / TestController.php中进行。这些操作,我们将调用 foo bar

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 { {1}}。

我是从臀部拍摄的,所以如果某处至少有一个braino或拼写错误,请不要感到惊讶。