I am new to Laravel. Does the Laravel create a database connection every time for each query of the program or use the same database object throughout the program using the "Singleton" Pattern? Does the strategy have an impact on performance, especially for Enterprise Level Applications?
The database layer of Laravel is also implemented using singletons. This means that there is only one database connection per request. This helps to keep the database layer of the application clean and easy to use.
A DB connection should not normally be a Singleton. Two reasons: many DB drivers are not thread safe. Using a singleton means that if you have many threads, they will all share the same connection.
Digging around, I found that the typical way to implement the singleton pattern is to create a singleton trait (basically a Ruby module) that can be used by any class that wants to be a singleton. Most notably, the singleton trait implements the constructor and clone function as protected.
The singleton method binds a class or interface into the service container so that Laravel can maintain dependency (when using an interface as the constructor parameter). (Actually Singleton is a design pattern. Singleton implementation always returns the same object on subsequent calls instead of a new instance).
No, it's not a singleton, but a factory pattern. However the same connection will be reused if possible and you don't manually request it to reconnect. There is no performance hit.
At the beginning of ever request lifecycle, in app/bootstrap/start.php
an instance of Illuminate\Foundation\Application
gets created. This servers as IoC container.
Shortly after creating the application all service providers will be loaded. The service providers are defined in app/config/app.php
'providers' => array(
// ...
'Illuminate\Database\DatabaseServiceProvider',
// ...
),
Let's have a look at the Illuminate\Database\DatabaseServiceProvider
shall we? The important part is the register
function
$this->app->bindShared('db', function($app)
{
return new DatabaseManager($app, $app['db.factory']);
});
An instance of DatabaseManager
gets bound to db
. This instance will stay the same over the whole request and will be used for every database request.
Say you call
DB::table('users')->get();
First, the DB
facade will resolve to the instance of DatabaseManager
that gets bound in the DatabaseServiceProvider
using bindShared('db')
protected static function getFacadeAccessor() { return 'db'; }
Then the table('users')
call gets forwarded because the method doesn't exist in Database Manager
public function __call($method, $parameters)
{
return call_user_func_array(array($this->connection(), $method), $parameters);
}
It is called on the return value of $this->connection()
public function connection($name = null)
{
list($name, $type) = $this->parseConnectionName($name);
// If we haven't created this connection, we'll create it based on the config
// provided in the application. Once we've created the connections we will
// set the "fetch mode" for PDO which determines the query return types.
if ( ! isset($this->connections[$name]))
{
$connection = $this->makeConnection($name);
$this->setPdoForType($connection, $type);
$this->connections[$name] = $this->prepare($connection);
}
return $this->connections[$name];
}
With if (!isset($this->connections[$name]))
it will check if the connection already has been established and will only make a new connection if not.
Then it returns the connection and table('users')->get()
will be executed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With