I'm currently separating my API from a full Phalcon website to a micro/medium one for easier maintenance and devops purposes.
I've separated my api into collections. These collections use the methods from the corresponding controllers. It however seems that Phalcon cannot find the namespace my controllers reside in.
All my controllers are separated into namespaces: Ontrack\Controllers\Api\V1
These controllers extend from a ControllerBase
which extends on its own from the Phalcon Controller class.
How can this issue be fixed?
Full error:
There are no handlers to mount
#0 /home/vagrant/workspace/phalcon/api/public/index.php(43): Phalcon\Mvc\Micro->mount(Object(Phalcon\Mvc\Micro\Collection))
#1 {main}
When I change my general-user.php
file to use an UserController object I get a different error:
( ! ) Fatal error: Uncaught Error: Class 'Ontrack\Controllers\Api\V1\UserController' not found in /home/vagrant/workspace/phalcon/api/app/collections/v1/general-user.php on line 6
( ! ) Error: Class 'Ontrack\Controllers\Api\V1\UserController' not found in /home/vagrant/workspace/phalcon/api/app/collections/v1/general-user.php on line 6
Call Stack
# Time Memory Function Location
1 0.0030 361992 {main}( ) .../index.php:0
2 0.0080 377968 include( '/home/vagrant/workspace/phalcon/api/app/config/routes.php' ) .../index.php:40
3 0.0144 379624 include( '/home/vagrant/workspace/phalcon/api/app/collections/v1/general-user.php' ) .../routes.php:5
Folder structure:
- app
--collections
--config
--controllers
---v1
-public
Contents of /public/index.php:
<?php
use Phalcon\Mvc\Micro;
use Phalcon\Di\FactoryDefault;
error_reporting(E_ALL);
define('BASE_PATH', dirname(__DIR__));
define('APP_PATH', BASE_PATH . '/app');
try {
/**
* The FactoryDefault Dependency Injector automatically registers
* the services that provide a full stack framework.
*/
$di = new FactoryDefault();
/**
* Read services
*/
include APP_PATH . "/config/services.php";
/**
* Get config service for use in inline setup below
*/
$config = $di->getConfig();
/**
* Include Autoloader
*/
include APP_PATH . '/config/loader.php';
/**
* Handle and deploy the application
*/
$application = new Micro();
$application->setDI($di);
//Loading all API routes
include APP_PATH . '/config/routes.php';
foreach($collections as $collection) {
$application->mount($collection);
}
$application->notFound(function () use ($application) {
$application->response->setStatusCode(404, "Not Found")->sendHeaders();
echo "not found!";
});
$application->handle();
} catch (\Exception $e) {
echo $e->getMessage() . '<br>';
echo '<pre>' . $e->getTraceAsString() . '</pre>';
}
Contents of /app/collections/v1/general-user.php:
<?php
use Phalcon\Mvc\Micro\Collection as MicroCollection;
use Ontrack\Controllers\Api\V1\UserController as UserController;
$general_user = new MicroCollection();
$general_user->setHandler('Ontrack\\Controllers\\Api\\V1\\UserController', true);
$general_user->setPrefix('/v1/user');
$general_user->post('/revokedevice', 'revokedeviceAction');
return $general_user;
Contents of /app/config/config.php:
<?php
defined('BASE_PATH') || define('BASE_PATH', getenv('BASE_PATH') ?: realpath(dirname(__FILE__) . '/../..'));
defined('APP_PATH') || define('APP_PATH', BASE_PATH . '/app');
return new \Phalcon\Config([
'database' => [
'adapter' => 'Mysql',
'host' => 'localhost',
'username' => 'root',
'password' => '',
'dbname' => 'defaultname',
'charset' => 'utf8',
],
'application' => [
'applicationname' => 'MyApp',
'appDir' => APP_PATH . '/',
'controllersDir' => APP_PATH . '/controllers/',
'modelsDir' => APP_PATH . '/models/'
// This allows the baseUri to be understand project paths that are not in the root directory
// of the webpspace. This will break if the public/index.php entry point is moved or
// possibly if the web server rewrite rules are changed. This can also be set to a static path.
'baseUri' => '/',
]
]);
Contents of /app/config/loader.php:
<?php
$loader = new \Phalcon\Loader();
/**
* We're a registering a set of directories taken from the configuration file
*/
$loader->registerDirs(
[
$config->application->controllersDir,
$config->application->modelsDir,
]
)->register();
$loader->registerNamespaces(
[
//EXAMPLE "Example\Base" => "vendor/example/base/", USAGE $var = new Example\Base();
'Ontrack\Controllers\Api' => APP_PATH . '/controllers/v1/',
'Ontrack\Models' => APP_PATH . '/models/',
'Ontrack\Vendors' => $config->application->vendorDir,
]
)->register();
Contents of /app/config/routes.php:
<?php
$collections = [
include APP_PATH . '/collections/v1/general-auth.php',
include APP_PATH . '/collections/v1/general-user.php',
];
return $collections;
Contents of /app/config/services.php:
<?php
/**
* Shared configuration service
*/
$di->setShared('config', function () {
return include APP_PATH . "/config/config.php";
});
/**
* The URL component is used to generate all kind of urls in the application
*/
$di->setShared('url', function () {
$config = $this->getConfig();
$url = new UrlResolver();
$url->setBaseUri($config->application->baseUri);
return $url;
});
/**
* Database connection is created based in the parameters defined in the configuration file
*/
$di->setShared('db', function () {
$config = $this->getConfig();
$class = 'Phalcon\Db\Adapter\Pdo\\' . $config->database->adapter;
$params = [
'host' => $config->database->host,
'username' => $config->database->username,
'password' => $config->database->password,
'dbname' => $config->database->dbname,
'charset' => $config->database->charset
];
if ($config->database->adapter == 'Postgresql') {
unset($params['charset']);
}
$connection = new $class($params);
return $connection;
});