atelierspierrot / mvc-fundamental

此软件包已被废弃且不再维护。未建议替代软件包。

一个易于使用和扩展的基本MVC系统。

dev-dev 2016-01-02 12:46 UTC

This package is not auto-updated.

Last update: 2024-03-02 15:08:51 UTC


README

Code Climate

一个易于使用且轻量级的MVC系统(默认依赖项约为1Mo),用于构建简单的Web应用。

安装

将此软件包添加到您的Composer需求中

"require": {
    "your/depdencies": "*",
    "atelierspierrot/mvc-fundamental": "dev-master"
}

请注意,此应用程序需要PHP版本5.4或更高。

使用方法

此软件包的目的是轻松快速地构建简单的Web应用,尽可能少地使用代码,并基于强大的基本架构。

默认系统嵌入所有基本的"MVC Web应用"对象:一个FrontController接收一个Request并询问Router要启动匹配特定Route的操作;操作通常是Controller的方法(但不一定)使用TemplateEngine生成输出;最后,FrontController返回一个Response

所有这些对象都是可重写的,但整个应用程序被设计为使用在\MVCFundamental\Interfaces命名空间中定义的一些API接口。您的自定义对象必须实现这些接口之一(一个良好的实践可能是扩展默认对象)。

快速入门

前控制器

入口点是创建一个包含一组选项(如果需要)的FrontController对象

$app = \MVCFundamental\FrontController::getInstance( array $options );

下面是选项部分的完整审查。

前控制器创建一个AppKernel实例来处理所有应用程序核心逻辑,如依赖容器、错误管理等。在前控制器本身定义了一些快捷别名,以便您可以使用以下方式检索依赖项:

$route = $app->get( 'router' );
$route = $app->set( 'request' , new Request );

一旦定义了配置和路由,只需调用run()方法即可让前控制器分发请求。

$app->run();

路由

您的实际应用程序逻辑位于您定义的路由和相应的回调中。内部Router将尝试根据请求和您的路由定义获取正确的回调,或者使用自动系统获取控制器的方法。

要定义路由,您可以使用

// direct callback
$app->addRoute('/my-route', function(){ return 'This is my route content';  })

// to use the front controller in your callback, write
$app->addRoute('/my-route', function() use ($app){ return 'This is my route content';  })

// a controller's method - this will try to call MycontrollerController::methodAction()
$app->addRoute('/my-route', array( 'mycontroller' , 'method' ))

// a method of the default controller if so
$app->addRoute('/my-route', 'method')

// a direct view file path - the path must exists
$app->addRoute('/my-route', 'my-view-file.html')

自动系统将尝试首先查找当前URI的前部分与array( controller , method )对应关系,或者作为默认控制器的简单method

  • 一个像/mycontroller/mymethod的路由将调用MycontrollerController::mymethodAction()
  • 一个像/myaction的路由将调用DefaultController::myactionAction()

对于每种类型的路由(已定义或自动),任何URI参数都将作为回调参数检索。例如,一个像/mycontroller/myaction/name/my-name的路由将调用MycontrollerController::myactionAction( 'my-name' )。您可以通过编写路由来“请求”保留来自路由的参数

// fetch a $name argument as a string (default)
$app->addRoute('/my-route/{name}', function($name){ 
    return "Hello $name";  
})

// fetch a $name argument as a string (default) and an ID argument as an integer
$app->addRoute('/my-route/{name}/{id:\d+}', function($name, $id){ 
    return "Hello $name, I got ID $id";  
})

由于回调的参数被重新排列,您可以根据需要以任何顺序编写它们

// arguments order usage does not matter
$app->addRoute('/my-route/{name}/{id:\d+}', function($id, $name){ 
    return "Hello $name, I got ID $id";  
})

如果需要,您始终可以使用以下参数

  • FrontController本身作为\MVCFundamental\Interfaces\FrontControllerInterface $arg
  • Request作为\MVCFundamental\Interfaces\RequestInterface $arg
  • Response作为\MVCFundamental\Interfaces\ResponseInterface $arg
  • TemplateEngine作为\MVCFundamental\Interfaces\TemplateEngineInterface $arg
  • 一个包含所有请求参数的data数组作为array $data
$app->addRoute('/my-route', 
    function( RequestInterface $arg1, ResponseInterface $arg2, FrontControllerInterface $app ){
        // ....
        return "Hello world";  
    }
)

回调返回

路由回调可以返回各种类型的东西

  • 一个简单的字符串,将被用作最终响应内容
  • 一个类似于 array ( string $view_file , array $view_parameters ) 的数组,用于调用带有 $view_parameters 参数的 $view_file 模板来构建最终内容
  • 一个完整的 \MVCFundamental\Interfaces\ResponseInterface 对象,用于替换实际响应。

在回调内部,你可以

  • 使用 render 函数渲染所需的任意数量的模板
$app->render( $view_file, array $params = array() ) : string
  • 通过调用布局来使用布局
$app->getNew('layout' , $view_file, array $options = array() ) : string
  • 使用 include 语句调用另一个控制器的函数
$app->callControllerAction( $controller = null, $action = null, array $arguments = array() ) : string
  • 使用 call 调用另一个路由
$app->callRoute( $route, array $arguments = array(), $method = 'get' ) : string
  • 使用重定向或转发到新的路由
$app->redirect( $route, $follow = false ) : string
  • 使用可选的可观察对象触发一个事件
$app->trigger( 'event.name' , object ) : void
  • 做任何其他 PHP 事情...

模板化系统

模板构建由 TemplateEngine 对象处理,该对象创建并聚合一些 TemplateLayout 实例。

$template_engine = $app->get( 'template_engine' ) : object

$new_template = $template_engine->getNewTemplate( $view_file , array $arguments ) : string

$new_layout = $template_engine->getNewLayout( $layout_file , array $arguments , array $options ) : string

模板引擎与两种对象协同工作:简单的 TemplateLayout。一个 Template 是一个包含参数的简单视图文件,而一个 Layout 是一种“全页”画布,处理预定义的页面部分,其 child(子),默认为一个特定的模板文件,并且可以在布局对象中重写。

事件管理

前端控制器被设计为能够注册和注销一些事件监听器并触发一个事件

// register a callback for an event
$app->on( event.name , callback )

// unregister a callaback
$app->off( event.name , callback )

// trigger an event
$app->trigger( event.name )

// trigger an event with an observable content
$app->trigger( event.name , observable_object )

错误 & 异常

该包在 \MVCFundamental\Exceptions 命名空间中包含了一套(相当)完整的自定义异常,并有一个内部处理程序来处理它们。尝试在抛出异常时始终使用这些对象之一。如果有疑问,可以使用快捷方式编写

$app->error( $message, $status = 500 )

应用选项

在构建自定义应用时,可以在构建前端控制器时定义以下选项

$options = array(

    // the application mode in "dev , test , production"
    // you can test it with $app->isMode('dev')
    'mode'                      => 'production',

    // all these will overwrite the default app objects
    'router'                    => '\MVCFundamental\Basic\Router',
    'route_item'                => '\MVCFundamental\Basic\Route',
    'response'                  => '\MVCFundamental\Basic\Response',
    'request'                   => '\MVCFundamental\Basic\Request',
    'template_engine'           => '\MVCFundamental\Basic\TemplateEngine',
    'template_item'             => '\MVCFundamental\Basic\Template',
    'layout_item'               => '\MVCFundamental\Basic\Layout',
    'locator'                   => '\MVCFundamental\Basic\Locator',
    'error_controller'          => '\MVCFundamental\Basic\ErrorController',
    'event_item'                => '\MVCFundamental\Basic\Event',
    'event_manager'             => '\MVCFundamental\Basic\EventManager',

    // this can be a callback to retrieve a controller class: function ($name) {}
    'controller_locator'        => null,

    // this can be a callback to retrieve a view file: function ($view_name) {}
    'view_file_locator'         => null,

    // the controllers name mask
    'controller_name_finder'    => '%sController',

    // the actions name mask
    'action_name_finder'        => '%sAction',

    // name of the default controller
    'default_controller_name'   => 'default',

    // name of the default controller's action
    'default_action_name'       => 'index',

    // the default template file
    // you can use it with $template_engine->renderDefault()
    'default_template'          => 'default.php',
    
    // the default layout view file
    'default_layout'            => 'layout.php',
    
    // the default layout class
    // you can use it with $template_engine->getgetDefaultLayout()
    'default_layout_class'      => '\MVCFundamental\Commons\DefaultLayout',

    // the default response content type
    'default_content_type'      => 'html',

    // the default response charset
    'default_charset'           => 'utf8',

    // the routes definition array
    'routes'                    => array(),

    // the errors messages
    '500_error_info'            => 'An internal error occurred :(',
    '404_error_info'            => 'The requested page cannot be found :(',
    '403_error_info'            => 'Access to this page is forbidden :(',

    // set to `true` to transform errors in exceptions (with app rendering)
    // this is automatically enabled in 'production' mode
    'convert_error_to_exception'=> false,

    // a temporary directory - the server user MUST have writing rights
    // this will fallback to a system temporary directory
    'temp_dir'                  => dirname($_SERVER['SCRIPT_FILENAME']).'/tmp/',

    // application logger system:
        // one of the \Library\Logger levels
    'minimum_log_level'         => null,
        // must implement PSR\Logger\Interface
    'app_logger'                => 'Library\Logger',

);

API

当系统启动时,以下所有必需组件都被创建并存储在容器中

  • **路由器**,它必须实现 \MVCFundamental\Interfaces\RouterInterface
  • **请求**,它必须实现 \MVCFundamental\Interfaces\RequestInterface
  • **响应**,它必须实现 \MVCFundamental\Interfaces\ResponseInterface
  • **模板引擎**,它必须实现 \MVCFundamental\Interfaces\TemplateEngineInterface
  • **定位器**,它必须实现 \MVCFundamental\Interfaces\LocatorInterface
  • **错误控制器**,它必须实现 \MVCFundamental\Interfaces\ErrorControllerInterface
  • **事件管理器**,它必须实现 \MVCFundamental\Interfaces\EventManagerInterface

此外,任何控制器都必须实现 \MVCFundamental\Interfaces\ControllerInterface,并且路由器必须处理一个实现 \MVCFundamental\Interfaces\RouteInterface 的路由集合。

模板引擎可以处理一些实现 \MVCFundamental\Interfaces\TemplateInterface模板 和一些实现 \MVCFundamental\Interfaces\LayoutInterface布局

事件管理器将创建并触发实现 \MVCFundamental\Interfaces\EventInterface 的事件。

它们都默认为 \MVCFundamental\Basic 命名空间中的实现,但你可以覆盖所有这些。

应用生命周期

运行时的生命周期完全由前端控制器处理,它调用内核的一些方法。基本的生命周期方案类似于

// creation of the front controller instance with options
$app = FrontController::getInstance( $options );
// this will create the AppKernel object and call:
$app->boot()
$kernel->boot()

// loading of app settings: routes or other options
$app
    ->addRoute( ... )
    ->on( event , ... )
;

// launch the app work
$app->run();
// this will distribute the request
$response = $app->handle( $request );
// then send the response
$app->send( $response );
// and finally terminate the runtime
$kernel->terminate();

作者 & 许可证

PHP MVC Fundamental

http://github.com/atelierspierrot/mvc-fundamental

版权 (c) 2013-2016 Pierre Cassat 和贡献者

根据 Apache 许可证 2.0 版本授权。

https://apache.ac.cn/licenses/LICENSE-2.0

Les Ateliers Pierrot - 巴黎,法国

http://www.ateliers-pierrot.fr/ - contact@ateliers-pierrot.fr