Yii2动态设置组件值

时间:2016-09-21 05:38:14

标签: php yii2

我正在使用此库https://github.com/yiioverflow/yii2-imap

 'imap' => [
                'class' => 'roopz\imap\Imap',
                'connection' => [
                    'imapPath' => '{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX',
                    'imapLogin' => 'abc@gmail.com',//set this value dynamically
                    'imapPassword' => '123',//set this value dynamically
                    'serverEncoding' => 'encoding', // utf-8 default.
                    'attachmentsDir' => 'uploads/attachments'
                ],
            ],
  //Create imap class object
  $mailbox = yii::$app->imap->connection;
  // Read all messaged into an array:
  $mailsIds = $mailbox->searchMailbox('ALL');

在控制器中。想在yii2中使用session设置这个值。

3 个答案:

答案 0 :(得分:1)

我在这里找到了替代的php-imap库[PHP IMAP] [1]

[1]:https://github.com/barbushin/php-imap。在yii2中可以使用composer轻松安装。并且可以传递动态值

  $mailbox = new PhpImap\Mailbox('{imap.gmail.com:993/imap/ssl}INBOX', 'some@gmail.com', '*********', __DIR__);
  // Read all messaged into an array:
  $mailsIds = $mailbox->searchMailbox('ALL');

答案 1 :(得分:0)

在config中传递依赖于Yii::$app的动态值将不起作用,因为您指的是应用程序,并且它是使用该配置构建的(组件也是应用程序的一部分)并且此时不存在。当应用程序初始化并且存在Yii::$app对象时,需要稍后设置它。例如,在控制器或某个自定义组件中。

使用库yiioverflow/yii2-imap可以这样做:

use Yii;

...

Yii:$app->imap->connection = [
    'imapPath' => '{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX',
    'imapLogin' => $imapLogin, // Set this value dynamically
    'imapPassword' => $imapPassword, // Set this value dynamically
    'serverEncoding' => 'encoding', // utf-8 default
    'attachmentsDir' => 'uploads/attachments',
],

然后你需要打电话:

Yii:$app->imap->createConnection();

正确更新配置。

由于此组件的编写方式(这些属性受imapLogin数组保护并填充),因此无法单独设置imapPasswordconnection。如果你想这样做,你必须对这个组件进行子类化并自己编写这些setter,并将使用过的组件替换为自定义的组件。

有关应用程序组件的更多信息,请参阅official docs

答案 2 :(得分:0)

您可以使用自己的"服务层" (与全局Yii::$app类似)。只需创建\yii\di\ServiceLocator实例:

// Init service layer.
$services = new ServiceLocator();
$services->setComponents([
    'imap' => [
        'class' => 'roopz\imap\Imap',
        'connection' => [
            'imapPath' => '{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX',
            'imapLogin' => 'abc@gmail.com',//set this value dynamically
            'imapPassword' => '123',//set this value dynamically
            'serverEncoding' => 'encoding', // utf-8 default.
            'attachmentsDir' => 'uploads/attachments'
        ],
    ],
    // ...
]);


// Retrieving the defined components:
$imap = $services->get('imap');
$imap = $services->imap;

如果imap组件仅使用您的控制器,则可以将$services存储为此控制器的受保护/私有属性。 所描述的方法与Yii::$app中的常用组件完全类似,因为应用程序类也是ServiceLocator。

或者,您可以使用imap-instance:

定义或重新定义组件
// Preparing components
$defaultImapConfig = [
    'connection' => [
        'imapPath'       => '{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX',
        'imapLogin'      => null,
        'imapPassword'   => null,
        'serverEncoding' => 'encoding', // utf-8 default.
        'attachmentsDir' => 'uploads/attachments'
    ],
];


// Init service layer.
$services = new ServiceLocator();


// Define component 
$imap = new \roopz\imap\Imap(ArrayHelper::merge($defaultImapConfig, ['connection' => [
    'imapLogin'     => 'abc@gmail.com',
    'imapPassword'  => '123',
]]));

$services->set('imap', $imap);


// Redefine component with new config
$imap = new \roopz\imap\Imap(ArrayHelper::merge($defaultImapConfig, ['connection' => [
    'imapLogin'     => 'dfg@gmail.com',
    'imapPassword'  => '456',
]]));

$services->set('imap', $imap);      // If component definition with the same name already exist, it will be ovewritten.

当然,您可以使用类似的方式在Yii::$app中重新定义全局组件,但这是不好的做法。我建议创建单独的(本地)服务层,可以从控制器,模型等访问。

有关使用here找到的服务定位器的更多详细信息。