We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

CLI Problem service db wasn't found in the dependency injection container

Hi, I'm use phalcon 2.0 and I got the problem with cli application when query from database. How to fix ? here is my code in /myapp/app/console.php

<?php

use Phalcon\Cli\Console as ConsoleApp;
use Phalcon\DI\FactoryDefault\Cli as CliDI;

error_reporting(E_ALL);

define('VERSION', '1.0.0');
define('APP_PATH', realpath('') . '/');

//Read the configuration
$config = new Phalcon\Config\Adapter\Ini(APP_PATH . 'app/config/config.ini');

$loader = new \Phalcon\Loader();
/**
 * Auto-loader configuration
 */
$loader->registerDirs(
    array(
        APP_PATH . $config->application->controllersDir,
        APP_PATH . $config->application->pluginsDir,
        APP_PATH . $config->application->libraryDir,
        APP_PATH . $config->application->modelsDir,
        APP_PATH . $config->application->tasksDir,
    )
)->register();

/**
 * The FactoryDefault Dependency Injector automatically register the right services providing a full stack framework
 */
$di = new \Phalcon\DI\FactoryDefault\CLI();

/**
 * Database connection is created based in the parameters defined in the configuration file
 */
$di->set('db', function () use ($config) {
    return new \Phalcon\Db\Adapter\Pdo\Mysql(array(
        "host" => $config->database->host,
        "username" => $config->database->username,
        "password" => $config->database->password,
        "dbname" => $config->database->name,
    ));
});

/**
 * If the configuration specify the use of metadata adapter use it or use memory otherwise
 */
$di->set('modelsMetadata', function () use ($config) {
    if (isset($config->models->metadata)) {
        $metaDataConfig = $config->models->metadata;
        $metadataAdapter = 'Phalcon\Mvc\Model\Metadata\\' . $metaDataConfig->adapter;
        return new $metadataAdapter();
    } else {
        return new Phalcon\Mvc\Model\Metadata\Memory();
    }
});

$di = new CliDI();

$console = new ConsoleApp();
$console->setDI($di);

/**
 * Process the console arguments
 */
$arguments = array();
foreach ($argv as $k => $arg) {
    if ($k == 1) {
        $arguments['task'] = $arg;
    } elseif ($k == 2) {
        $arguments['action'] = $arg;
    } elseif ($k >= 3) {
        $arguments['params'][] = $arg;
    }
}

// define global constants for the current task and action
define('CURRENT_TASK', (isset($argv[1]) ? $argv[1] : null));
define('CURRENT_ACTION', (isset($argv[2]) ? $argv[2] : null));

try {
    // handle incoming arguments
    $console->handle($arguments);
} catch (\Phalcon\Exception $e) {
    echo $e->getMessage();
    exit(255);
}
?>

and this is my MainTask in /myapp/app/tasks/

<?php

class MainTask extends \Phalcon\CLI\Task {

    public function mainAction() {
        echo "\nThis is the default task and the default action \n";
    }

    public function testAction() {
        $phql = "SELECT * FROM Users Where username = 'qwe'";
        $r = $this->modelsManager->executeQuery($phql);
        echo $r->username;
    }

    public function test1Action() {
        echo "11 \n";
    }

?>

when I type php app/console.php main test1 the result is

11

it's ok but when i type with php app/console.php main test , the response is

Service 'db' wasn't found in the dependency injection container

How to fix this problem . thank you



11.1k
Accepted
answer

Ok I found my problem now , becuase I redeclare $di 2 times so they can't work with 2 instance here is my new code

<?php

use Phalcon\Cli\Console as ConsoleApp;
use Phalcon\DI\FactoryDefault\Cli as CliDI;

error_reporting(E_ALL);

define('VERSION', '1.0.0');
define('APP_PATH', realpath('') . '/');

//Read the configuration
$config = new Phalcon\Config\Adapter\Ini(APP_PATH . 'app/config/config.ini');

/**
 * Auto-loader configuration
 */
require APP_PATH . 'app/config/loader.php';
/**
 * The FactoryDefault Dependency Injector automatically register the right services providing a full stack framework
 */

/**
 * Database connection is created based in the parameters defined in the configuration file
 */
require APP_PATH . 'app/config/services.php';

$di = new CliDI();
$console = new ConsoleApp();
$console->setDI($di);

/**
 * Process the console arguments
 */
$arguments = array();
foreach ($argv as $k => $arg) {
    if ($k == 1) {
        $arguments['task'] = $arg;
    } elseif ($k == 2) {
        $arguments['action'] = $arg;
    } elseif ($k >= 3) {
        $arguments['params'][] = $arg;
    }
}

// define global constants for the current task and action
define('CURRENT_TASK', (isset($argv[1]) ? $argv[1] : null));
define('CURRENT_ACTION', (isset($argv[2]) ? $argv[2] : null));

try {
    // handle incoming arguments
    $console->handle($arguments);
} catch (\Phalcon\Exception $e) {
    echo $e->getMessage();
    exit(255);
}

I had similiar requirement, but not only to connect db service but other as well.


//$diCli is my CLI IoC DI
//$di is loaded from the main web app
//resolve and copy other services
require_once APPLICATION_PATH . '/services/services.php';

$diCli->set('db', $di->get('db'));
$diCli->set('webservice', $di->get('webservice'));
$diCli->set('messageBroker', $di->get('messageBroker'));

In this way it is easy to maintain only one main IoC (the web app). CLI app gets the same services resolved at runtime.