CrossPHP
  • Namespace
  • Class
  • Download

Namespaces

  • Cross
    • Auth
    • Cache
      • Driver
      • Request
    • Core
    • DB
      • Connecter
      • Drivers
      • SQLAssembler
    • Exception
    • Http
    • I
    • Lib
      • Document
    • Module
    • MVC
    • Runtime
  • None

Classes

  • Cross\Auth\CookieAuth
  • Cross\Auth\SessionAuth
  • Cross\Cache\Driver\FileCacheDriver
  • Cross\Cache\Driver\MemcacheDriver
  • Cross\Cache\Driver\RedisDriver
  • Cross\Cache\Request\FileCache
  • Cross\Cache\Request\Memcache
  • Cross\Cache\Request\RedisCache
  • Cross\Cache\RequestCache
  • Cross\Core\Annotate
  • Cross\Core\Application
  • Cross\Core\ArrayMap
  • Cross\Core\Config
  • Cross\Core\CrossArray
  • Cross\Core\Delegate
  • Cross\Core\FrameBase
  • Cross\Core\Helper
  • Cross\Core\HttpAuth
  • Cross\Core\Loader
  • Cross\Core\Rest
  • Cross\Core\Router
  • Cross\DB\Connecter\BaseConnecter
  • Cross\DB\Connecter\MySQLConnecter
  • Cross\DB\Connecter\PgSQLConnecter
  • Cross\DB\Connecter\SQLiteConnecter
  • Cross\DB\DBFactory
  • Cross\DB\Drivers\CouchDriver
  • Cross\DB\Drivers\MongoDriver
  • Cross\DB\Drivers\PDOSqlDriver
  • Cross\DB\SQLAssembler\MySQLAssembler
  • Cross\DB\SQLAssembler\PgSQLAssembler
  • Cross\DB\SQLAssembler\SQLAssembler
  • Cross\DB\SQLAssembler\SQLiteAssembler
  • Cross\Http\Request
  • Cross\Http\Response
  • Cross\Lib\Array2XML
  • Cross\Lib\Document\CallTree
  • Cross\Lib\Document\CallTreeToHTML
  • Cross\Lib\Document\HTML
  • Cross\Lib\StringToPHPStream
  • Cross\Module\SQLModule
  • Cross\MVC\Controller
  • Cross\MVC\Module
  • Cross\MVC\View
  • Cross\Runtime\ClosureContainer

Interfaces

  • Cross\I\CacheInterface
  • Cross\I\HttpAuthInterface
  • Cross\I\PDOConnecter
  • Cross\I\RequestCacheInterface
  • Cross\I\RouterInterface
  • Cross\I\SqlInterface

Exceptions

  • Cross\Exception\CacheException
  • Cross\Exception\CoreException
  • Cross\Exception\CrossException
  • Cross\Exception\FrontException

Functions

  • ascLogo
  • line
  • tBody
  • th
  • tHead
  1 <?php
  2 /**
  3  * Cross - a micro PHP 5 framework
  4  *
  5  * @link        http://www.crossphp.com
  6  * @license     MIT License
  7  */
  8 namespace Cross\Core;
  9 
 10 use Cross\Exception\CoreException;
 11 use Cross\Exception\FrontException;
 12 use Cross\Runtime\ClosureContainer;
 13 use Cross\I\RouterInterface;
 14 use Cross\Http\Response;
 15 use Cross\Http\Request;
 16 use Closure;
 17 
 18 //检查环境版本
 19 version_compare(PHP_VERSION, '5.3.6', '>=') or die('requires PHP 5.3.6!');
 20 
 21 //外部定义的项目路径
 22 defined('PROJECT_PATH') or die('undefined PROJECT_PATH');
 23 
 24 //项目路径
 25 define('PROJECT_REAL_PATH', rtrim(PROJECT_PATH, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR);
 26 
 27 //项目APP路径
 28 define('APP_PATH_DIR', PROJECT_REAL_PATH . 'app' . DIRECTORY_SEPARATOR);
 29 
 30 //框架路径
 31 define('CP_PATH', dirname(__DIR__) . DIRECTORY_SEPARATOR);
 32 
 33 /**
 34  * @author wonli <wonli@live.com>
 35  * Class Delegate
 36  * @package Cross\Core
 37  */
 38 class Delegate
 39 {
 40     /**
 41      * @var string
 42      */
 43     public $app_name;
 44 
 45     /**
 46      * @var Application
 47      */
 48     private $app;
 49 
 50     /**
 51      * @var Router
 52      */
 53     private $router;
 54 
 55     /**
 56      * @var Config
 57      */
 58     private $config;
 59 
 60     /**
 61      * @var Loader
 62      */
 63     private $loader;
 64 
 65     /**
 66      * 运行时配置 (高于配置文件)
 67      *
 68      * @var array
 69      */
 70     private $runtime_config;
 71 
 72     /**
 73      * 运行时匿名函数容器
 74      *
 75      * @var ClosureContainer
 76      */
 77     private $action_container;
 78 
 79     /**
 80      * Delegate的实例
 81      *
 82      * @var Delegate
 83      */
 84     private static $instance;
 85 
 86     /**
 87      * 初始化框架
 88      *
 89      * @param string $app_name 要加载的app名称
 90      * @param array $runtime_config 运行时指定的配置
 91      * @throws CoreException
 92      * @throws FrontException
 93      */
 94     private function __construct($app_name, array $runtime_config)
 95     {
 96         $this->app_name = $app_name;
 97         $this->runtime_config = $runtime_config;
 98 
 99         $this->loader = Loader::init();
100         $this->config = self::initConfig($app_name, $runtime_config);
101 
102         $this->registerNamespace();
103         $this->action_container = new ClosureContainer();
104         $this->router = new Router($this);
105         $this->app = new Application($app_name, $this);
106     }
107 
108     /**
109      * 当前框架版本号
110      *
111      * @return string
112      */
113     static function getVersion()
114     {
115         return '1.6.1';
116     }
117 
118     /**
119      * 实例化框架
120      *
121      * @param string $app_name app名称
122      * @param array $runtime_config 运行时加载的设置
123      * @return self
124      * @throws CoreException
125      * @throws FrontException
126      */
127     static function loadApp($app_name, array $runtime_config = array())
128     {
129         if (!isset(self::$instance[$app_name])) {
130             self::$instance[$app_name] = new Delegate($app_name, $runtime_config);
131         }
132 
133         return self::$instance[$app_name];
134     }
135 
136     /**
137      * 直接调用控制器类中的方法
138      * <pre>
139      * 忽略路由别名相关配置和URL参数, @cp_params注释不生效
140      * </pre>
141      *
142      * @param string $controller "控制器:方法"
143      * @param string|array $args 参数
144      * @param bool $return_content 是输出还是直接返回结果
145      * @return array|mixed|string
146      * @throws CoreException
147      */
148     public function get($controller, $args = array(), $return_content = false)
149     {
150         return $this->app->dispatcher($controller, $args, $return_content);
151     }
152 
153     /**
154      * 解析url并运行
155      *
156      * @throws CoreException
157      * @throws FrontException
158      */
159     public function run()
160     {
161         $this->app->dispatcher($this->router->getRouter());
162     }
163 
164     /**
165      * 自定义router运行
166      *
167      * @param RouterInterface $router
168      * @throws CoreException
169      */
170     public function rRun(RouterInterface $router)
171     {
172         $this->app->dispatcher($router);
173     }
174 
175     /**
176      * 处理REST风格的请求
177      * <pre>
178      * $app = Cross\Core\Delegate::loadApp('web')->rest();
179      *
180      * $app->get("/", function(){
181      *    echo "hello";
182      * });
183      * </pre>
184      *
185      * @return Rest
186      * @throws CoreException
187      */
188     public function rest()
189     {
190         return Rest::getInstance($this);
191     }
192 
193     /**
194      * CLI模式下运行方式
195      * <pre>
196      * 在命令行模式下的调用方法如下:
197      * php /path/index.php controller:action params1=value params2=value ... $paramsN=value
198      * 第一个参数用来指定要调用的控制器和方法
199      * 格式如下:
200      *      控制器名称:方法名称
201      *
202      * 在控制器:方法后加空格来指定参数,格式如下:
203      *      参数1=值, 参数2=值, ... 参数N=值
204      *
205      * 控制器中调用$this->params来获取并处理参数
206      * </pre>
207      *
208      * @param int|bool $run_argc
209      * @param array|bool $run_argv
210      * @throws CoreException
211      */
212     public function cliRun($run_argc = false, $run_argv = false)
213     {
214         if (PHP_SAPI !== 'cli') {
215             die('This app is only running from CLI');
216         }
217 
218         if (false === $run_argc) {
219             $run_argc = $_SERVER['argc'];
220         }
221 
222         if (false === $run_argv) {
223             $run_argv = $_SERVER['argv'];
224         }
225 
226         if ($run_argc == 1) {
227             die('Please specify params: controller:action params');
228         }
229 
230         //去掉argv中的第一个参数
231         array_shift($run_argv);
232         $controller = array_shift($run_argv);
233 
234         //使用get调用指定的控制器和方法,并传递参数
235         $this->get($controller, $run_argv);
236     }
237 
238     /**
239      * 注册运行时匿名函数
240      *
241      * @param string $name
242      * @param Closure $f
243      * @return $this
244      */
245     function on($name, Closure $f)
246     {
247         $this->action_container->add($name, $f);
248         return $this;
249     }
250 
251     /**
252      * application对象
253      *
254      * @return Application
255      */
256     function getApplication()
257     {
258         return $this->app;
259     }
260 
261     /**
262      * app配置对象
263      *
264      * @return Config
265      */
266     function getConfig()
267     {
268         return $this->config;
269     }
270 
271     /**
272      * Loader
273      *
274      * @return Loader
275      */
276     function getLoader()
277     {
278         return $this->loader;
279     }
280 
281     /**
282      * 获取运行时指定的配置
283      *
284      * @return array
285      */
286     function getRuntimeConfig()
287     {
288         return $this->runtime_config;
289     }
290 
291     /**
292      * @return Router
293      */
294     function getRouter()
295     {
296         return $this->router;
297     }
298 
299     /**
300      * 返回当前app的aspect容器实例
301      *
302      * @return ClosureContainer
303      */
304     function getClosureContainer()
305     {
306         return $this->action_container;
307     }
308 
309     /**
310      * @return Request
311      */
312     function getRequest()
313     {
314         return Request::getInstance();
315     }
316 
317     /**
318      * @return Response
319      */
320     function getResponse()
321     {
322         return Response::getInstance();
323     }
324 
325     /**
326      * 初始化App配置
327      *
328      * @param string $app_name
329      * @param array $runtime_config
330      * @return Config
331      * @throws FrontException
332      * @throws CoreException
333      */
334     private static function initConfig($app_name, array $runtime_config)
335     {
336         $request = Request::getInstance();
337         $host = $request->getHostInfo();
338         $index_name = $request->getIndexName();
339 
340         $request_url = $request->getBaseUrl();
341         $script_path = $request->getScriptFilePath();
342 
343         //app名称和路径
344         $runtime_config['app'] = array(
345             'name' => $app_name,
346             'path' => APP_PATH_DIR . $app_name . DIRECTORY_SEPARATOR
347         );
348 
349         $env_config = array(
350             //url相关设置
351             'url' => array(
352                 'host' => $host,
353                 'index' => $index_name,
354                 'request' => $request_url,
355                 'full_request' => $host . $request_url
356             ),
357 
358             //配置和缓存的绝对路径
359             'path' => array(
360                 'cache' => PROJECT_REAL_PATH . 'cache' . DIRECTORY_SEPARATOR,
361                 'config' => PROJECT_REAL_PATH . 'config' . DIRECTORY_SEPARATOR,
362                 'script' => $script_path . DIRECTORY_SEPARATOR,
363             ),
364 
365             //静态文件url和绝对路径
366             'static' => array(
367                 'url' => $host . $request_url . '/static/',
368                 'path' => $script_path . DIRECTORY_SEPARATOR . 'static' . DIRECTORY_SEPARATOR
369             )
370         );
371 
372         foreach ($env_config as $key => $value) {
373             if (isset($runtime_config[$key]) && is_array($runtime_config[$key])) {
374                 $runtime_config[$key] = array_merge($value, $runtime_config[$key]);
375             } elseif (!isset($runtime_config[$key])) {
376                 $runtime_config[$key] = $value;
377             }
378         }
379 
380         return Config::load(APP_PATH_DIR . $app_name . DIRECTORY_SEPARATOR . 'init.php')->combine($runtime_config);
381     }
382 
383     /**
384      * 批量注册命名空间
385      *
386      * @throws CoreException
387      */
388     private function registerNamespace()
389     {
390         $namespaceConfig = $this->config->get('namespace');
391         if (!empty($namespaceConfig)) {
392             foreach ($namespaceConfig as $namespace => $libDir) {
393                 $libDir = PROJECT_REAL_PATH . $libDir;
394                 if (file_exists($libDir)) {
395                     $this->loader->registerNamespace($namespace, $libDir);
396                 } else {
397                     throw new CoreException("Register namespace {$namespace} failed");
398                 }
399             }
400         }
401     }
402 }
403 
CrossPHP API documentation generated by ApiGen