php - 直接从 Controller 运行 sql 查询

标签 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 方法使连接变得更容易(更安全?)。我可以将整个查询直接放入模块的 Controller 中吗?是这样的吗? :

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

最佳答案

是的,您可以按照您的建议进行。

我有类似以下内容:

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

编辑添加

您可以通过在 Controller 中定义方法并使用类似 $this->doAQuery(); 之类的内容调用它们来直接从 Controller 进行调用,不过,我非常喜欢将东西放在正确的位置以便于维护,所以我将概述执行此操作所需的步骤。

我假设您知道如何/可以阅读有关如何创建骨架模块的文档,但我最终可能会低调一点。提前致歉。

为了便于讨论,我将把我们的示例模块命名为 Zac_Example。所以我们假设我们在 app/code/local/Zac/Example 中有一个模块。任何其他路径都将假设我们从该目录开始。

首先,您需要定义一个模型(我想如果您愿意,您可以使用助手)和 Controller ,因此我们在 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 */
    }
}

现在,有了模型,我们就可以设置 Controller 了。我们将调用 Controller test,因此以下内容位于controllers/TestController.php中。我们将这些操作称为 foobar

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/foohttp://yourserver/example/test/bar 。如果我们将 Controller 文件命名为 IndexController.php ,那么它们将是 http://yourserver/example/index/foohttp://yourserver/example/index/bar

如果您只需要提供一项操作,则可以将 Controller 文件命名为 IndexController.php 并将 Controller 中的方法命名为 indexAction 并使用 URL http://yourserver/example/ .

我只是草率地拍摄,所以如果某处至少有一个脑洞或拼写错误,请不要感到惊讶。

关于php - 直接从 Controller 运行 sql 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9520629/

相关文章:

php - 如何在 Wordpress Gravity Forms 中使用 PHP 创建条目

php - 一个元素在多维数组中出现多少次

mysql - 在 Ruby 中查找相邻的多边形

php - MySQL从文本区域插入到多行

mysql - 链接表可以有两个互斥的列吗?

SQL:删除具有无效外键的记录

View 中的 SQL CTE 与存储过程中的临时表

php - 正则表达式从字符串中获取货币和金额

java - 如何设计易于扩展的游戏任务系统?

PHP UTF-8 不工作