如何在控制台/ shell中加载组件

时间:2015-02-14 00:30:00

标签: cakephp

在CakePHP中,如何在shell中加载组件?

要在控制器中使用组件,请在名为$ components的属性中包含一组组件。这对我的壳牌不起作用。文档中没有提供“即时”加载。

class MakePdfsShell extends Shell {
    public $components = array('Document'); // <- this doesn't work
    public function main()
    {
        $this->Document = $this->Components->load('Document'); // <- this doesnt work either
        $this->Document->generate(); // <- this is what I want to do
    }
    ...

5 个答案:

答案 0 :(得分:9)

我在一些控制器中使用了一些xml实用程序。其中一个控制器通过蛋糕控制台启动繁重的任务,以便它可以通过PHP CLI在后台安静地运行,同时用户的请求立即完成(任务完成后,它会将结果通过电子邮件发送给用户)

xml实用程序非常通用,可以在控制器和shell中使用,对于应用程序来说太具体了,无法保证它们的供应商状态。 Lib文件夹提供的解决方案无效,因为CakePhp v3似乎没有Lib文件夹。

花了一些时间后,我设法将我的控制器组件加载到shell任务。以下是:

namespace App\Shell;

use Cake\Console\Shell;

use Cake\Core\App;
use Cake\Controller\Component;
use Cake\Controller\ComponentRegistry;
use App\Controller\Component\XmlUtilitiesComponent;   // <- resides in your app's src/Controller/Component folder

class XmlCheckShell extends Shell
{

    public function initialize() {
        $this->Utilities = new XmlUtilitiesComponent(new ComponentRegistry());
    }

...

$this->Utilities现在可以在我的整个shell类中使用。

答案 1 :(得分:5)

你根本就没有。

如果您认为必须在shell中加载组件,那么您的应用程序架构设计糟糕且应该重构。

从技术上讲,这是可能的,但它没有意义,并且可能有非常讨厌的副作用。组件不会在请求范围之外运行。一个组件被认为是在HTTP请求和控制器的范围内运行 - 这显然不存在于shell中。

将东西放在正确的位置

为什么XML操作必须进入组件?这只是错误的地方。这应该进入一个类,例如App\Utility\XmlUtils,并且对请求和控制器都有 no 依赖关系。

逻辑正确地解耦,然后可以在需要它的其他地方使用。此外,如果您获得传入的XML,那么执行此操作的正确位置(通过使用您的实用程序类)将位于模型层内,而不是控制器。

您想了解分离关注和紧密耦合

因为你违背了这两个原则。

在询问之前搜索

您可能已经尝试搜索via Googleon SO您会找到其中一个:

请注意,其中一些可能会鼓励不良做法。我还没有检查过它们。

答案 2 :(得分:4)

如果您尝试从shell访问自定义XyzComponent,那么您可能在那里拥有通用的功能。通常有用的功能(也可以从shell访问)的正确位置在/Lib/

您可以将旧的XyzComponent类从/Controller/Component/XyzComponent.php移动到/Lib/Xyz/Xyz.php。 (您应该重命名您的班级以删除&#34;组件&#34;后缀,例如&#34; XyzComponent&#34;变为&#34; Xyz&#34 ;.)

要访问新位置,请在控制器中删除&#39; Xyz&#39;来自您的class::$components数组。在控制器文件的顶部,添加

App::uses('Xyz', 'Xyz'); // that's ('ClassName', 'folder_under_/Lib/')

现在您只需要实例化该类。在您的方法中,您可以$this->Xyz = new Xyz();现在您使用相同的代码,但也可以从您的Shell访问它。

答案 3 :(得分:4)

我假设您有一个名为 YourComponent 的组件:

<?php

App::uses('Component', 'Controller');

class YourComponent extends Component {

    public function testMe() {
        return 'success';
    }
}

- with cake 2。,您可以像这样加载您的组件

App::uses('ComponentCollection', 'Controller');
App::uses('YourComponent', 'Controller/Component');

class YourShell extends AppShell {

    public function startup() {
        $collection = new ComponentCollection();
        $this->yourComponent = $collection->load('Your');
    }

    public function main() {
        $this->yourComponent->testMe();
    }
}

- with cake 3。您可以像这样加载您的组件

<?php

namespace App\Shell;


use App\Controller\Component\YourComponent;
use Cake\Console\Shell;
use Cake\Controller\ComponentRegistry;

class YourShell extends Shell {

    public function initialize() {
        parent::initialize();
        $this->yourComponent = new YourComponent(new ComponentRegistry(), []);
    }

    public function main() {
        $pages = $this->yourComponent->testMe();
    }
}

答案 4 :(得分:-3)

// TestShell.php

class TestShell extends AppShell{

    public function test(){
        //to load a component in dis function
     App::import('Component', 'CsvImporter');
     $CsvImporter = new CsvImporterComponent();
     $data = $CsvImporter->get();
    }

}

// CsvImporterComponent.php

App::uses('Component', 'Controller');

class CsvImporterComponent extends Component {

    function get(){
    //your code
    }

}