如何使用 zf-console 执行 Zend Framework 3 操作?
How to execute Zend Framework 3 action with zf-console?
我想用 zf-console 执行 ZF3 操作。
我可以使用 zend-mvc-console 模块做到这一点,它工作正常。
例如。
Application/config/module.config.php:
'console' => [
'router' => [
'routes' => [
'cronroute' => [
'options' => [
'route' => 'sync',
'defaults' => [
'controller' => Controller\ConsoleController::class,
'action' => 'syncEvents'
]
]
]
]
]
],
Application/src/Controller/ConsoleController.php
class ConsoleController extends AbstractActionController
{
/**
* Entity manager.
* @var Doctrine\ORM\EntityManager
*/
private $entityManager;
/**
* User Manager
* @var Application\Service\UserManager
*/
private $userManager;
/**
* Constructor.
*/
public function __construct($entityManager, $userManager)
{
$this->entityManager = $entityManager;
$this->userManager = $userManager;
}
public function syncAction()
{
$response = $this->userManager->syncUserInfo();
return $response ? 'Sync Success' : 'Failed to sync';
}
}
但是它说它将被弃用:
https://zendframework.github.io/zend-mvc-console/intro/#deprecated
建议使用 zfcampus 的 zf-console:
https://github.com/zfcampus/zf-console
但是我找不到执行控制器操作或使用我的构建服务(如 UserManager)的方法。
有构建 Zend 应用程序和检索服务管理器的示例:
use Zend\Console\Console;
use Zend\Console\ColorInterface as Color;
use ZF\Console\Application;
use ZF\Console\Dispatcher;
chdir(dirname(__DIR__));
require __DIR__ . '/../vendor/autoload.php'; // Composer autoloader
$application = Zend\Mvc\Application::init(require 'config/application.config.php');
$services = $application->getServiceManager();
$buildModel = $services->get('My\BuildModel');
有没有办法用它执行控制器操作?或者我可以加载我的 UserManager 服务吗?
我试图让我的 UserManager:
$buildModel = $services->get('Application\Service\UserManager');
但是接收错误:
PHP Fatal error: Uncaught exception 'Zend\ServiceManager\Exception\ServiceNotFoundException' with message 'Unable to resolve service "Application\Service\UserManager" to a factory; are you certain you provided it during configuration?' in /var/www/html/vendor/zendframework/zend-servicemanager/src/ServiceManager.php:687
zend-mvc-console 模块似乎处于弃用的边缘。就像你一样,我正在尝试实施 zfcampus/zf-console。由于 mvc-console 模块似乎(几乎)已弃用,我建议您使用不同于 (mvc) 控制器的东西来进行控制台工作。我使用了可以处理调用的 class(以 zf-console 期望的方式)。
这是我为我的项目制作的虚拟示例;
这是在命令行调用的脚本:
use Zend\Console\Console;
use Zend\ServiceManager\ServiceManager;
use Zend\Stdlib\ArrayUtils;
use Zend\Stdlib\Glob;
use ZF\Console\Application;
use ZF\Console\Dispatcher;
require_once __DIR__ . '/vendor/autoload.php'; // Composer autoloader
$configuration = [];
foreach (Glob::glob('config/{{*}}{{,*.local}}.php', Glob::GLOB_BRACE) as $file) {
$configuration = ArrayUtils::merge($configuration, include $file);
}
// Prepare the service manager
$smConfig = isset($config['service_manager']) ? $configuration['service_manager'] : [];
$smConfig = new \Zend\Mvc\Service\ServiceManagerConfig($smConfig);
$serviceManager = new ServiceManager();
$smConfig->configureServiceManager($serviceManager);
$serviceManager->setService('ApplicationConfig', $configuration);
// Load modules
$serviceManager->get('ModuleManager')->loadModules();
$routes = [
[
'name' => 'dumb',
'route' => '[--foo=]',
'description' => 'Some really cool feature',
'short_description' => 'Cool feature',
'options_descriptions' => [
'foo' => 'Lorem Ipsum',
],
'defaults' => [
'foo' => 'bar',
],
'handler' => function($route, $console) use ($serviceManager) {
$handler = new \Application\Command\DumbCommand();
return $handler($route, $console);
}
],
];
$config = $serviceManager->get('config');
$application = new Application(
$config['app'],
$config['version'],
$routes,
Console::getInstance(),
new Dispatcher()
);
$exit = $application->run();
exit($exit);
处理函数可以使用服务管理器将任何依赖项注入命令处理程序:
'handler' => function($route, $console) use ($serviceManager) {
/** @var \Doctrine\ORM\EntityManager $entityManager */
$entityManager = $serviceManager->get(\Doctrine\ORM\EntityManager::class);
/** @var mixed $repository */
$contactRepository = $entityManager->getRepository(\Application\Entity\Contact::class);
$handler = new \Application\Command\DumbCommand($contactRepository);
return $handler($route, $console);
}
命令class放在命令文件夹中,看起来像:
<?php
namespace Application\Command;
use Application\Entity\Contact;
use Application\Repository\ContactRepository;
use Zend\Console\Adapter\AdapterInterface;
use ZF\Console\Route;
class DumbCommand
{
/** @var ContactRepository */
private $contactRepository;
public function __construct($contactRepository)
{
$this->contactRepository = $contactRepository;
}
/**
* @param Route $route
* @param AdapterInterface $console
* @throws \Doctrine\ORM\ORMException
*/
public function __invoke(Route $route, AdapterInterface $console)
{
$console->writeLine('Bob was here');
foreach ($this->contactRepository->findAll() as $item) {
/** @var Contact $item */
$console->writeLine($item->getFirstName() . ' was here');
}
}
}
(
这是我的解决方案:
- 我将控制台命令路由添加到我的 module.config.php 文件
'console' => array(
'commands' => array(
array(
'name' => 'sendemail',
'handler' => PostCommand::class,
),
array(
'name' => 'sendsms',
'handler' => SmsTransferCommand::class,
)
)
),
- 我在 /public 中创建了一个 console.php(这将是 运行,带有启动 CLI 应用程序的参数)
use Zend\Console\Console;
use Zend\ServiceManager\ServiceManager;
use ZF\Console\Application;
use ZF\Console\Dispatcher;
chdir(dirname(__DIR__));
require_once 'vendor/autoload.php'; // Composer autoloader
// Prepare application and service manager
$appConfig = require 'config/application.config.php';
$application = Zend\Mvc\Application::init($appConfig);
$serviceManager = $application->getServiceManager();
// Load modules
$serviceManager->get('ModuleManager')->loadModules();
$config = $serviceManager->get('config');
$routes = $config['console']['commands']; // This depends on your structure, this is what I created (see. 1.)
$application = new Application(
$config['app'],
$config['version'],
$routes,
Console::getInstance(),
new Dispatcher($serviceManager) // Use service manager as a dependency injection container
);
$exit = $application->run();
exit($exit);
- 我将 CLI 命令处理程序分隔到 src/Command 文件夹中。我的 CLI 命令处理程序是我定义的服务,由工厂创建。 (这就是我使用服务管理器作为容器的原因 - 参见。2.)
[这里的serviceEmail是一个本地class变量,由这个命令处理程序的工厂加载。]
/**
* @param Route $route
* @param AdapterInterface $console
*
* @return int
*/
public function __invoke(Route $route, AdapterInterface $console)
{
$mails = $this->serviceEmail->sendMailFromDb();
$console->writeLine('Sent mails: ' . \count($mails), ColorInterface::WHITE, ColorInterface::RED);
return 0;
}
我想用 zf-console 执行 ZF3 操作。
我可以使用 zend-mvc-console 模块做到这一点,它工作正常。
例如。
Application/config/module.config.php:
'console' => [
'router' => [
'routes' => [
'cronroute' => [
'options' => [
'route' => 'sync',
'defaults' => [
'controller' => Controller\ConsoleController::class,
'action' => 'syncEvents'
]
]
]
]
]
],
Application/src/Controller/ConsoleController.php
class ConsoleController extends AbstractActionController
{
/**
* Entity manager.
* @var Doctrine\ORM\EntityManager
*/
private $entityManager;
/**
* User Manager
* @var Application\Service\UserManager
*/
private $userManager;
/**
* Constructor.
*/
public function __construct($entityManager, $userManager)
{
$this->entityManager = $entityManager;
$this->userManager = $userManager;
}
public function syncAction()
{
$response = $this->userManager->syncUserInfo();
return $response ? 'Sync Success' : 'Failed to sync';
}
}
但是它说它将被弃用:
https://zendframework.github.io/zend-mvc-console/intro/#deprecated
建议使用 zfcampus 的 zf-console:
https://github.com/zfcampus/zf-console
但是我找不到执行控制器操作或使用我的构建服务(如 UserManager)的方法。
有构建 Zend 应用程序和检索服务管理器的示例:
use Zend\Console\Console;
use Zend\Console\ColorInterface as Color;
use ZF\Console\Application;
use ZF\Console\Dispatcher;
chdir(dirname(__DIR__));
require __DIR__ . '/../vendor/autoload.php'; // Composer autoloader
$application = Zend\Mvc\Application::init(require 'config/application.config.php');
$services = $application->getServiceManager();
$buildModel = $services->get('My\BuildModel');
有没有办法用它执行控制器操作?或者我可以加载我的 UserManager 服务吗?
我试图让我的 UserManager:
$buildModel = $services->get('Application\Service\UserManager');
但是接收错误:
PHP Fatal error: Uncaught exception 'Zend\ServiceManager\Exception\ServiceNotFoundException' with message 'Unable to resolve service "Application\Service\UserManager" to a factory; are you certain you provided it during configuration?' in /var/www/html/vendor/zendframework/zend-servicemanager/src/ServiceManager.php:687
zend-mvc-console 模块似乎处于弃用的边缘。就像你一样,我正在尝试实施 zfcampus/zf-console。由于 mvc-console 模块似乎(几乎)已弃用,我建议您使用不同于 (mvc) 控制器的东西来进行控制台工作。我使用了可以处理调用的 class(以 zf-console 期望的方式)。
这是我为我的项目制作的虚拟示例;
这是在命令行调用的脚本:
use Zend\Console\Console;
use Zend\ServiceManager\ServiceManager;
use Zend\Stdlib\ArrayUtils;
use Zend\Stdlib\Glob;
use ZF\Console\Application;
use ZF\Console\Dispatcher;
require_once __DIR__ . '/vendor/autoload.php'; // Composer autoloader
$configuration = [];
foreach (Glob::glob('config/{{*}}{{,*.local}}.php', Glob::GLOB_BRACE) as $file) {
$configuration = ArrayUtils::merge($configuration, include $file);
}
// Prepare the service manager
$smConfig = isset($config['service_manager']) ? $configuration['service_manager'] : [];
$smConfig = new \Zend\Mvc\Service\ServiceManagerConfig($smConfig);
$serviceManager = new ServiceManager();
$smConfig->configureServiceManager($serviceManager);
$serviceManager->setService('ApplicationConfig', $configuration);
// Load modules
$serviceManager->get('ModuleManager')->loadModules();
$routes = [
[
'name' => 'dumb',
'route' => '[--foo=]',
'description' => 'Some really cool feature',
'short_description' => 'Cool feature',
'options_descriptions' => [
'foo' => 'Lorem Ipsum',
],
'defaults' => [
'foo' => 'bar',
],
'handler' => function($route, $console) use ($serviceManager) {
$handler = new \Application\Command\DumbCommand();
return $handler($route, $console);
}
],
];
$config = $serviceManager->get('config');
$application = new Application(
$config['app'],
$config['version'],
$routes,
Console::getInstance(),
new Dispatcher()
);
$exit = $application->run();
exit($exit);
处理函数可以使用服务管理器将任何依赖项注入命令处理程序:
'handler' => function($route, $console) use ($serviceManager) {
/** @var \Doctrine\ORM\EntityManager $entityManager */
$entityManager = $serviceManager->get(\Doctrine\ORM\EntityManager::class);
/** @var mixed $repository */
$contactRepository = $entityManager->getRepository(\Application\Entity\Contact::class);
$handler = new \Application\Command\DumbCommand($contactRepository);
return $handler($route, $console);
}
命令class放在命令文件夹中,看起来像:
<?php
namespace Application\Command;
use Application\Entity\Contact;
use Application\Repository\ContactRepository;
use Zend\Console\Adapter\AdapterInterface;
use ZF\Console\Route;
class DumbCommand
{
/** @var ContactRepository */
private $contactRepository;
public function __construct($contactRepository)
{
$this->contactRepository = $contactRepository;
}
/**
* @param Route $route
* @param AdapterInterface $console
* @throws \Doctrine\ORM\ORMException
*/
public function __invoke(Route $route, AdapterInterface $console)
{
$console->writeLine('Bob was here');
foreach ($this->contactRepository->findAll() as $item) {
/** @var Contact $item */
$console->writeLine($item->getFirstName() . ' was here');
}
}
}
(
这是我的解决方案:
- 我将控制台命令路由添加到我的 module.config.php 文件
'console' => array(
'commands' => array(
array(
'name' => 'sendemail',
'handler' => PostCommand::class,
),
array(
'name' => 'sendsms',
'handler' => SmsTransferCommand::class,
)
)
),
- 我在 /public 中创建了一个 console.php(这将是 运行,带有启动 CLI 应用程序的参数)
use Zend\Console\Console;
use Zend\ServiceManager\ServiceManager;
use ZF\Console\Application;
use ZF\Console\Dispatcher;
chdir(dirname(__DIR__));
require_once 'vendor/autoload.php'; // Composer autoloader
// Prepare application and service manager
$appConfig = require 'config/application.config.php';
$application = Zend\Mvc\Application::init($appConfig);
$serviceManager = $application->getServiceManager();
// Load modules
$serviceManager->get('ModuleManager')->loadModules();
$config = $serviceManager->get('config');
$routes = $config['console']['commands']; // This depends on your structure, this is what I created (see. 1.)
$application = new Application(
$config['app'],
$config['version'],
$routes,
Console::getInstance(),
new Dispatcher($serviceManager) // Use service manager as a dependency injection container
);
$exit = $application->run();
exit($exit);
- 我将 CLI 命令处理程序分隔到 src/Command 文件夹中。我的 CLI 命令处理程序是我定义的服务,由工厂创建。 (这就是我使用服务管理器作为容器的原因 - 参见。2.)
[这里的serviceEmail是一个本地class变量,由这个命令处理程序的工厂加载。]
/**
* @param Route $route
* @param AdapterInterface $console
*
* @return int
*/
public function __invoke(Route $route, AdapterInterface $console)
{
$mails = $this->serviceEmail->sendMailFromDb();
$console->writeLine('Sent mails: ' . \count($mails), ColorInterface::WHITE, ColorInterface::RED);
return 0;
}