Slim throws 500 HTTP and missing class errors when on live host


#1

I’ve been working with php for a while now and have been tinkering with Slim recently. I’ve made plenty of local projects, but never uploaded any of them to any host. After uploading my latest project to a host for the first time, however, I am running in to some issues.

Nothing at all seems to work when uploaded on to the host. Everything works fine on my local server (XAMPP on Windows10 running PHP 7.0.9), however the remote host only gives a 500 HTTP error and several “class cannot be found” errors. Checking some logs, I found this:

[01-Mar-2017 16:30:28 Europe/London] PHP Fatal error:  Uncaught Error: Class 'Citadel\Middleware\TrailingSlashMiddleware' not found in /home/mctoolbo/_CITADEL/files/containers/containers.php:51
Stack trace:
#0 /home/mctoolbo/_CITADEL/startup/app.php(38): require()
#1 /home/mctoolbo/_CITADEL/public/index.php(7): require('/home/mctoolbo/...')
#2 {main}
  thrown in /home/mctoolbo/_CITADEL/files/containers/containers.php on line 51
[01-Mar-2017 16:30:33 Europe/London] PHP Fatal error:  Uncaught Error: Class 'Citadel\Middleware\TrailingSlashMiddleware' not found in /home/mctoolbo/_CITADEL/files/containers/containers.php:51
Stack trace:
#0 /home/mctoolbo/_CITADEL/startup/app.php(38): require()
#1 /home/mctoolbo/_CITADEL/public/index.php(7): require('/home/mctoolbo/...')
#2 {main}
  thrown in /home/mctoolbo/_CITADEL/files/containers/containers.php on line 51

After some research I found a post that said to change any require()s with include_onces. After doing that, it still throws a 500 HTTP error but now the error logs show a new, smaller error:

[01-Mar-2017 16:52:55 Europe/London] PHP Fatal error:  Class 'Citadel\Middleware\Middleware' not found in /home/mctoolbo/_CITADEL/files/Middleware/TrailingSlashMiddleware.php on line 5

My TrailingSlashMiddleware.php file looks like this:

<?php

namespace Citadel\Middleware;

class TrailingSlashMiddleware extends Middleware {
	
	function __invoke($request, $response, $next) {
	    $uri = $request->getUri();
	    $path = $uri->getPath();
	    if ($path != '/' && substr($path, -1) == '/') {
	        $uri = $uri->withPath(substr($path, 0, -1));
	        if($request->getMethod() == 'GET') {
	            return $response->withRedirect((string)$uri, 301);
	        }
	        else {
	            return $next($request->withUri($uri), $response);
	        }
	    }
	    return $next($request, $response);
	}
}

Which is based on https://www.slimframework.com/docs/cookbook/route-patterns.html and extends the “main” middleware class, here:

<?php

namespace Citadel\Middleware;

class Middleware {

	protected $container;

	public function __construct($container) {
		$this->container = $container;
	}
}

I am adding the middleware in a containers.php file, which looks like this:

<?php

$container['db'] = function ($config) {
    $db = $config['database'];
    $pdo = new PDO("mysql:host=".$db['host'].";dbname=".$db['name'],$db['user'],$db['pass']);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    return $pdo;
};

$container['view'] = function ($container) {
	$view = new \Slim\Views\Twig("../files/views", [
		"cache" => false,
	]);
	$view->addExtension(new \Slim\Views\TwigExtension(
		$container->router,
		$container->request->getUri()
	));
	$twig = $view->getEnvironment();
	$twig->addGlobal('session', $_SESSION);
	return $view;
};

$container['home'] = function ($container) {
	return new \Citadel\Controllers\Home($container);
};

$container['account'] = function ($container) {
	return new \Citadel\Controllers\Account($container);
};

$container['user'] = function ($container) {
	return new \Citadel\Controllers\User($container);
};

$app->add(new \Citadel\Middleware\TrailingSlashMiddleware($container));
$app->add(new \Citadel\Middleware\SessionSetMiddleware($container));

All of this works PERFECTLY when I test locally, however completely breaks when uploaded to a public host.

I’m no server expert, so I cannot determine whether or not it’s an issue with the code itself, or if I am doing something wrong for the type of server the host is using. For reference sake, I am using a small company named XenonHosting (http://xenonhosting.co.uk/) which uses Linux Arch KDE (Not a Linux guy, so I’m unsure if that’s relevant or even the correct way to write it). Both my local server and the remote one use the same php version, and I uploaded the site files exactly as they are on my local server.

Does ANYONE have any ideas as to what’s going on? I’ve been trying for several hours to figure this one out on my own, but I don’t know enough about Slim to pin-point the cause of this issue.


#2

I suspect class autoloader is failing, as you have copied over everything “as is”, instead of installing with composer.
Try to run:
composer dump-autoloader
from your project root directory.

If this does not help, delete your vendor folder and run:
composer install


#3

My guess is that you’re running Windows locally and Linux on the server.

The name of the file needs to match the name of class exactly as Linux has a case-sensitive filesystem.

i.e. middleware.php and Middleware.php are different on Linux.


#4

My apologies for the late replies. This forum was preventing me from making any more posts for a while due to me being a new user.

My guess is that you’re running Windows locally and Linux on the server.

The name of the file needs to match the name of class exactly as Linux has a case-sensitive filesystem.

i.e. middleware.php and Middleware.php are different on Linux.

Yes, this seems to be the case. I had actually thought of that very early on, and made the appropriate changes to all the file names and paths, but after double checking just now it seems my changes did not save correctly, thus the fix was never applied. After changes the paths and file names a second time, everything started to work as it should. Thank you!