doctrs/stored-procedure-bundle
Install the Bundle
composer require doctrs/stored-procedure-bundle
Add to config/bundles.php:
return [
// ...
Doctrs\StoredProcedureBundle\DoctrsStoredProcedureBundle::class => ['all' => true],
];
Configure Connections
Create config/packages/stored_procedure.yaml:
stored_procedure:
connections:
default:
dbname: '%env(DATABASE_URL)%'
host: '%env(DB_HOST)%'
port: '%env(DB_PORT)%'
user: '%env(DB_USER)%'
password: '%env(DB_PASSWORD)%'
First Use Case: Execute a Procedure
Inject the Doctrs\StoredProcedureBundle\Manager\StoredProcedureManager service:
use Doctrs\StoredProcedureBundle\Manager\StoredProcedureManager;
class MyService {
public function __construct(private StoredProcedureManager $manager) {}
public function callProcedure() {
$result = $this->manager->execute('my_schema.my_procedure', [
'param1' => 'value1',
'param2' => 123,
]);
return $result;
}
}
Named Connections: Use named connections (e.g., default, admin_master) to manage multiple DB environments.
stored_procedure:
connections:
read_replica:
dbname: '%env(READ_DB)%'
host: '%env(READ_HOST)%'
Execute via:
$this->manager->execute('schema.proc', [], 'read_replica');
Dynamic Connections: Use ~ for default connection (falls back to Symfony’s database_connection).
any_connection: ~
Parameter Binding: Pass parameters as an associative array.
$this->manager->execute('schema.proc', [
'in_param' => 'value',
'out_param' => null, // For OUT parameters
]);
Result Handling:
executeScalar() for single-value returns.execute() and iterate over rows:
foreach ($this->manager->execute('schema.get_users') as $row) {
echo $row['name'];
}
Transactions:
Wrap calls in a transaction via Doctrine’s EntityManager:
$this->manager->getConnection('default')->beginTransaction();
try {
$this->manager->execute('schema.transfer_funds', ['amount' => 100]);
$this->manager->getConnection('default')->commit();
} catch (\Exception $e) {
$this->manager->getConnection('default')->rollBack();
throw $e;
}
config/app.php under providers:
Doctrs\StoredProcedureBundle\DoctrsStoredProcedureBundle::class,
.env:
stored_procedure:
connections:
default:
dbname: '%env(DB_DATABASE)%'
host: '%env(DB_HOST)%'
port: '%env(DB_PORT)%'
user: '%env(DB_USERNAME)%'
password: '%env(DB_PASSWORD)%'
AppServiceProvider:
public function register() {
$this->app->bind(\Doctrs\StoredProcedureBundle\Manager\StoredProcedureManager::class,
function ($app) {
return new \Doctrs\StoredProcedureBundle\Manager\StoredProcedureManager(
$app->make(\Doctrine\DBAL\Connection::class)
);
}
);
}
red-defender/pgfunc (last updated in 2016). Ensure compatibility with your PostgreSQL version (tested on 9.4+).EntityManager. Use getConnection() to access the underlying DBAL connection.config/packages/doctrine.yaml:
doctrine:
dbal:
logging: true
profiling: true
pgfunc’s debug mode (if supported) or wrap calls in:
$this->manager->getConnection()->getEventManager()->addListener(
\Doctrine\DBAL\Connection::EVENT_QUERY,
function ($eventArgs) {
error_log($eventArgs->getSql());
}
);
schema.proc) to avoid ambiguity.Doctrine\DBAL\Exception for robust error handling:
try {
$this->manager->execute('schema.proc');
} catch (\Doctrine\DBAL\Exception $e) {
// Log or rethrow
}
StoredProcedureManager in PHPUnit:
$mockManager = $this->createMock(StoredProcedureManager::class);
$mockManager->method('execute')->willReturn([['data' => 'test']]);
$this->app->instance(StoredProcedureManager::class, $mockManager);
Doctrs\StoredProcedureBundle\Connection\ConnectionInterface.$this->manager->getConnection()->fetchAssociative(
'SELECT * FROM information_schema.routines WHERE routine_name = ?',
['my_procedure']
);
How can I help you explore Laravel packages today?