在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
}
...
Run Code Online (Sandbox Code Playgroud)
小智 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());
}
...
Run Code Online (Sandbox Code Playgroud)
$this->Utilities 现在可以在我的整个shell类中使用.
如果您认为必须在shell中加载组件,那么您的应用程序架构设计得很糟糕,应该进行重构.
从技术上讲它是可能的,但它没有意义,可以有非常讨厌的副作用.组件不会在请求范围之外运行.组件被认为在HTTP请求和控制器的范围内运行 - 这显然不存在于shell中.
为什么XML操作必须进入组件?这只是错误的地方.这应该进入一个类,App\Utility\XmlUtils例如,对请求和控制器都没有依赖性.
逻辑正确地解耦,然后可以在需要它的其他地方使用.此外,如果您获得传入的XML,那么执行此操作的正确位置(通过使用您的实用程序类)将位于模型层内,而不是控制器.
因为你违背了这两个原则.
请注意,其中一些可能会鼓励不良做法.我还没有检查过它们.
如果您尝试从 shell 访问自定义 XyzComponent,那么您可能在那里拥有常用功能。常用功能(也可以从 shell 访问)的正确位置在/Lib/.
您可以将旧的 XyzComponent 类从/Controller/Component/XyzComponent.php到/Lib/Xyz/Xyz.php。(您应该重命名您的类以删除“Component”后缀,例如,“XyzComponent”变为“Xyz”。)
要访问新位置,请在控制器中从class::$components阵列中删除“Xyz” 。在控制器文件的顶部,添加
App::uses('Xyz', 'Xyz'); // that's ('ClassName', 'folder_under_/Lib/')
Run Code Online (Sandbox Code Playgroud)
现在你只需要实例化这个类。在您的方法中,您可以$this->Xyz = new Xyz();使用相同的代码,但也可以从您的 Shell 访问它。
小智 6
我假设您有一个名为YourComponent的组件:
<?php
App::uses('Component', 'Controller');
class YourComponent extends Component {
public function testMe() {
return 'success';
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)
<?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();
}
}
Run Code Online (Sandbox Code Playgroud)