【问题标题】:How do I view a SQL Statement in Phalconphp?如何在 Phalconphp 中查看 SQL 语句?
【发布时间】:2014-07-22 11:35:10
【问题描述】:

我想查看下面即将执行的SQL语句:

<?php

 //Deleting existing robot
 $success = $connection->delete(
     "robots",
     "id = 101"
 );

 //Next SQL sentence is generated
 DELETE FROM `robots` WHERE `id` = 101

如何添加某种侦听器或只是简单的 var_dump 将由 $connection->delete 生成的选择查询

谢谢

【问题讨论】:

    标签: php database phalcon


    【解决方案1】:

    我确定的方式是使用记录器类和事件系统:Phalcon Events Manager

    您创建一个扩展记录器适配器的类

    <?php
    
    namespace PhalconX\Logger\Adapter;
    
    /**
     * Basic Array based Logging for debugging Phalcon Operations
     * @package PhalconX\Logger\Adapter
     */
    class Basic extends \Phalcon\Logger\Adapter
    {
        private $data = array();
    
        /**
         * Add a statement to the log
         * @param string $statement
         * @param null $type
         * @param array $params
         * @return $this|\Phalcon\Logger\Adapter
         */
        public function log($statement, $type=null, array $params=null)
        {
            $this->data[] = array('sql'=>$statement, 'type'=>$type, 'params'=>$params); // array('sql'=>$statement, 'type'=>$type);
            return $this;
        }
    
        /**
         * return the log
         * @return array
         */
        public function getLog(){
            return $this->data;
        }
    
        /**
         * Required function for the interface, unused
         * @param $message
         * @param $type
         * @param $time
         * @param $context
         */
        public function logInternal($message, $type, $time, $context){
    
        }
    
        /**
         * Required function for the interface, unused
         */
        public function getFormatter(){
    
        }
    
        /**
         * Required function for the interface, unused
         */
        public function close(){
    
        }
    }
    

    然后将其附加到您的数据库中,并按类型调查事件

    $eventsManager = new \Phalcon\Events\Manager();
    $logger = new \PhalconX\Logger\Adapter\Basic();
    $profiler = $phalconDi->getProfiler();
    //Listen all the database events
    
    /** @var $event \Phalcon\Events\Event */
    /** @var $phalconConnection \Phalcon\Db\Adapter\Pdo\Mysql */
    
    $eventsManager->attach('db', function($event, $phalconConnection) use ($logger, $profiler) {
        if ($event->getType() == 'beforeQuery') {
            $profiler->startProfile($phalconConnection->getSQLStatement());
            $logger->log($phalconConnection->getSQLStatement(), \Phalcon\Logger::INFO, $phalconConnection->getSQLVariables());
        }
        if ($event->getType() == 'afterQuery') {
            $profiler->stopProfile();
        }
    });
    

    这假设您的依赖注入器中有一个“db”键。

    我的记录器只是将查询存储在一个数组中,以便我可以在页面底部输出它们。

    【讨论】:

    • 谢谢@CodeMonkey 我会试试的。我已经有一个用于错误事件的记录器。我会试试你的。
    【解决方案2】:

    我的技巧是从那些准备好的 SQL 语句中分解出最接近真实的 SQL 语句:

    function statement2sql($connection) {
        $stmt = $connection->getSQLStatement();
        foreach ( $connection->getSQLVariables() as $k => $v ) {
            // replaces :p1, .. :p11 .. and defined binds with binded values
            $stmt = preg_replace('/:' . $k . '([^A-Za-z0-9])/', '\'' . $v . '\'$1', $stmt);
        }
        return $stmt;
    }
    

    定义为方法或函数,您可以将其结果推送到分析器,如接受的答案:

    $eventsManager->attach('db:beforeQuery', function($event, $connection) {
        $profiler->startProfile(statement2sql($connection));
    }
    
    $eventsManager->attach('db:afterQuery', function($event, $connection) {
        $profiler->stopProfile();
    }
    

    或以其他方式存储 - 使用记录器或其他调试类。

    【讨论】:

      【解决方案3】:

      我很幸运地将我的 SQL 执行调用包装在 try/catch 中,然后打印异常。 MySQL 返回的任何错误消息都在异常消息中,其中将包含原始查询。

      function get_item_by_id ($db_connection, $item_id) {
          try {
              $stmt = 'SELECT * FROM inventory WHERE id=:id';
              $prepared_stmt = $db_connection->prepare ($stmt);
      
              $result = $db_connection->executePrepared ($prepared_stmt,
                  array (
                      "id" => $item_id
                  ),
                  array (
                      "id" => Column::BIND_PARAM_INT
                  )
              );
      
              $result->setFetchMode (Phalcon\Db::FETCH_OBJ);
              $item_arr = $result->fetchAll ();
              return $item_arr;
          }
          catch (Exception $e) {
              print_r ($e->getMessage());
          }
      }
      

      【讨论】:

        【解决方案4】:

        另一种选择,我个人的偏好,是从数据库的角度来看情况。大多数 SQL 数据库允许您为某些事件设置触发器(在您的情况下为 DELETE),并使用传入请求的全文生成日志条目。

        参考:https://stackoverflow.com/a/10671410/1504367

        【讨论】:

          猜你喜欢
          • 2012-06-17
          • 1970-01-01
          • 2014-01-22
          • 2017-05-08
          • 2021-10-20
          • 2010-09-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多