Jak uzyskać identyfikator ostatnio wstawionego wiersza z bazy danych WordPress?

98

Moja wtyczka WordPress ma tabelę z polem klucza podstawowego AUTO_INCREMENT o nazwie ID. Kiedy nowy wiersz jest wstawiany do tabeli, chciałbym uzyskać wartość ID wstawienia.

Funkcja polega na używaniu AJAX do wysyłania danych do serwera w celu wstawienia do bazy danych. Nowy identyfikator wiersza jest zwracany w odpowiedzi AJAX w celu zaktualizowania stanu klienta. Jest możliwe, że wielu klientów przesyła dane na serwer w tym samym czasie. Dlatego muszę się upewnić, że każde żądanie AJAX otrzyma w odpowiedzi DOKŁADNY nowy identyfikator wiersza.

W PHP istnieje metoda o nazwie mysql_insert_id dla tej funkcji, ale jest ona ważna dla warunku wyścigu tylko wtedy, gdy argumentem jest identyfikator_linku ostatniej operacji. Moja operacja z bazą danych jest na $ wpdb. Jak wyodrębnić identyfikatora_połączenia od $ wpdb aby upewnić się, że prace mysql_insert_id? Czy jest jakiś inny sposób uzyskania identyfikatora ostatniego wstawionego wiersza z $ wpdb?

Dzięki.

Morgan Cheng
źródło
Link | zasób jest przechowywany w $wpdb->dbh, ale jest zdefiniowany jako protected $dbh;... więc nie możesz uzyskać do niego bezpośredniego dostępu, dlatego użyj odpowiedzi poniżej :)
jave.web

Odpowiedzi:

197

Zaraz po $wpdb->insert() co robi wstawianie, zrób to:

$lastid = $wpdb->insert_id;

Więcej informacji o tym, jak robić rzeczy na sposób WordPress, można znaleźć w kodeksie WordPress. Powyższe szczegóły zostały znalezione tutaj, na stronie klasy wpdb

jsnfwlr
źródło
Czy to jest tak $lastid = $wpdb->$insert_id :?
Francisco Corrales Morales,
„Ta funkcja zwraca fałsz, jeśli nie można wstawić wiersza. W przeciwnym razie zwraca liczbę wierszy, na które ma to wpływ (która zawsze będzie wynosić 1)”. Od: codex.wordpress.org/Function_Reference/wpdb_Class#INSERT_rows
unbreak
1
@unbreak - zła funkcja ... czytasz o wpdb-> insert ($ table, $ data, $ format);
jsnfwlr
4
Warto również wiedzieć, że jeśli używasz zapytania $ wpdb-> query, nadal będzie ono przypisywać insert_id.
Dave Scotese
2
nie było konieczne, ale myślę, że trochę się poprawia, podkreślenie instrukcji i usunięcie wcięcia, ponieważ nie jest wymagane dla pojedynczego wiersza.
kamal pal
14

Tak to zrobiłem w moim kodzie

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

Więcej zmiennych klas

Francisco Corrales Morales
źródło
1
„Ta funkcja zwraca wartość fałsz, jeśli nie można wstawić wiersza. W przeciwnym razie zwraca liczbę wierszy, na które ma to wpływ (która zawsze będzie wynosić 1)”. od: codex.wordpress.org/Function_Reference/wpdb_Class#INSERT_rows
unbreak
1
To działa. Te $wpdb->querypowroty len z wierszy i $wpdb->insert_idma ostatnie wstawiony id. Dzięki!
Fabio Montefuscolo,
Jest to lepsze dla mnie, ponieważ chcę przechwytywać wstawki, które w przeciwnym razie zwrócą błąd z powodu zduplikowanych wartości kolumn w unikalnej kolumnie. Nie ma sposobu, aby INSERT IGNOREz $wpdb->insertniestety.
Solomon Closson
@unbreak - wygląda na to, że zwraca insert_iddo mnie wartość, a nie liczbę wierszy, których dotyczy problem.
Solomon Closson
0

Coś takiego powinno też to zrobić:

$last = $wpdb->get_row("SHOW TABLE STATUS LIKE 'table_name'");
$lastid = $last->Auto_increment;
Jaskółka oknówka
źródło
10
Czy nie spowodowałoby to problemu, gdyby dwa rekordy zostały wstawione prawie dokładnie w tym samym czasie przez dwa różne procesy? Oba procesy mogą wstawiać w tym samym czasie (lub wystarczająco blisko tego samego czasu), tak aby funkcja auto_increment zwróciła tę samą liczbę dla obu procesów.
Michael Khalili
0

Musiałem uzyskać ostatni identyfikator po włożeniu go, więc

$lastid = $wpdb->insert_id;

Nie było opcji.

Czy wykonałem następujące czynności:

global $wpdb;
$id = $wpdb->get_var( 'SELECT id FROM ' . $wpdb->prefix . 'table' . ' ORDER BY id DESC LIMIT 1');
Marco Floriano
źródło
-6

Wezwanie mysql_insert_id()wewnątrz transakcji powinno to zrobić:

mysql_query('BEGIN');
// Whatever code that does the insert here.
$id = mysql_insert_id();
mysql_query('COMMIT');
// Stuff with $id.
Ollie Saunders
źródło
4
To nie robi tego przy użyciu obiektu $ wpdb, jak wspomniano w OP.
jsnfwlr