I'm trying to build a test backend with slim 4, php-di (bridge for slim 4) and eloquent. In particular I got to the point of wanting to try connecting to the database (mysql provided with xampp). Trying to start the program I get the following error:
Uncaught Error: Call to a member function connection() on null in C:\xampp\htdocs\smk-backend\vendor\illuminate\database\Capsule\Manager.php
Here is my index.php file:
<?php
(require_once __DIR__ . '/../config/bootstrap.php')->run();
Here is my bootstrap.php file:
<?php
use App\Controllers\Home\HomeController;
use DI\ContainerBuilder;
use Psr\Container\ContainerInterface;
use function DI\create;
use Illuminate\Database\Capsule\Manager;
require_once __DIR__ . '/../vendor/autoload.php';
$container = (new ContainerBuilder())
->addDefinitions([
Defaults::class => create(Defaults::class),
EloquentManager::class => create(EloquentManager::class),
HomeController::class => create(HomeController::class)
])
->build();
$app = \DI\Bridge\Slim\Bridge::create();
$app->setBasePath('/smk-backend');
(require_once __DIR__ . '/routes.php')($app);
return $app;
Here is my defaults.php file:
<?php
class Defaults {
private $dbSettings;
public function __construct()
{
$this->dbSettings = [
'database' => 'prova',
'username' => 'root',
'password' => '',
'host' => '127.0.0.1:3306',
'driver' => 'mysql',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',
'prefix' => '',
];
}
public function getDbSettings() {
return $this->dbSettings;
}
}
Here is my eloquent.php file:
<?php
use Slim\App;
use Illuminate\Database\Capsule\Manager;
class EloquentManager {
private $capsule;
public function __construct(Defaults $defaults)
{
$capsule = new Manager;
$capsule->addConnection($defaults->getDbSettings());
$capsule->setAsGlobal();
$capsule->bootEloquent();
$this->capsule = $capsule;
}
}
Here is my HomeController.php file:
<?php
namespace App\Controllers\Home;
use Illuminate\Database\Capsule\Manager;
use Illuminate\Database\Query\Builder;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
final class HomeController
{
protected $manager;
public function __construct(Manager $manager)
{
$this->manager = $manager;
}
public function index(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
$response->getBody()->write('Welcome!');
return $response;
}
public function getTest(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
$prova = $this->manager->table('Test')->get();
$response->getBody()->write(var_export($prova, true));
return $response;
}
}
Finally here is my routes.php file:
<?php
use Slim\App;
use App\Controllers\Home\HomeController;
return function (App $app)
{
$app->get('/', [HomeController::class, 'getTest']);
};
All files are in the same folder except index.php and HomeController.php. From what I understand from the error, the problem is that no connection is created with the database. I tried to make some changes in the configuration (defaults.php file) but it seems that the problem is not there. I have a feeling that the HomeController class object receives nothing when the constructor is invoked. I tried to use Autowiring
From PowerShell I can connect to the database without problems
Thank you
I managed to fix my code.
Here is my new bootstrap.php file:
I eliminated several useless classes, also from the container definitions, and fixed the most important error: I wasn't passing the container instance in the call to the create function. I replaced the
create
function call withautowire
where I add the definitions.Here is my new eloquent.php file:
The biggest difference is that it is no longer a class, and now also contains the entire database configuration part. I will evaluate whether to move it to a separate configuration file anyway.
It is not yet clear to me how it is possible that when the
HomeController
class is instantiated, the Eloquent Manager object passed to the constructor still maintains the configuration used for the connection. It's not even clear to me how I was supposed to use theIlluminate\Database\Connection
class that was suggested to me. I think the last thing missing isdeclare(strict_types=1)
in every file.Update
This part of code is useless:
This part of code is useless. The code works perfectly without it. From what I understood by carefully rereading the php-di documentation, autowire works automatically even without going through the
addDefinitions
method