Due to debugging reasons (I am hunting down a very weird bug), I need to extend the Laravel classes Illuminate\Database\DatabaseManager
, Illuminate\Database\Connection
, and Illuminate\Database\Query\Builder
.
Hence, I created the following three classes in my application.
namespace App\Database;
use Illuminate\Database\DatabaseManager as BaseDatabaseManager;
class DatabaseManager extends BaseDatabaseManager {
public static bool $isDebugEnabled = false;
// ...
// Overwrites some methods of the base class which prints additional diagnostic information
// if `self::$isDebugEnabled === true`.
// ...
}
and
namespace App\Database;
use Illuminate\Database\Connection as BaseConnection;
class Connection extends BaseConnection {
public static bool $isDebugEnabled = false;
/**
* Get a new query builder instance.
*
* This returns our own extended query builder with instrumentation.
*
* @return Query\Builder
*/
public function query(): Query\Builder {
return new Query\Builder(
$this, $this->getQueryGrammar(), $this->getPostProcessor()
);
}
// ...
// Overwrites some methods of the base class which prints additional diagnostic information
// if `self::$isDebugEnabled === true`.
// ...
}
and
namespace App\Database\Query;
use Illuminate\Database\Query\Builder as BaseBuilder;
class Builder extends BaseBuilder {
public static bool $isDebugEnabled = false;
// ...
// Overwrites some methods of the base class which prints additional diagnostic information
// if `self::$isDebugEnabled === true`.
// ...
}
How do I register my custom DatabaseManager
and Connection
with the Laravel Service Container instead of the original parent classes? The original classes are registered in \Illuminate\Foundation\Application::registerCoreContainerAliases()
which is called by the constructor of the Application
object, i.e. these classes are registered at a very early stage.
I thought that I could "re-register" my classes in \App\Providers\AppServiceProvider::register
like this
namespace App\Providers;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register() {
// Overwrite core container services with our own classes
// for debugging purposes
// See \Illuminate\Foundation\Application::registerCoreContainerAliases()
$this->app->alias('db', \App\Database\DatabaseManager::class);
$this->app->alias('db.connection', \App\Database\Connection::class);
}
}
but it did not work. The original classes are still being used. I used app->alias
, because this is what registerCoreContainerAliases
originally uses, too. But I also tried ->bind
with no success.
After some debugging I found out that ->alias
and ->bind
do not overwrite a previously registered binding, but simply add a new binding to the end of the list. Hence, the previously registered services by the Laravel core application are still preferential.
What is the correct solution?