【问题标题】:Fatal error when trying to start a transaction in PHP 7.3 with mysqli尝试使用 mysqli 在 PHP 7.3 中启动事务时出现致命错误
【发布时间】:2021-05-08 19:54:29
【问题描述】:

我要执行以下交易:

START TRANSACTION;
INSERT INTO
   `orders` (producten, totaalprijs, account_id) 
VALUES
   (
      "{\"601bced33b191\":{\"naam\":\"Sierkussens binnen\", \"alias\":\"sierkussens - binnen\", \"url\":\"https:\\ / \\ / printzelf.nl\\ / new\\ / product\\ / sierkussens - binnen ? term = sierkussen\", \"afbeelding\":\"cms\\ / images\\ / producten\\ / textiel_producten\\ / Sierkussens\\ / sierkussen_1.jpg\", \"aantal\":\"1\", \"hoogte\":null, \"breedte\":null, \"uploaden\":\"1\", \"specificaties\":{\"Formaat\":{\"waarde\":\"40 x 40 cm\"}, \"Materiaal\":{\"waarde\":\"Dekostof\"}, \"Samenstelling\":{\"waarde\":\"Hoes\"}, \"Kleur garen\":{\"waarde\":\"Zwart\"}, \"Kleur rits\":{\"waarde\":\"Zwart\"}, \"Ontwerp\":{\"waarde\":\"PRO ontwerpcontrole\"}}, \"prijs\":\"13.99\", \"totaalprijs\":13.99, \"canvas\":\"{\\n \\\"customer_id\\\": \\\"33\\\", \\n \\\"order_id\\\": \\\"123\\\", \\n \\\"quantity\\\": \\\"1\\\", \\n \\\"rulers\\\": null, \\n \\\"canvas_size\\\": \\\"0x0\\\", \\n \\\"bleed\\\": null, \\n \\\"safety_margin\\\": null, \\n \\\"dpi\\\": null, \\n \\\"multiple_layouts\\\": null, \\n \\\"procheck\\\": \\\"y\\\", \\n \\\"multiple_pages\\\": \\\"1\\\", \\n \\\"product_name\\\": \\\"Sierkussens binnen\\\", \\n \\\"thumbnail\\\": \\\"cms\\\\\\ / images\\\\\\ / producten\\\\\\ / textiel_producten\\\\\\ / Sierkussens\\\\\\ / sierkussen_1.jpg\\\"\\n}\"}}", "19", "33" 
   )
;
UPDATE
   `orders` 
SET
   order_id = CONCAT(account_id, ".", id) 
WHERE
   id = LAST_INSERT_ID();
COMMIT;

所以我尝试像这样开始交易:

$conn->autocommit(FALSE);
$conn->query('
INSERT INTO orders
(
    producten,
    totaalprijs,
    account_id
)
VALUES
(
    "'.$conn->real_escape_string($encodedproductenarray).'",
    "'.$conn->real_escape_string(subtractbtw($subtotaalcheckoutafr)).'",
    "'.$conn->real_escape_string($_SESSION['user']['id']).'"
)');
$conn->query('
UPDATE orders SET order_id = CONCAT(account_id, ".", id)
WHERE id = LAST_INSERT_ID()');
$conn->commit();

但这给了我以下错误:

PHP Fatal error:  Uncaught Error: Call to undefined method Connection::autocommit()

我做错了吗?

$conn 是我的连接类,包含以下内容:

session_start();
class Connection {
    // Configure Database Vars
    private $host     = 'localhost';
    private $username = 'sdgsdg';
    private $password = 'sdgsdg!';
    private $db_name  = 'dsgsd';
    public $db;

    function __construct() {
        // Create connection
        $db = new mysqli($this->host, $this->username, $this->password, $this->db_name);
        // Check connection
        if ($db->connect_errno > 0) {
            die('Unable to connect to the database: '.$db->connect_error);
        }
        $this->db = $db;
    }

    public function query($query) {
        $db = $this->db;
        $this->db->query('SET NAMES utf8');
        if (!$result = $this->db->query($query)) {
            die('There was an error running the query ['.$db->error.']');
        } else {
            return $result;
        }
    }

    public function multi_query($query) {
        $db = $this->db;
        if (!$result = $this->db->multi_query($query)) {
            die('There was an error running the multi query ['.$db->error.']');
        } else {
            return $result;
        }
    }

    public function real_escape_string($value) {
        return $this->db->real_escape_string($value);
    }

    public function inserted_id() {
        return $this->db->insert_id;
    }
}

$conn = new Connection();

我也尝试在这样的查询中添加整个事务:

$insertorder = '
START TRANSACTION;
    INSERT INTO orders
    (
        producten,
        totaalprijs,
        account_id
    )
    VALUES
    (
        "'.$conn->real_escape_string($encodedproductenarray).'",
        "'.$conn->real_escape_string(subtractbtw($subtotaalcheckoutafr)).'",
        "'.$conn->real_escape_string($_SESSION['user']['id']).'"
    );
    UPDATE orders SET order_id = CONCAT(account_id, ".", id)
    WHERE id = LAST_INSERT_ID();
COMMIT;';
$insertordercon = $conn->query($insertorder);

但这给了我一个语法错误。

【问题讨论】:

  • 如果你使用自定义连接类,当然不能只调用mysqli的方法就可以了。您需要实现一个方法,告诉它在 $this->db 上调用 autocommit
  • $conn->db->autocommit(); 记住函数在 mysqli 对象上,而不是你的包装类。或者您需要在您的类中创建一个调用 mysqli 方法的等效函数(尽管这确实相对毫无意义)
  • 您还应该阅读将 prepared statements 与占位符一起使用,而不是手动转义值并将它们直接放入查询中。
  • 您还尝试使用 query()-method 而不是 multi_query()-method 执行包含多个查询的字符串。
  • @ADyson 谢谢你,我是这样工作的。

标签: php sql mysqli transactions


【解决方案1】:

您的班级中有一个mysqli 对象。这具有您要使用的所有方法。做这样的事情:

$conn->db->autocommit(FALSE);
$conn->query('
INSERT INTO orders
(
    producten,
    totaalprijs,
    account_id
)
VALUES
(
    "'.$conn->real_escape_string($encodedproductenarray).'",
    "'.$conn->real_escape_string(subtractbtw($subtotaalcheckoutafr)).'",
    "'.$conn->real_escape_string($_SESSION['user']['id']).'"
)');
$conn->query('
UPDATE orders SET order_id = CONCAT(account_id, ".", id)
WHERE id = LAST_INSERT_ID()');
$conn->db->commit();

或者,您可以在自己的类中实现这些方法。您已经为queryreal_escape_string 这样做了,所以应该很容易。只需插入类:

public function autocommit($b) {
    $this->db->autocommit($b);
}

public function commit() {
   $this->db->commit();
}

...或类似的。

【讨论】:

    猜你喜欢
    • 2016-06-14
    • 1970-01-01
    • 2020-02-28
    • 1970-01-01
    • 2012-11-01
    • 2015-09-13
    • 2014-09-07
    • 2014-03-28
    • 1970-01-01
    相关资源
    最近更新 更多