I'm moving a project of mine into Slim Microframework, by using PHP-DI containerization. I need to POST some JSON data to http://localhost/api/base (XAMPP) and get a confirmation (at least at the beginning). This is my index.php:
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
use Slim\Exception\HttpMethodNotAllowedException;
use Slim\Exception\HttpNotFoundException;
use Slim\Routing\RouteContext;
use DI\ContainerBuilder;
// Set error reporting to display all errors
error_reporting(E_ALL);
ini_set('display_errors', 'On');
// Autoloading using Composer's autoload
require __DIR__ . '/../vendor/autoload.php';
// Include dependencies file
$container = require_once __DIR__ . '/../config/dependencies.php';
// Create Slim app
$app = AppFactory::create();
// Include routes
require __DIR__ . '/../src/routes.php';
$app->run();
This is routes.php:
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use App\Controllers\HotelBaseController;
// Include dependencies file
$container = require_once __DIR__ . '/../config/dependencies.php';
// Define basic route
$app->get('/', function (Request $request, Response $response) {
$response->getBody()->write('Hello, World!');
return $response;
});
// Route for handling POST request to /api/base
$app->post('/api/base', function (Request $request, Response $response) use ($container) {
// Get the HotelBaseController service from the container
$hotelBaseController = $container->get('HotelBaseController');
// Call the handlePostRequest method
return $hotelBaseController->handlePostRequest($request, $response);
});
$app->get('/api/base/', function (Request $request, Response $response) {
return $response->withStatus(301)->withHeader('Location', '/api/base');
});
This is the dependencies.php:
<?php
use DI\ContainerBuilder;
// use Psr\Http\Message\ResponseInterface as Response;
// use Psr\Http\Message\ServerRequestInterface as Request;
require __DIR__ . '/../vendor/autoload.php';
// Create ContainerBuilder instance
$containerBuilder = new ContainerBuilder();
// Set up your container configuration
$containerBuilder->addDefinitions([
'HotelBaseController' => DI\create(\App\Controllers\HotelBaseController::class),
]);
// Build the container
return $containerBuilder->build();
And, finally, this is hotelBaseController.php:
<?php
namespace App\Controllers;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
class HotelBaseController {
public function handlePostRequest(Request $request, Response $response) {
// Get the JSON data from the request body
$data = $request->getParsedBody();
// You can access the individual fields from the JSON data
$userId = $data['userId'] ?? '';
$apiKey = $data['apiKey'] ?? '';
$documentType = $data['document_type'] ?? '';
$hotelId = $data['hotel_id'] ?? '';
$hotelName = $data['name'] ?? '';
$res = 'Who knows';
return $res;
}
}
?>
When sending any POST request, containing a simple JSON, I get the error:
<b>Fatal error</b>: Uncaught Error: Call to a member function get() on bool in C:\xampp\htdocs\src\routes.php:20
Stack trace:
#0 C:\xampp\htdocs\vendor\slim\slim\Slim\Handlers\Strategies\RequestResponse.php(38):
{closure}(Object(Slim\Http\ServerRequest), Object(Slim\Http\Response), Array)
#1 C:\xampp\htdocs\vendor\slim\slim\Slim\Routing\Route.php(358):
Slim\Handlers\Strategies\RequestResponse->__invoke(Object(Closure), Object(Slim\Http\ServerRequest),
Object(Slim\Http\Response), Array)
#2 C:\xampp\htdocs\vendor\slim\slim\Slim\MiddlewareDispatcher.php(65):
Slim\Routing\Route->handle(Object(Slim\Http\ServerRequest))
#3 C:\xampp\htdocs\vendor\slim\slim\Slim\MiddlewareDispatcher.php(65):
Slim\MiddlewareDispatcher->handle(Object(Slim\Http\ServerRequest))
#4 C:\xampp\htdocs\vendor\slim\slim\Slim\Routing\Route.php(315):
Slim\MiddlewareDispatcher->handle(Object(Slim\Http\ServerRequest))
#5 C:\xampp\htdocs\vendor\slim\slim\Slim\Routing\RouteRunner.php(68):
Slim\Routing\Route->run(Object(Slim\Http\ServerRequest))
#6 C:\xampp\htdocs\vendor\slim\slim\Slim\MiddlewareDispatcher.php(65):
Slim\Routing\RouteRunner->handle(Object(Slim\Http\ServerRequest))
#7 C:\xampp\htdocs\vendor\slim\slim\Slim\App.php(199):
Slim\MiddlewareDispatcher->handle(Object(Slim\Http\ServerRequest))
#8 C:\xampp\htdocs\vendor\slim\slim\Slim\App.php(183): Slim\App->handle(Object(Slim\Http\ServerRequest))
#9 C:\xampp\htdocs\public\index.php(50): Slim\App->run()
#10 {main}
thrown in <b>C:\xampp\htdocs\src\routes.php</b> on line <b>20</b><br />
I would like to understand where am I making a mistake. Thanks
The error message contains
bool? You have$container = require_once? I know exactly what's going on.See,
require_onceacts differently thanrequire. Not just in the fact that it only requires the code once, but also for scripts that return a value.The first time you require it, you'll get your value as expected.
The second time however, you'll only get
false. That's because since the file had already been loaded, it didn't load it again.There's no "global require_once return value cache" sadly.
What you'll have to do is require it only once, and propagate that variable instead of loading it another time.