Расширяйте mysqli с ведением журнала запросов, но не теряйте insert_id - PullRequest
1 голос
/ 01 июня 2011

У меня есть класс, который расширяет mysqli, чтобы запросы регистрировались.

К сожалению, я не могу понять, как не потерять свойство insert_id.

Я бы хотел это сделать

$sql = sprintf("
    INSERT INTO picture
    SET     nm_picture = '%s'

",
    Db::instance()->escape_string($_POST['nm_picture'])
);

$result = Db::instance()->queri($sql);
$id_inserted_pic = Db::instance()->insert_id;

, но $id_inserted_pic - это идентификатор Activity_log.

Я надеялся, что смогу переопределить $this->insert_id, но, увы, нет.

Любая помощь приветствуется.

Мой код в том виде, в котором он есть, с небольшим удалением для простоты: (обратите внимание, что некоторые из них были написаны другими людьми и / или могут быть не идеальными)

class Db extends \mysqli
{
    private static $instance;
    protected $_database;

    public $insert_id; /* doesn't error but doesn't work either */

    private function __construct(array $config)
    {
        if (
            is_array($config)
            && isset($config['host'])
            && isset($config['username'])
            && isset($config['password'])
            && isset($config['database'])
        )
        {
            $this->_database = $config['database'];
            parent::__construct(
                $config['host']
                , $config['username']
                , $config['password']
                , $config['database']
                , $config['port']
                , $config['socket']
            );
        }
    }

    /**
     * Singleton Pattern
     * @param array $config
     */
    public static function instance(array $config = null)
    {
        if (!isset(self::$instance)) {
                $c = __CLASS__;
                self::$instance = new $c($config);
            }
            return self::$instance;
    }

    /**
     * Save the passed string into the activity_log table
     *
     * @param string $query
     * @param bool $force default false
     */
    public function activity_log($query, $force = false)
    {
        $sql = sprintf('
            INSERT INTO sw_activity_log
            SET     tx_activity_log = "%s"
        ',
            $query
        );
        $result = $this->query($sql);

        if ($result !== false)
        {
            return $result;
        }
        else
        {
            //...
        }
    }

    /**
     * Run a query and activity_log() it if matched and not told otherwise
     *
     * @param string $query
     * @param unknown_type $resultmode
     * @param bool|null $fl_log default null
     *
     * @return mysqli_result;
     */
    public function queri($query, $resultmode = null, $fl_log = null)
    {
        $result = parent::query($query, $resultmode);
        $tmp_insert_id = $this->insert_id;

        if ($result !== false)
        {
            if ($fl_log || ($fl_log !== false && preg_match('~^(\s+)?(REPLACE|INSERT|DELETE|UPDATE)~ims', $query) > 0))
            {
                self::activity_log($query);
            }
            $this->insert_id = $tmp_insert_id;
            return $result;
        }
        else
        {
            // ...
        }
    }
}

Ответы [ 2 ]

2 голосов
/ 01 июня 2011

Я бы посоветовал вашему методу queri сохранить идентификатор вставки где-нибудь в переменной класса. Имейте функцию регистрации, устанавливающую переменную флага, говорящую методу queri, чтобы НЕ сохранять идентификатор вставки, когда выполняется запрос журнала. Таким образом, ваш идентификатор вставки будет сохранен после последней вставки без регистрации.

1 голос
/ 01 июня 2011

У вас есть две возможности:

  • Не используйте автоинкремент в журнале активности.Там действительно нет необходимости в этом.В этой таблице даже нет необходимости в первичном ключе, потому что, с чем вы собираетесь связать его?
  • Вставьте журнал активности перед фактическим запросом, оберните все в транзакции и выполните откат при запросеневерно.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...