作为程序员一定要保持良好的睡眠,才能好编程

yaf 第六课 yaf cli模式运行

发布时间:2018-11-12

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