在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
}
...
答案 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 Google或on 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';
}
}
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();
}
}
<?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
}
}