yajra/laravel-oci8
Oracle database driver for Laravel using the PHP OCI8 extension. Adds an Illuminate/Database-compatible Oracle connection with Laravel version support (5.1+ through 13), plus optional PHPStan/Larastan helpers for OCI8-specific DB methods.
Installation:
composer require yajra/laravel-oci8:^13
For Laravel 5.5+, no additional service provider registration is required. For older versions, add to config/app.php:
Yajra\Oci8\Oci8ServiceProvider::class,
Configure .env:
DB_CONNECTION=oracle
DB_HOST=your_oracle_host
DB_PORT=1521
DB_SERVICE_NAME=your_service
DB_DATABASE=your_db
DB_USERNAME=your_user
DB_PASSWORD=your_password
First Query:
$users = DB::connection('oracle')->select('SELECT * FROM users WHERE 1=1');
Schema::create('users', function (Blueprint $table) {
$table->id(); // Uses sequence in 12c+, identity in 12c+
$table->string('name');
$table->timestamps();
});
$results = DB::table('users')
->where('name', 'LIKE', '%John%')
->orderBy('created_at', 'desc')
->get();
$config = config('database.connections.oracle');
$config['username'] = 'dynamic_user';
DB::connection($config)->getPdo();
Schema::create('orders', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->json('metadata')->nullable(); // Oracle 21c+ native JSON
$table->comment('Stores user orders with metadata');
});
Schema::table('users', function (Blueprint $table) {
$table->index('email', 'idx_users_email');
$table->index(['name', 'created_at'], 'idx_users_name_date');
});
$users = DB::table('users')->paginate(15); // Uses Oracle-specific COUNT query
$results = DB::table('products')
->where('metadata->>$.category', '=', 'electronics')
->get();
$results = DB::table('orders')
->joinLateral('order_items', 'orders.id', '=', 'order_items.order_id')
->select('orders.*', 'order_items.product_id')
->get();
// Switch connections dynamically
$config = config('database.connections.oracle');
$config['database'] = 'reporting_db';
$reportData = DB::connection($config)->select('SELECT * FROM reports');
DB_HOST=host1.example.com,host2.example.com
DB_LOAD_BALANCE=yes
Schema::prefix('app_'); // Applies to all subsequent operations
Schema::create('users', function (Blueprint $table) { ... });
Schema::table('posts', function (Blueprint $table) {
$table->bigIncrements('id'); // Uses IDENTITY column
});
// Configure in config/scout.php
'driver' => 'oracle',
class User extends Model {
protected $connection = 'oracle';
protected $casts = [
'metadata' => 'json',
'created_at' => 'datetime:Y-m-d H:i:s',
];
}
php artisan db:show --connection=oracle
Case Sensitivity:
'providers' => [
'users' => [
'driver' => 'oracle',
'model' => App\User::class,
],
],
binary_ci:
DB::table('users')->where('name', 'LIKE', '%John%', 'binary_ci');
Sequence Ownership:
// Fix: Grant usage on sequences
DB::statement('GRANT CREATE SESSION TO your_user');
DB::statement('GRANT CREATE SEQUENCE TO your_user');
Name Length Limits:
ORA_MAX_NAME_LEN=128
Schema::table('long_table_names', function (Blueprint $table) {
$table->index('column_name', 'idx_ltn_column'); // Keep names < 128 chars
});
JSON Limitations:
// ❌ Avoid:
$user->metadata->category = 'new_category';
$user->save(); // Fails silently
// ✅ Do:
$user->metadata = json_decode($user->metadata, true);
$user->metadata['category'] = 'new_category';
$user->metadata = json_encode($user->metadata);
$user->save();
Pagination Quirks:
rownum adjustments:
// Fix for "ORA-01795: maximum number of expressions in a list is 1000"
DB::table('large_table')->whereIn('id', $ids)->get();
// Use chunking:
$ids->chunk(999)->each(function ($chunk) {
DB::table('large_table')->whereIn('id', $chunk)->get();
});
Connection Timeouts:
.env:
DB_CONNECT_TIMEOUT=30
DB_TRANSPORT_CONNECT_TIMEOUT=120
config/logging.php:
'default' => env('LOG_CHANNEL', 'oracle'),
'channels' => [
'oracle' => [
'driver' => 'single',
'path' => storage_path('logs/oracle.log'),
'level' => 'debug',
],
],
DB::select('SELECT /*+ FIRST_ROWS(10) */ * FROM large_table WHERE active = 1');
-- Grant required privileges
GRANT CREATE SESSION, CREATE TABLE, CREATE SEQUENCE TO your_user;
Custom Grammar: Override Oracle grammar for project-specific syntax:
class CustomOracleGrammar extends Yajra\Oci8\OracleGrammar {
public function compileSelect(SelectQuery $query) {
// Custom logic
return parent::compileSelect($query);
}
}
Register in AppServiceProvider:
public function boot() {
DB::connection('oracle')->setQueryGrammar(new CustomOracleGrammar());
}
Dynamic Configuration:
Extend the dynamic config array for runtime overrides:
'oracle' => [
'driver' => 'oracle',
'dynamic' => [App\Services\OracleConfig::class, 'overrideConfig'],
],
class OracleConfig {
public static function overrideConfig(&$config) {
$config['database'] = self::getEnvironmentDatabase();
}
}
PHPStan/Larastan: Enable OCI8-specific method recognition:
includes:
- vendor/yajra/laravel-oci8/extension.
How can I help you explore Laravel packages today?