Just In Case. Fetch mode customization for PDO connection in Laravel Framework

mitrallex
3 min readApr 8, 2021

About Just In Case

While studying the Laravel framework, I was faced with some not-so-obvious problems (for me). One day, when I realized that it might be helpful for other people to know about it, I decided to write down all the issues that seem interesting to me. To this end, I will write series of articles with the name “Just In Case”. Information from these articles might not be very important but, you know, it’s just in case information.

Please note that most information about the Laravel framework can be found in the official documentation. This article offers a little more details in some cases.

Introduction

In some cases we need to work with the results returned from the Query Builder as a Collection of arrays instead of Std Objects (Standard Defined Classes) which is the defailt behaviour.

By the way, the results of Eloquent queries are always returned as Collection instances.

Act

Previously (in Laravel 5.3 and below) we could set fetch mode for PDO connection from the configuration file or to do something like this:

DB::connection()->setFetchMode(\PDO::FETCH_ASSOC);

But if you tried to do that for newer version of Laravel you will get an error :

Call to undefined method Illuminate\Database\MySqlConnection::setFetchMode()

In vendor/laravel/framework/src/Illuminate/Database/Connection.php we have a protected property:

/**
* The default fetch mode of the connection.
*
*
@var int
*/
protected
$fetchMode = PDO::FETCH_OBJ;

So as you can see by default we fetch records as objects and we can’t change this value outside the Connection class.

Actually we can do that but throught the StatementPrepared event (Illuminate\Database\Events\StatementPrepared). This evemt fires in the Connection class during configuration of prepared statement:

/**
* Configure the PDO prepared statement.
*
*
@param \PDOStatement $statement
*
@return \PDOStatement
*/
protected function
prepared(PDOStatement $statement)
{
$statement->setFetchMode($this->fetchMode);

$this->event(new StatementPrepared(
$this, $statement
));

return $statement;
}

So, to change fetch mode of the connection we need to listen this event in some service provider: you can use AppServiceProvider or EventServiceProvider or any other one. Add the following code in the boot method of an appropriate service provider (do not forget to import StatementPrepared class):

public function boot()
{
Event::listen(StatementPrepared::class, function($event) {
/** @var StatementPrepared $event */
$event->statement->setFetchMode(\PDO::FETCH_ASSOC);
});
}

That’s all, now if we tried to execute some request like:

DB::table('tasks')->get()

As a result we will get the Collection of arrays instead of Collection of Std Objects. To ensure that you can just iterate through the result and check if each item is an array, for example:

/** @var Tasks $task */
foreach
($tasks as $task) {
$isArray = is_array($task);
}

Just In Case

Do not forget to register you service provider in config/app.php in providers section. For exampler let’s register EventServiceProvider:

/*
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/

'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
...
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
],

Conclusion

Laravel no longer includes the ability to customize the PDO “fetch mode” from your configuration files. Instead, PDO::FETCH_OBJ is always used. If you would still like to customize the fetch mode for your application you may listen for the new Illuminate\Database\Events\StatementPrepared event.

There is nothing new about the customization fetch mode of the PDO connection, but I faced with such a problem during my job and this knowledge would really save my time.

P.S. If you have any questions or suggestions write it in the comments. Thank you for the reading!

--

--