Advanced Topics
Transactions
Rubik wraps PDO transactions. You must ensure your tables support transactions (e.g., InnoDB for MySQL).
Helper Method (Recommended)
The transaction method automatically commits on success and rolls back if any Throwable is caught.
try {
Rubik::transaction(function() {
$u = new User();
$u->save();
if (somethingWrong()) {
throw new Exception("Rollback!");
}
});
} catch (Exception $e) {
// Transaction already rolled back here
}
Manual Control
Security: The SQL Value Object
Rubik automatically escapes all inputs passed to where, insert, and update. However, sometimes you need to pass raw SQL (e.g., database functions).
To do this securely, use the AdaiasMagdiel\Rubik\SQL class. Rubik detects instances of this class and injects the string verbatim.
use AdaiasMagdiel\Rubik\SQL;
// BAD: Potentially unsafe if $input is dirty
$q->update(['updated_at' => "NOW()"]); // Will define string "NOW()"
// GOOD:
$q->update(['updated_at' => SQL::raw('NOW()')]); // Will execute SQL function
Security Warning
NEVER pass user-supplied data into SQL::raw().
Bad: `SQL::raw("dATEDIFF(now(), '$userInput')")` -> **SQL Injection**.
Good: `where('date', '<', $userInput)` -> **Safe (Parameterized)**.
Identifiers vs Values
Rubik internally distinguishes between:
- Identifiers: Table names and Column names. These are sanitized via
quoteIdentifier(adds backticks`or double quotes"). - Values: Data content. These are parameterized as
:placeholder.
Scopes (Magic Methods)
You can define reusable query logic in your Model using the scope prefix.
Definition:
class User extends Model {
public function scopeActive(Query $query) {
$query->where('status', 'active');
}
}
Usage:
Handling Database Differences
Rubik attempts to abstract differences, but some leak through:
- Auto-Increment: SQLite handles standard
INTEGER PRIMARY KEYas auto-increment. MySQL requires the explicitAUTO_INCREMENTflag. Rubik'sSchemaTraithandles this generation logic. - String vs Text: In SQLite,
VARCHARis mapped toTEXT. In MySQL, strict lengths are enforced. - JSON: MySQL has a native
JSONtype. SQLite stores it asTEXT. Rubik validates JSON validity in PHP before saving to ensure consistency.