CrossPHP


MMVC,REST,Layer,PSR,composer,注释配置,智能路由别名

程序需求及简介

PHP5.3以上版本。支持PSR,composer,MMVC,REST, 注释配置。 Layer布局支持,更换模板更简单。路由别名(先写代码,后定义,比如rul:/Controller/Action/5,可以通过别名指定为:/d/5)。 全局的异常处理系统及错误展示,在开发中可以快速定位到具体的代码行数。默认使用PDO, 更安全, 更简单易用的MySQL支持。

获取框架

http://www.crossphp.com/download下载框架完整版并解压到本地目录。

打开浏览器输入地址http://domain/htdocs/web访问默认页面, cp的项目结构请点此链接查看

入口文件

默认页面的入口文件在htdocs/web/index.php

require __DIR__ . '/../../crossboot.php';
Cross\Core\Delegate::loadApp('web')->run();

cp不同于其他框架, 入口文件也是处理逻辑很重要的一部分, 通过入口文件您可以灵活控制程序入口:

require __DIR__ . '/../../crossboot.php';
//使用运行时配置
$web = Cross\Core\Delegate::loadApp('web', array(
    'myConfig' => array(
        'name' => 'ideaa',
    )
));

//获取配置
$config = $web->getConfig();

//获取request对象
$request = $web->getRequest();

//response对象
$response = $web->getResponse();

//注册一个命名空间
$loader = $web->getLoader();
$loader->registerNamespace('abc', PROJECT_REAL_PATH . 'lib/abc');

$web->on('dispatcher', function() use ($web) {
    //当程序运行到dispatcher时, 调用此匿名函数
});

$web->on('parseAnnotate', function($annotate, $config) {
    //当运行到解析注释配置时, 调用此匿名函数
});

$web->on('cpCache', function($config){
    //初始化请求缓存时调用此函数
});

try {
    //使用默认路由
    $web->run();
} catch (Exception $e) {
    //正式环境下捕获运行过程中的异常信息
    //调用指定的控制器处理异常信息
    $web->get('error');
}

在cp中, 你也可以不使用默认路由, 自己分析url, 使用get()调用指定的控制器和方法

require __DIR__ . '/../../crossboot.php';	
$web = Cross\Core\Delegate::loadApp('web');

//例如url为:http://localhost/?controller=main&action=index&a=b&b=2&c=3
$request = $_GET + $_POST;
$controller = !empty($request['controller'])?$request['controller']:'defaultController';
$action = !empty($request['action'])?$request['action']:'defaultAction';
unset($request['controller'], $request['action']);

try {
    //调用指定控制器和方法并传参
    $web->get("{$controller}:{$action}", $request);
} catch (Exception $e) {
    //正式环境下捕获运行过程中的异常信息
    //调用指定的控制器处理异常信息
    $web->get('error');
}

除此之外在入口文件中, 你还可以定义使用REST风格的路由

require __DIR__ . '/../../crossboot.php';	
//使用运行时配置
$web = Cross\Core\Delegate::loadApp('web');

$rest = $web->rest();
$rest->get('/', function(){
    echo 'hello';
});

$rest->get('/hello/{:name}', function($name){
    echo "hello {$name}";
});

//当所有规则匹配失败时转由默认路由处理
$rest->on('mismatching', function() use($web) {
    $web->run();
});

try {
    $rest->run();
} catch (Exception $e) {
    //正式环境下捕获运行过程中的异常信息
    //调用指定的控制器处理异常信息
    $web->get('error');
}

为了避免在入口写过多的重复代码, 增加了引导文件crossboot.php, 在引导文件中定义项目了路径, 引入框架启动文件, 一些全局设置等

//框架依赖的唯一常量
define('PROJECT_PATH', __DIR__);

//项目中的常量在这里定义
define('COOKIE_DOMAIN', '');
define('TIME', time());

//一些全局配置
date_default_timezone_set('Asia/Chongqing');
header("Content-Type:text/html; charset=utf-8");

//使用composer install来进行安装
//require PROJECT_PATH . '/vendor/autoload.php';

//使用压缩包安装时候,需要引入框架根目录下的boot.php文件
require PROJECT_PATH . '/framework/boot.php';

//这里还可以载入一些你经常使用的函数库

你还可以在引导文件中定义你项目所需常量, 载入你的类和函数库等

默认控制器

在入口处通过loadApp()指定加载的app名称, 此时默认控制器文件位于app/web/controllers目录下的Main.php文件

namespace app\web\controllers;

use Cross\Core\Delegate;

class Main extends Web
{
    /**
     * 默认控制器
     */
    function index()
    {
        $this->data ['action'] = __FUNCTION__;
        $this->data ['version'] = Delegate::getVersion();

        $this->display($this->data);
    }

    function hi()
    {
        echo 'hi';
    }
}

在控制器中新增hi()方法, 通过浏览器地址http://domain/htdocs/web/?/main/hi访问控制器, 在控制器中使用modules 来使用数据库

视图控制器

cpMVC中的V对应视图控制器, 视图控制器与控制器默认一一对应, 与默认控制器对应的是app/web/views/MainView.php类. 在控制器中使用

$this->display($this->data);

来调用默认的视图控制器, 视图控制器中定义同名方法来处理输出, 在方法内部可以调用指定模板, 设置页面title等操作.

namespace app\web\views;

/**
 * @Auth: wonli <wonli@live.com>
 * Class MainView
 * @package app\web\views
 */
class MainView extends WebView
{
    /**
     * 默认视图控制器
     *
     * @param array $data
     */
    function index($data = array())
    {
        $this->renderTpl('main/index', $data);
    }
}

这里调用 $this->renderTpl() 载入的模板. templates/{main/index}.tpl.php, 并将$data传递到模板中, 这里仅需传入模板文件定义的目录和文件名前缀即可, 默认模板路径可以在app配置文件中指定. 模板文件后缀可以在通过类的成员属性$tpl_file_ext_name覆盖.

<div class="jumbotron">
    <div class="container">
        <h1>Hello World</h1>
        <p>OOP,MMVC,Layer,Annotate,双向智能别名,PSR,Composer</p>
        <p>
            <a class="btn btn-primary btn-lg" href="http://document.crossphp.com" target="_blank" role="button">
                查看文档 »
            </a>
        </p>
    </div>
</div>

<div class="container">
    <a href="http://www.crossphp.com/" target="_blank" title="crossphp.com">CrossPHP</a>
    <?php printf('v%s', $data['version']); ?>
</div>

在模板中调用$data即可访问视图控制器中传递过来的具体数据, 视图控制器中的其他方法请点此链接查看

在模板中, 除了调用$data访问数据外, 你还可以直接调用视图控制器中定义的方法来扩展模板系统. 查看自定义方法

如果app只需提供API, 不需要渲染模板, 也不必为每个控制器创建对应的视图控制器, 只需要在控制器的父类中指定view属性即可, 具体可以查看app/api/controllers/Api.php中的构造方法

修改数据配置

使用admin前需要修改数据库配置config/db.config.php.

$mysql_link = array(
    'host' => '127.0.0.1',
    'port' => '3306',
    'user' => 'root',
    'pass' => '123456',
    'prefix' => '',
    'charset' => 'utf8',
);

/**
 * redis
 */
$redis_link = array(
    'host' => '127.0.0.1',
    'port' => 6379,
    'pass' => '',
    'timeout' => 2.5
);

#默认数据库配置
$db = $mysql_link;
$db['name'] = 'test';

return array(
    'mysql' => array(
        'db' => $db,
    )
);

并导入sql/admin/back.sql文件到指定的数据库。然后通过浏览器访问http://domain/htdocs/admin 就可以进入到默认集成的管理后台了. skeleton-admin文档

后台入口

后台入口文件在htdocs/admin/index.php

session_start();
require __DIR__ . '/../../crossboot.php';

//登录成功后$_SESSION['u']会被赋值
//如果$_SESSION['u']为空,访问任何页面都只会输出登录界面
if (empty($_SESSION['u'])) {
    Cross\Core\Delegate::loadApp('admin')->get('Main:login');
} else {
    Cross\Core\Delegate::loadApp('admin')->run();
}

在后台页面入口中, 我们用简单的方法实现了登录认证, 用到了

Cross\Core\Delegate::loadApp('admin')->get('Main:login');

通过Delegate::get()方法, 我们可以轻易的与第三方系统整合

REST模式

除了传统的MVC模式外, CP还支持REST模式

关于skeleton的更多介绍可以阅读skeleton文档