We are moving our forum in GitHub Discussions. For questions about Phalcon v3/v4 you can visit here and for Phalcon v5 here.

Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

DI - how pass parameters to service constructor from DI

I can't find a clear explanation of how pass parameters to constructor from DI. I have a two classes, every class should be instantiated by passing arguments to his constructor. From documentation I've fonund 2 possiable ways to do it, the first method is clear:


class ProductActivity extends Activity implements IActivity
{
    public function __construct($userID)
    {
        parent::__construct($userID);
    }
}

class ActivitiesBuilder
{
    /** @var IActivity $activity */
    protected $activity;

    public function __construct(IActivity $activity)
    {
        $this->setActivity($activity);
        $this->buildActivity();
    }
}

$di->set('productActivity', array(
    'className' => 'Yapi\Library\Activities\ProductActivity',
    'arguments' => array(
        array('type' => 'parameter', 'value' =>  null)
    )), true);

$di->set('activityBuilder', array(
    'className' => 'Yapi\Library\Activities\ActivitiesBuilder',
    'arguments' => array(
        array('type' => 'service', 'name' => null),
    )), true);

class UserController extends ControllerBase
{
    public function couponAction($userID, $limit = 'all')
    {
        $this->di->getService('productActivity')->setParameter(0, array('type' => 'parameter', 'value' => $userID));
        $this->di->getService('activityBuilder')->setParameter(0, array('type' => 'service', 'name' => 'productActivity'));
        $this->di->getActivityBuilder()
    }
}

This is a second method, what is not clear for me here, is how shold I register the service in this case:


class UserController extends ControllerBase
{
    public function couponAction($userID, $limit = 'all')
    {
        $this->di->get('activityBuilder', array($this->di->get('productActivity', array($userID))));
    }
}


19.1k

I don't know if it's correct, but looks like this is how I should register services in case of second way

$di->set('productActivity', function ($userID) {
    return new Yapi\Library\Activities\ProductActivity($userID);
}, true);

$di->set('activityBuilder', function ($service) {
    return new Yapi\Library\Activities\ActivitiesBuilder($service);
}, true);


6.9k
Accepted
answer

I don't know if it's correct, but looks like this is how I should register services in case of second way

$di->set('productActivity', function ($userID) {
   return new Yapi\Library\Activities\ProductActivity($userID);
}, true);

$di->set('activityBuilder', function ($service) {
   return new Yapi\Library\Activities\ActivitiesBuilder($service);
}, true);

Close, you do it like so with anonymous closures, providing these variables are available in the scope of the bootstrap file.

$di->set('productActivity', function () use ($userID) {
    return new Yapi\Library\Activities\ProductActivity($userID);
}, true);

$di->set('activityBuilder', function () use ($service) {
    return new Yapi\Library\Activities\ActivitiesBuilder($service);
}, true);