Routing Problem - Returns 404 - only last route is loaded - SOLVED


#1

I found an issue when multiple routes are included in the index.php file - only the last route seems to be loaded. The other routes will return a 404 error. I can change the order and the last file always works properly.

I am using version 3.8.1.

Snippet:

$app = new \Slim\App;

require_once “…/src/routes/file1.php”;
require_once “…/src/routes/file2.php”;
require_once “…/src/routes/file3.php”;

$app->run();


#2

Update #2:
I found something interesting (locally). The last route listed in the index.php file seemed to work. I moved one of the others to the bottom and that one worked.

require_once ‘…/src/routes/r1.php’;
require_once ‘…/src/routes/r2.php’;
require_once ‘…/src/routes/r3/php’;

I tried this on the server and the call made an attempt to work. I got a 500 error; however, it found the route.


#3

I think the problem is within the r1, r2 and r3 files. I think you overwrite the previous routing in there, but this is just a guess since you didn’t post them :slight_smile:


#4

Here are the route skeletons. The only thing that seems odd is creating a new $app in each route. I modeled this after a Slim demo video. I’ve tried with and without the variable and they seem to work the same.

r1.php
--------------
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

$app = new \Slim\App;

$app->get('/apicall', function (Request $request, Response $response) {
   // does some stuff
});

$app->get('/apicall/{username}', function (Request $request, Response $response) {
    // does some stuff
});

$app->get('/apicall/id/{id}', function (Request $request, Response $response) {
    // does some stuff
});

$app->delete('/apicall/{username}', function (Request $request, Response $response) {
    // does some stuff
});


r2.php
---------
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

require_once '../src/models/ProductRequest.php';
require_once '../src/models/ProductManifest.php';

$app = new \Slim\App;

$app->post('/product', function (Request $request, Response $response) {
    // does some stuff
});


r3.php
---------------
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

$app = new \Slim\App;

$app->get('/user', function (Request $request, Response $response) {
    // does some stuff
});

$app->get('/user/{username}', function (Request $request, Response $response) {
    // does some stuff
});

$app->get('/user/id/{id}', function (Request $request, Response $response) {
    // does some stuff
});

$app->get('/user/apikey/{apikey}', function (Request $request, Response $response) {
    // does some stuff
});

#5

Creating the new $app object in each route was the problem. I removed it from all routes and now things work as expected.


#6

So it was something like i thought it was :slight_smile:
Anyways. A routing file should only have routing inside (lesson learned)

What I have is a bootstrap file (loaded in the index)

$app = include_once __DIR__ . '/../init/bootstrap.php';
$app->run();

Then my bootstrap (parts of it):

include_once ROOTDIR . '/vendor/autoload.php';
include __DIR__.'/env.php'; // Include a certain environment configuration
$app = new \Slim\App(['settings' => $config]);

include __DIR__ . './initDIC.php'; // initialize Dependency Injection Container
include __DIR__ . '/routes.php';   // Register all routes

$app->add( new InfoMiddleware($config['debug'], $appStartTime) ); // middleware

return $app;

So each include has a separate task, which is far more clean & easy to maintain.