Ok, to me this one is rather odd. But I'm probably just missing something.
I have a REST API using Slim with about 20 routes. Each route loads a MySQL class with a db config passed to the construct.
But, any time I'm adding a new route with a new db connection config (that I havent yet setup in the db), it throws a "bad db config" exception even though I am not calling the new/unfinished route.
So, it seems that the MySQL class in EVERY ROUTE is being instantiated whenever I make an API call.
Ummm..?
CODE SAMPLE PER REQUEST:
$app->group('/content/get', function () use ($app) {
require('config/mysql.settings.php');
$db = new MySQL($dbconfig['pages']);
$app->get('/:site/:page', function ($site, $page) use ($app, $db) {
...
});
});
$app->group('/library/get', function () use ($app) {
require('config/mysql.settings.php');
$db = new MySQL($dbconfig['docs']);
$app->get('/:doc', function ($doc) use ($app, $db) {
...
});
});
$app->group('/price/get', function () use ($app) {
require('config/mysql.settings.php');
$db = new MySQL($dbconfig['price']);
$app->get('/:doc', function ($doc) use ($app, $db) {
...
});
});
If the user for the "price" configuration hasnt been added to the db, and I make a call to /library/get, I get a db error. Once I add the price user to the db, the error stops.
It has done this with every new db user I specify in a route - until its actually added to the db.
This is a PHP thing, not a Slim thing. We both know that a PHP script executes from top to bottom, acting upon and evaluating whatever it finds as it goes. While it's true that code within Slim routes isn't executed until a route is matched, your MySQL class instantiation is happening within a route group definition, not within a route.
This example, based on the Slim Skeleton, is what I worked up to verify what I figured was happening.
<?php
require '../vendor/autoload.php';
// Prepare app
$app = new \Slim\Slim();
var_dump('app');
// Define routes
$app->get('/', function () use ($app) {
echo "/";
});
$app->group('/v1', function () use ($app) {
var_dump('/v1/var_dump');
$app->get('/home', function () use ($app) {
echo "/v1/home";
});
});
$app->group('/v2', function () use ($app) {
var_dump('/v2/var_dump');
$app->get('/home', function () use ($app) {
echo "/v2/home";
});
});
// Run app
$app->run();
No matter which route you hit, all three calls to var_dump
will be executed before the route code is executed.
If this were my app, I'd consider using Slim's resource locator to configure your DB connections.
$app->dbConfig = $dbconfig;
$app->docsDb = function () use ($app) {
return new MySQL($app->dbconfig['docs']);
};
Then, within the appropriate route, you can use the connection like so (assuming you have a findAll()
method on your MySQL
class):
$app->get('/example', function () use ($app) {
$allDocs = $app->docsDb->findAll();
});
There are myriad benefits to that, not the least of which is avoiding having code in your index.php
that's being unexpectedly executed out of turn.