很多情况下,需要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