使用查询日志记录扩展 mysqli,但不要丢失 insert_id

发布于 2024-11-11 15:50:42 字数 3041 浏览 5 评论 0原文

我有一个扩展 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 ID。

我希望我能够覆盖 $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
        {
            // ...
        }
    }
}

I have a class that extends mysqli so that queries are logged.

Unfortunately, I can't figure out how not to lose the insert_id property.

I'd like to be able to do this

$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;

but $id_inserted_pic is the activity_log ID.

I hoped I'd be able to override $this->insert_id but alas no.

Any help appreciated.

My code as it stands with a few bit removed for simplicity:
(please note that some of it was written by other people and/or may not be ideal)

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
        {
            // ...
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

带刺的爱情 2024-11-18 15:50:42

我建议让您的 queri 方法将插入 ID 保存在类变量中的某个位置。让日志记录函数设置一个标志变量,告诉 queri 方法在执行日志查询时不存储插入 ID。这样您就可以保留上次非日志插入的插入 ID。

I'd suggest having your queri method save the insert ID somewhere in a class variable. Have the logging function set a flag variable telling the queri method to NOT store the insert ID when a log query is performed. That way you'd have your insert ID preserved from the last non-log insertion.

笑红尘 2024-11-18 15:50:42

您有两种可能性:

  • 不要在活动日志中使用自动增量。确实没有必要。该表中甚至不需要主键,因为您要将它与什么链接?
  • 在实际查询之前插入活动日志,将所有内容包装在事务中,并在查询无效时回滚。

You have two possibilities:

  • Don't use an auto-increment in your activity log. There really is no need for it. There isn't even a need for a primary key in that table, cause what are you going to link it with?
  • Insert the activity log before the actual query, wrap everything in a transaction and rollback when the query is invalid.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文