Two boolean flags in a row, easy to transpose, and they mean opposite things. Getting them the wrong way round produces data corruption rather than an error.
The signature
public function insert(
string $table,
Select|array $set,
bool $odkUpdate = FALSE, // 3rd: ON DUPLICATE KEY UPDATE
bool $ignoreErrors = FALSE // 4th: INSERT IGNORE
): int|string|mysqli_stmt
What each does
| Call | On a duplicate key |
|---|---|
insert( $t, $v ) | Throws |
insert( $t, $v, TRUE ) | Overwrites the existing row with your values |
insert( $t, $v, FALSE, TRUE ) | Keeps the existing row and does nothing |
Why transposing them is worse than an error
Say you keep a counter and want "insert if new, otherwise leave alone":
// WRONG - resets the counter every time Db::i()->insert( 'myapp_counts', array( 'key' => $k, 'uses' => 1, 'ignored' => 0 ), TRUE ); // RIGHT - insert if new, otherwise leave the existing row alone Db::i()->insert( 'myapp_counts', array( 'key' => $k, 'uses' => 1, 'ignored' => 0 ), FALSE, TRUE );
The wrong version runs without complaint and silently resets uses to 1 and ignored to 0 on every call. Nothing is logged, nothing throws, and the bug only shows up as counters that never climb.
Which one you actually want
- Caching a computed value that should refresh — ON DUPLICATE KEY UPDATE (3rd argument).
- Recording that something happened, where the first record is the true one — INSERT IGNORE (4th argument).
- Genuinely new rows only — neither, and let it throw. A duplicate key is information.
If you want neither semantic, use Db::i()->replace(), which is a real REPLACE INTO — note that deletes and re-inserts, so any column you omit reverts to its default.
Verified against
Invision Community 5.0.19, by reading system/Db/Db.php.
Recommended Comments