Como obter a última ID de linha inserida do banco de dados WordPress?

94

Meu plugin do WordPress tem uma tabela com um campo de chave primária AUTO_INCREMENT chamado ID. Quando uma nova linha é inserida na tabela, gostaria de obter o valor de ID da inserção.

O recurso é usar AJAX para postar dados no servidor para inserir no banco de dados. O novo ID de linha é retornado na resposta AJAX para atualizar o status do cliente. É possível que vários clientes estejam postando dados no servidor ao mesmo tempo. Portanto, tenho que garantir que cada solicitação AJAX obtenha a nova ID de linha EXATA em resposta.

No PHP, existe um método chamado mysql_insert_id para este recurso. Mas, ele é válido para condição de corrida apenas se o argumento for link_identifier da última operação. Minha operação com o banco de dados está em $ wpdb. Como extrair o link_identifier de $ wpdb para garantir que mysql_insert_id funcione? Existe alguma outra maneira de obter o id da última linha inserida de $ wpdb?

Obrigado.

Morgan Cheng
fonte
O link | recurso está armazenado em $wpdb->dbh, mas está definido como protected $dbh;... mas você não pode acessá-lo diretamente, portanto, use a resposta abaixo :)
jave.web

Respostas:

191

Logo após o $wpdb->insert()que faz a inserção, faça o seguinte:

$lastid = $wpdb->insert_id;

Mais informações sobre como fazer as coisas do jeito WordPress podem ser encontradas no códice do WordPress. Os detalhes acima foram encontrados aqui na página da classe wpdb

jsnfwlr
fonte
É assim $lastid = $wpdb->$insert_id :?
Francisco Corrales Morales
"Esta função retorna falso se a linha não puder ser inserida. Caso contrário, ela retorna o número de linhas afetadas (que sempre será 1)." De: codex.wordpress.org/Function_Reference/wpdb_Class#INSERT_rows
unbreak
1
@unbreak - função errada aí ... você está lendo sobre wpdb-> insert ($ table, $ data, $ format);
jsnfwlr
4
Também é útil saber que se você usar $ wpdb-> query, ele ainda atribuirá insert_id.
Dave Scotese de
2
não foi necessário, mas acho que melhora um pouco, afirmação destacada e recuo removido, pois não é necessário para uma única linha.
kamal pal
14

É assim que eu fiz, no meu código

 ...
 global $wpdb;
 $query =  "INSERT INTO... VALUES(...)" ;
 $wpdb->query(
        $wpdb->prepare($query)
);
return $wpdb->insert_id;
...

Mais variáveis ​​de classe

Francisco Corrales Morales
fonte
1
"Esta função retorna falso se a linha não puder ser inserida. Caso contrário, ela retorna o número de linhas afetadas (que sempre será 1)." de: codex.wordpress.org/Function_Reference/wpdb_Class#INSERT_rows
unbreak
1
Funciona. O $wpdb->queryretorna o tamanho das linhas afetadas e $wpdb->insert_idpossui o último id inserido. Obrigado!
Fabio Montefuscolo
Isso é melhor para mim, porque desejo capturar inserções que, de outra forma, retornarão um erro devido a valores de coluna duplicados em uma coluna única. Não há nenhuma maneira para INSERT IGNOREcom $wpdb->insertinfelizmente.
Solomon Closson de
@unbreak - Parece que está retornando o insert_idpara mim, não o número de linhas afetadas.
Solomon Closson de
0

Algo assim também deve servir:

$last = $wpdb->get_row("SHOW TABLE STATUS LIKE 'table_name'");
$lastid = $last->Auto_increment;
Martin
fonte
10
Isso não causaria um problema se dois registros fossem inseridos quase exatamente ao mesmo tempo por dois processos diferentes? Ambos os processos podem ser inseridos ao mesmo tempo (ou próximos o suficiente ao mesmo tempo) para que o auto_incremento retorne o mesmo número para ambos os processos.
Michael Khalili,
0

Eu precisava obter a última forma de id após inseri-lo, então

$lastid = $wpdb->insert_id;

Não era uma opção.

Fiz o seguinte:

global $wpdb;
$id = $wpdb->get_var( 'SELECT id FROM ' . $wpdb->prefix . 'table' . ' ORDER BY id DESC LIMIT 1');
Marco floriano
fonte
-6

Colocar a chamada para mysql_insert_id()dentro de uma transação deve fazer isso:

mysql_query('BEGIN');
// Whatever code that does the insert here.
$id = mysql_insert_id();
mysql_query('COMMIT');
// Stuff with $id.
Ollie Saunders
fonte
4
Isso não é feito usando o objeto $ wpdb, conforme mencionado no OP.
jsnfwlr