简体   繁体   中英

Simple way to get config in ZF2 class

I want to create a simple class that will send a predefined email to given email address. So I created the following class:

namespace Custom;

use Zend\Mail\Message;
use Zend\Mail\Transport\Smtp as SmtpTransport;
use Zend\Mail\Transport\SmtpOptions;

class Notification
{   
    public function sendEmailNotification($to)
    {
        try {
            $message = new Message();
            $message->addTo($to)
                ->addFrom('test@example.com')
                ->setSubject('Hello')
                ->setBody('Predefined email body');

            $transport = new SmtpTransport();
            $options   = new SmtpOptions(array(
                    'name'              => 'smtp.example.com',
                    'host'              => 'smtp.example.com',
                    'port'              => '587',
                    'connection_class'  => 'plain',
                    'connection_config' => array(
                            'username'  => 'test@example.com',
                            'password'  => 'somepasswd',
                            'ssl'       => 'tls',
                    ),
            ));
            $transport->setOptions($options);
            $transport->send($message);
        } catch (\Exception $e) {
            echo $e->getMessage();
        }
    }
}

From controller, the email is then sent with:

$notification = new \Custom\Notification();
$notification->sendEmailNotification('example@example.com');

This works as intended.

Next thing that I wanted to do is to move mail server configuration parameters into project configuration file ( local.php ). Problem is - how can I get the configuration parameters in my \\Custom\\Notification class (which is not a controller)?

Solutions I have found so far seem too complicated to a beginner like me. To do something like $config = $this->getServiceLocator()->get('Config'); you have to do some kind of magic all around the project.

Is there a simple way to get data from configuration file in a custom class?

You have to use injection for your purpose. Just create a factory for your controller, in which you inject the config to your controller.

namespace Application\Controller\Service;

class YourControllerFactory 
{
    public function __invoke(ContainerInterface $container)
    {
        $serviceLocator = $container->getServiceLocator();
        $config = $serviceLocator->get('config');

        $controller = new YourController($config);

        return $controller;
    }
}

For this purpose your controller needs a constructor which takes the config as parameter.

namespace Application\Controller;

class YourController extends AbstractActionController
{
    protected $config;

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

    public function indexAction()
    {
        // inject your notification class with the config
        $notification = new \Custom\Notification($this->config);
        $notification->sendEmailNotification('example@example.com');
    }
}

Therefore your notification class needs a constructor which takes the config as parameter.

Other approaches

Another way solving your issue can be the registration of your notification class as a service. Just create a factory for your notification class, in which you create all the needed stuff and then just inject it to your notification class.

namespace Application\Mail;

class Notification
{
    protected $config;

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

    public function sendEmailNotification($to)
    {

    }
}

The factory itself is simple as pie, because we 've seen nearly the same approach in the controller factory.

namespace Application\Mail\Service;

class NotificationFactory
{
    public function __invoke(ContainerInterface $container)
    {
        $config = $container->get('config');
        $notification = new Notification($config);

        return $notification;
    }
}

Now you just have to note it in your module.config.php file in the service manager section.

'service_manager' => [
    'factories' => [
        Notification::class => NotificationFactory::class,
    ],
],

From now on you can access the notification class with the service container of zend framework 2. Remember the factory for your controller instance shown above? Instead of injecting the config to your controller, just inject it with the notification itself. Your notification class will be created with the needed config over the notification factory.

namespace Application\Controller\Service;

class YourControllerFactory 
{
    public function __invoke(ContainerInterface $container)
    {
        $serviceLocator = $container->getServiceLocator();
        $notification = $serviceLocator->get(Notification::class);

        return new YourController($notification);
    }
}

Have fun. ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM