Mysql insert_id всегда возвращает ноль

Я работаю над редактированием старого проекта с php 5.3 на php 7+. Неприятная работа, но мне приходится делать это с минимальными изменениями кода.

Я столкнулся со следующей проблемой. Insert_id всегда возвращает 0.

Я читал, что это может быть связано с тем, что у меня нет ключа auto_increment в таблице или последний запрос не был оператором INSERT или UPDATE, но моя проблема не связана с этим. Запрос успешно вводит информацию в базу данных.

Это код:

class DBTable{

 function connection(){
    $mysqli = new mysqli('localhost', 'username', 'pass', 'db');

    if (mysqli_connect_errno()) {
        printf("Connect failed: %s\n", mysqli_connect_error());
        exit();
    }

    if (!$mysqli->set_charset("utf8")) {
        printf("Error loading character set utf8: %s\n", $mysqli->error);
        exit();
    }
    return $mysqli;
  }

  function addrow_id($row){
    $query="some INSERT query";
    $res = $this->connection()->query($query);
    if ($res) $response = $this->connection()->insert_id; //always returns zero    
    return $response;
  }
}

Я прекрасно понимаю, что это нехороший PHP, но я не могу запустить проект с нового и моя задача просто сделать это для работы с PHP 7+

0
0
70
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

$this->connection() каждый раз возвращает новое соединение. Идентификаторы вставки относятся к конкретному соединению, иначе вы столкнетесь с помехами от параллельных клиентов. Вам необходимо повторно использовать объект подключения:

$query="some INSERT query";
$con = $this->connection();
$res = $con->query($query);
if ($res) $response = $con->insert_id;

Желательно, чтобы вы выполняли $this->con = $this->connection() один раз в __construct и повторно использовали одно и то же соединение для всего объекта; или, лучше, вы вводите одно соединение, которое вы установили глобально, как зависимость при создании экземпляра вашего объекта:

$con = new mysqli(...);
$db = new DBTable($con);

В противном случае у вас будет много накладных расходов на постоянное установление и разрыв соединений. Не говоря уже о тестируемости и так далее с жестко заданным соединением.

@ stefo91, Просто чтобы добавить еще один пункт, лучше использовать Шаблон синглтона для реализации метода connection().

Rajdeep Paul 10.08.2018 14:50

Нет, на самом деле лучше переключиться на внедрение зависимости, как редактировалось в.

deceze 10.08.2018 14:51

Я напрямую использовал код из вашего сообщения, хотя ответ выше тоже отличный.

<?php
class DBTable{
  private $dbcon;

  function __construct() {  //this constructor is called when you do $var = new DBTable() to instantiate your object

    //create the connection and assign it to the dbcon var
    $this->dbcon = new mysqli('localhost', 'username', 'password', 'db');

    //throw connection error and die
    if ($this->dbcon->connect_error) {
        printf("Connect failed: %s\n", $this->$dbcon->connect_error);
        exit();
    }

    //throw mysql error and die
    if (!$this->dbcon->set_charset("utf8")) {
        printf("Error loading character set utf8: %s\n", $this->$dbcon->error);
        exit();
    }
  }

  //I add a row and return an ID
  function addrow_id(){
    //create your query string
    $query="INSERT INTO TEST() VALUES()";
    //run the query
    $res = $this->dbcon->query($query);
    if ($res){  //if this value evaluates to zero, we want to throw an error
      $response = $this->dbcon->insert_id;
    } else {  //throw an error, because the query came back with a negative val
      $error = 'When adding a row, I got no results or a value that php interpolates as negative';
      throw new Exception($error);
    }
    //return the new id
    return $response;
  }
}
//instantiate your object/class
$dbTable = new DBTable();
//dump the outcome of your adding a row
var_dump($dbTable->addrow_id());
?>

Другие вопросы по теме