很多情况下,需要cli运行项目,我的项目采用yaf ,如何能够自动运行呢?
下面提供两种方法:
1、重新定义一个入口文件,修改相应的代码
操作步骤:复制 index.php 更名为 cli.php
cli.php
define('ENVIRONMENT', isset($_SERVER['HTTP_ENV']) ? $_SERVER['HTTP_ENV'] : 'product');
isset($_SERVER['HTTP_FETCH_DUMMY']) && define('FETCH_DUMMY', $_SERVER['HTTP_FETCH_DUMMY']);
define('APP_PATH', dirname(__FILE__));
define('CONFIGPATH', APP_PATH . '/app/configs/config.ini');
require_once APP_PATH . DIRECTORY_SEPARATOR . 'vendor/autoload.php';
if (!defined('CONFIGPATH')) echo 'No configpath defined, please define configpath and try again.';
switch (ENVIRONMENT) {
case 'develop':
error_reporting(-1);
ini_set('display_errors', 1);
ini_set('yaf.environ', 'develop');
break;
case 'testing':
case 'product':
ini_set('display_errors', 0);
break;
default:
header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
echo 'The application environment is not set correctly.';
exit(1); // EXIT_ERROR
}
//http://php.net/manual/zh/yaf-application.getconfig.php
//以下是cli是实现的逻辑
global $argc, $argv;
printf("=========notice=========\n 通过cli 传递到控制器方法中是一个数组 \n=========notice=========\n");
if ($argc > 1) {
$application = new Yaf_Application(CONFIGPATH);
$requstUri = $argv[1];
$requstUri = str_replace('request_uri=', '', $requstUri);
$requestUriArr = explode('/', trim($requstUri, '/'));
if (count($requestUriArr) < 3) {
printf("==================\n必须指定模块名\n==================");
}
$params = array_slice($argv, 2);
$moduleName = $requestUriArr[0];
$controllerClass = $requestUriArr[1];
$actionName = $requestUriArr[2];
$result = $application->execute([getInstance($controllerClass, $moduleName), $actionName . 'Action'], $params);
printf("\n=============result===============\n%s\n=============result===============\n",var_export($result,true));
}原 index.php
define('ENVIRONMENT', isset($_SERVER['HTTP_ENV']) ? $_SERVER['HTTP_ENV'] : 'product');
isset($_SERVER['HTTP_FETCH_DUMMY']) && define('FETCH_DUMMY', $_SERVER['HTTP_FETCH_DUMMY']);
define('APP_PATH', dirname(__FILE__));
define('CONFIGPATH', APP_PATH . '/app/configs/config.ini');
require_once APP_PATH . DIRECTORY_SEPARATOR . 'vendor/autoload.php';
if (!defined('CONFIGPATH')) echo 'No configpath defined, please define configpath and try again.';
switch (ENVIRONMENT) {
case 'develop':
error_reporting(-1);
ini_set('display_errors', 1);
ini_set('yaf.environ', 'develop');
break;
case 'testing':
case 'product':
ini_set('display_errors', 0);
break;
default:
header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
echo 'The application environment is not set correctly.';
exit(1); // EXIT_ERROR
}
//http://php.net/manual/zh/yaf-application.getconfig.php
$application = new Yaf_Application(CONFIGPATH);
$application->bootstrap()->run();两个文件对比下 就能发现差别。
这种方法,由于 execute 方法,对于后面的传参,需要一个一个传递,不能一次性传递一个键值对的参数,有这些弊端。
2、定义插件,去执行 (话说是最优美)
if ($request->isCli ()) {
global $argc, $argv;
if ($argc > 1) {
$module = '';
$uri = $argv [1];
if (preg_match ( '/^[^?]*%/i', $uri )) {
list ( $module, $uri ) = explode ( '%', $uri, 2 );
}
$module = strtolower ( $module );
$modules = Yaf_Application::app ()->getModules ();
if (in_array ( ucfirst ( $module ), $modules )) {
$request->setModuleName ( $module );
}
if (false === strpos ( $uri, '?' )) {
$args = array ();
} else {
list ( $uri, $args ) = explode ( '?', $uri, 2 );
parse_str ( $args, $args );
}
foreach ( $args as $k => $v ) {
$request->setParam ( $k, $v );
}
$request->setRequestUri ( $uri );
if ($request->isRouted () && ! empty ( $uri )) {
if (false !== strpos ( $uri, '/' )) {
list ( $controller, $action ) = explode ( '/', $uri );
$request->setActionName ( $action );
} else {
$controller = $uri;
}
$request->setControllerName ( ucfirst ( strtolower ( $controller ) ) );
}
}
}如果在插件中实现,routerStartup只需要$request->setRequestUri ( $uri ),如果是dispatchLoopStartup需要单独setControllerName和setActionName。
这里我采用了第一种方法来实现 重新定义 cli 入口文件,并修改相应的代码
相关思路来源于:http://shorturl.xiaosongit.com/uXn0P4