ultimo returns obtener mysqli_insert_id mysql_insert_id last_insert_id last insertar insertado insert_id formulario desde datos con php mysqli

returns - PHP/MySQLi en Windows: inserta en MySQL la tabla innoDB aumenta la columna AUTO_INCREMENT en 2



mysqli_insert_id returns 0 (1)

De acuerdo. Finalmente lo tengo. El problema es: redirijo todas las solicitudes a mi index.php y hago todo el resto con PHP. Probé el comportamiento de algunas clases con salidas simples. Una de las pruebas conduce al problema anterior. Revisé el registro de acceso de Apache y noté repetidas solicitudes de favicon.ico. Estas solicitudes, producidas automáticamente por los principales navegadores (ver también ¿Cómo prevenir las solicitudes de favicon.ico? ), También llegaron a index.php y parecen redirigir al navegador? normalmente todo esto se maneja en mi marco de aplicación, pero lo desactivé mientras lo probé.

Cuando hago un simple inserto a través de la API de PHP mysqli con instrucciones preparadas en Windows dentro de un proceso de PHP, la columna AUTO_INCREMENT definida se incrementa en 2 en lugar de 1:

INSERT INTO `table` (`name`) VALUES (?)

Aumenta en 1 cuando se realizan inserciones múltiples (una por una en transacciones separadas) dentro de un proceso de PHP.

Siempre aumenta en 1 cuando uso la misma consulta SQL a través de phpmyadmin.

No hay otras INSERT o UPDATE antes o después del INSERT mencionado. Solo un SHOW y algunas declaraciones SELECT antes.

No puedo encontrar la causa de este problema. ¿Cuáles pueden ser las causas de tal comportamiento?

Aquí las partes principales del código:

<?php class DB { private function __construct($host, $username, $password, $schema, $port, $socket) { if(is_null(self::$DB)) { self::$DB = new /MySQLi((string) $host, (string) $username, (string) $password, (string) $schema, (int) $port, (string) $socket); self::$DB->set_charset(''utf8''); } } // [...] public function __destruct() { if(!is_null(self::$DB)) self::$DB->close(); } // [...] public static function connect($host = '''', $username = '''', $password = '''', $schema = '''', $port = 0, $socket = '''') { if(is_null(self::$instance)) { $MD = new /MySQLi_driver(); $MD->report_mode = MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT; // [...] self::$instance = new self($host, $username, $password, $schema, $port, $socket); } return self::$instance; } // [...] public static function __callStatic($name, $args) { self::connect(); switch(true) { case in_array($name, array(''insert'', ''select'', ''update'', ''delete'', ''show'', ''describe'', ''explain'')): $query = isset($args[0]) ? (string) $args[0] : ''''; $vals = isset($args[1]) ? $args[1] : array(); $select = isset($args[2]) ? trim((string) $args[2]) : ''array''; $empty = isset($args[3]) ? $args[3] : array(); $types = isset($args[4]) ? trim((string) $args[4]) : ''''; return self::dml(in_array($name, array(''show'', ''describe'', ''explain'')) ? ''select'' : $name, $query, $vals, $select, $empty, $types); break; } //[...] } // [...] public static function dml($type, $query, $vals = array(), $select = ''array'', $empty = array(), $types = '''') { // [...] if(!empty($vals) || mb_strpos($query,''?'') !== false) { if(!$stmt = self::$DB->prepare($query)) throw new DBException(''Failed to prepare statement ''.htmlspecialchars($query).PHP_EOL.self::$DB->error.'' (''.self::$DB->sqlstate.'').''); $args = array(); if(empty($types)) { foreach($vals as &$val) { $t = gettype($val); if($t == ''string'' || $t == ''NULL'') $types.= ''s''; elseif($t == ''integer'' || $t == ''boolean'') $types.= ''i''; elseif($t == ''double'' || $t == ''float'') $types.= ''d''; else throw new DBException(''Its not possible to automatically assign a value of type ''.$t.''. Please specify the corresponding types manually.''); $args[] = $val; } } else { foreach($vals as &$val) $args[] = $val; } array_unshift($args, $types); $RC = new /ReflectionClass($stmt); $RM = $RC->getMethod(''bind_param''); if(!$RM->invokeArgs($stmt, $args)) throw new DBException(''Failed to bind params.''.PHP_EOL.self::$DB->error.'' (''.self::$DB->sqlstate.'').''); if(!$stmt->execute()) throw new DBException(''Failed to execute Statement.''.PHP_EOL.self::$DB->error.'' (''.self::$DB->sqlstate.'').''); if($type == ''select'') { // [...] } else { $return = $type == ''insert'' && self::$DB->insert_id > 0 ? self::$DB->insert_id : self::$DB->affected_rows; $stmt->close(); return $return; } } else { // [...] } } } ?>

Y:

echo DB::insert("INSERT INTO `table` (`name`) VALUES (?)", ["test"]);

El Query-Log muestra 2 inserciones. Esto causa el incremento adicional. Pero cuando pongo un eco en el método DB :: dml () correspondiente, solo se emite una vez, por lo que se lo llama una vez. El mysql-query-log:

151026 12:54:49 3 Connect XXX@localhost on XXX 3 Query SET NAMES utf8 3 Query SELECT DATABASE() AS `schema` 3 Query SHOW GRANTS FOR CURRENT_USER 3 Prepare INSERT INTO `table` (`name`) VALUES (?) 3 Execute INSERT INTO `table` (`name`) VALUES (''testinsert22'') 3 Close stmt 3 Quit 4 Connect XXX@localhost on XXX 4 Query SET NAMES utf8 4 Query SELECT DATABASE() AS `schema` 4 Query SHOW GRANTS FOR CURRENT_USER 4 Prepare INSERT INTO `table` (`name`) VALUES (?) 4 Execute INSERT INTO `table` (`name`) VALUES (''testinsert22'') 4 Close stmt 4 Quit