从命令行运行 Zend 框架操作
我想运行Zend框架操作以从命令行生成一些文件。这是否可能,我需要对使用 ZF 的现有 Web 项目进行多少更改?
谢谢!
我想运行Zend框架操作以从命令行生成一些文件。这是否可能,我需要对使用 ZF 的现有 Web 项目进行多少更改?
谢谢!
更新
虽然解决方案#1是可以的,但有时你想要一些更复杂的东西。特别是如果您期望有多个 CLI 脚本。如果你允许我,我会提出另一个解决方案。
首先,在你的Bootstrap中.php
protected function _initRouter ()
{
if (PHP_SAPI == 'cli')
{
$this->bootstrap ('frontcontroller');
$front = $this->getResource('frontcontroller');
$front->setRouter (new Application_Router_Cli ());
$front->setRequest (new Zend_Controller_Request_Simple ());
}
}
这种方法将剥夺默认路由器的调度控制,转而使用我们自己的路由器Application_Router_Cli。
顺便说一句,如果您在_initRoutes中为 Web 界面定义了自己的路由,则在命令行模式下可能需要中和它们。
protected function _initRoutes ()
{
$router = Zend_Controller_Front::getInstance ()->getRouter ();
if ($router instanceof Zend_Controller_Router_Rewrite)
{
// put your web-interface routes here, so they do not interfere
}
}
类Application_Router_Cli(我假设您已为应用程序前缀打开自动加载)可能如下所示:
class Application_Router_Cli extends Zend_Controller_Router_Abstract
{
public function route (Zend_Controller_Request_Abstract $dispatcher)
{
$getopt = new Zend_Console_Getopt (array ());
$arguments = $getopt->getRemainingArgs ();
if ($arguments)
{
$command = array_shift ($arguments);
if (! preg_match ('~\W~', $command))
{
$dispatcher->setControllerName ($command);
$dispatcher->setActionName ('cli');
unset ($_SERVER ['argv'] [1]);
return $dispatcher;
}
echo "Invalid command.\n", exit;
}
echo "No command given.\n", exit;
}
public function assemble ($userParams, $name = null, $reset = false, $encode = true)
{
echo "Not implemented\n", exit;
}
}
现在,您可以通过执行以下命令来运行应用程序
php index.php backup
在这种情况下,将调用 BackupController 控制器中的 cliAction 方法。
class BackupController extends Zend_Controller_Action
{
function cliAction ()
{
print "I'm here.\n";
}
}
您甚至可以继续修改Application_Router_Cli类,以便不是每次都执行“cli”操作,而是用户通过附加参数选择的内容。
最后一件事。为命令行界面定义自定义错误处理程序,这样您就不会在屏幕上看到任何html代码
在 Bootstrap 中.php
protected function _initError ()
{
$error = $frontcontroller->getPlugin ('Zend_Controller_Plugin_ErrorHandler');
$error->setErrorHandlerController ('index');
if (PHP_SAPI == 'cli')
{
$error->setErrorHandlerController ('error');
$error->setErrorHandlerAction ('cli');
}
}
在错误控制器中.php
function cliAction ()
{
$this->_helper->viewRenderer->setNoRender (true);
foreach ($this->_getParam ('error_handler') as $error)
{
if ($error instanceof Exception)
{
print $error->getMessage () . "\n";
}
}
}
这实际上比你想象的要容易得多。引导/应用程序组件和现有配置可以与 CLI 脚本一起重用,同时避免在 HTTP 请求中调用的 MVC 堆栈和不必要的权重。这是不使用 wget 的一个优点。
像启动公共索引一样启动脚本.php:
<?php
// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH',
realpath(dirname(__FILE__) . '/../application'));
// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV',
(getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV')
: 'production'));
require_once 'Zend/Application.php';
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/config.php'
);
//only load resources we need for script, in this case db and mail
$application->getBootstrap()->bootstrap(array('db', 'mail'));
然后,您可以继续使用采埃孚资源,就像在 MVC 应用程序中一样:
$db = $application->getBootstrap()->getResource('db');
$row = $db->fetchRow('SELECT * FROM something');
如果您希望向 CLI 脚本添加可配置的参数,请查看Zend_Console_Getopt
如果发现有在 MVC 应用程序中调用的通用代码,请考虑将其包装在对象中,并从 MVC 和命令行应用程序调用该对象的方法。这是一般的良好做法。