当前位置: 代码迷 >> 综合 >> Flight 一个可扩展的PHP微框架
  详细解决方案

Flight 一个可扩展的PHP微框架

热度:52   发布时间:2023-12-21 12:39:00.0

用户指南


路由

路由在 Flight 中是通过与一个回调函数匹配的URL模式。

Flight::route('/', function(){echo 'hello world!';});

可调用的回调可以是任何对象。所以你可以使用常规的功能:

function hello(){echo 'hello world!';}Flight::route('/', 'hello');

或者是一个类方法:

class Greeting {public static function hello() {echo 'hello world!';}}Flight::route('/', array('Greeting','hello'));

路由的匹配根据顺序定义。第一个匹配的路由请求将被调用。

路由方法

默认情况下,路由模式匹配的方法允许所有请求。你可以对特定的方法将一个标识符放在URL前面。

Flight::route('GET /', function(){echo 'I received a GET request.';});Flight::route('POST /', function(){echo 'I received a POST request.';});

您还可以将多个方法映射到一个回调,使用一个 “|” 分隔符:

Flight::route('GET|POST /', function(){echo 'I received either a GET or a POST request.';});

正则表达式

你可以在路由中使用正则表达式:

Flight::route('/user/[0-9]+', function(){// This will match /user/1234});

命名参数

你可以指定命名参数路由,她将被传递到你的回调函数。

Flight::route('/@name/@id', function($name, $id){echo "hello, $name ($id)!";});

你还可以使用包含正则表达式的命名参数,通过使用 “:” 分隔符:

Flight::route('/@name/@id:[0-9]{3}', function($name, $id){// This will match /bob/123// But will not match /bob/12345});

可选参数

您可以指定可选的命名参数,她被包在匹配的括号中。

Flight::route('/blog(/@year(/@month(/@day)))', function($year, $month, $day){// This will match the following URLS:// /blog/2012/12/10// /blog/2012/12// /blog/2012// /blog});

任何可选参数没有匹配将被传递NULL。

通配符

如果你想在单独URL部分匹配多个片段的路由。可以使用 “*” 通配符。

Flight::route('/blog/*', function(){// This will match /blog/2000/02/01});

所有的请求路由到一个回调,你可以写点东西:

Flight::route('*', function(){// Do something});

通过

您可以通过在回调函数通过返回 true 执行到下一个匹配的路由。

Flight::route('/user/@name', function($name){// Check some conditionif ($name != "Bob") {// Continue to next routereturn true;}});Flight::route('/user/*', function(){// This will get called});

扩展

Flight 被设计成一个可扩展的框架。框架附带了一组默认的方法和组件,但是她允许您映射的自己的方法,注册自己的类,或者覆盖现有的类和方法。

映射方法

映射你自己的方法,通过 “map” 方法:

// Map your methodFlight::map('hello', function($name){echo "hello $name!";});// Call your custom methodFlight::hello('Bob');

注册类

注册你自己的类,您可以使用 “register” 方法:

// Register your classFlight::register('user', 'User');// Get an instance of your class$user = Flight::user();

注册方法还允许为你的类构造函数传递参数。因此,当加载你的自定义类,她将预初始化。你可以定义的构造函数参数传递额外的数组。这里有一个加载数据库连接的例子:

// Register class with constructor parametersFlight::register('db', 'PDO', array('mysql:host=localhost;dnbname=test','user','pass'));// Get an instance of your class// This will create an object with the defined parameters////     new PDO('mysql:host=localhost;dnbname=test','user','pass');//$db = Flight::db();

如果你加了一个额外的回调参数,她将在类构建后立即执行。这允许你在新对象执行任何程序设置。回调函数接受一个参数,新对象的一个实例。

// The callback will be passed the object that was constructedFlight::register('db', 'PDO', array('mysql:host=localhost;dnbname=test','user','pass'), function($db){$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);});

默认情况下,每次你加载你的类都会得到一个共享实例。要得到一个新的实例,简单地通过 “false” 作为参数:

// Shared instance of the class$shared = Flight::db();// New instance of the class$new = Flight::db(false);

请记住,映射方法在注册类时有优先选择。如果你的声明都使用相同的名称,只有映射到的方法被调用。


覆盖

Flight 允许你覆盖默认的功能来满足自己的需求,而不需要修改任何代码。

例如, 当 Flight 没有匹配到 URL 的路由, 她会调用 “notFound” 方法发送一个通用的 “HTTP 404” 响应。 您可以覆盖此行为通过使用 “map” 方法:

Flight::map('notFound', function(){// Display custom 404 pageinclude 'errors/404.html';});

Flight 还允许您替换框架的核心组件 例如可以用你的自定义类替换默认的路由器类

// Register your custom classFlight::register('router', 'MyRouter');// When Flight loads the Router instance, it will load your class$myrouter = Flight::router();

Framework 的 “map” 和 “register” 方法不能被覆盖。如果你这样做,会得到一个错误。


过滤

Flight 允许你在调用之前和之后使用过滤方法。你需要记住它没有预定义的钩子。您可以过滤任何默认的框架方法以及任何你自定义的映射方法。

一个过滤器函数如下所示:

function(&$params, &$output) {// Filter code}

你可以使用传入的变量操纵输入或输出参数。

你可以在运行之前加一个过滤,像这样:

Flight::before('start', function(&$params, &$output){// Do something});

你可以在运行之后加一个过滤,像这样:

Flight::after('start', function(&$params, &$output){// Do something});

你可以添加多个过滤器来实现你想要的任何方法。她会按照声明的顺序执行。

这是一个过滤的例子:

// Map a custom methodFlight::map('hello', function($name){return "Hello, $name!";});// Add a before filterFlight::before('hello', function(&$params, &$output){// Manipulate the parameter$params[0] = 'Fred';});// Add an after filterFlight::after('hello', function(&$params, &$output){// Manipulate the output$output .= " Have a nice day!";}// Invoke the custom methodecho Flight::hello('Bob');

她将这样显示:

Hello Fred! Have a nice day! 

如果定义了多个过滤器,你可以在任何地方通过返回 “false” 来打破过滤功能:

Flight::before('start', function(&$params, &$output){echo 'one';});Flight::before('start', function(&$params, &$output){echo 'two';// This will end the chainreturn false;});// This will not get calledFlight::before('start', function(&$params, &$output){echo 'three';});

注意, “map” 和 “register” 等核心方法不能被过滤,因为她们是被直接调用的。


变量

Flight 允许你保存变量,这样就可以在你的应用程序任何地方使用。

// Save your variableFlight::set('id', 123);// Elsewhere in your application$id = Flight::get('id');

查看一个变量是否被你定义:

if (Flight::has('id')) {// Do something}

清除你的变量:

// Clears the id variableFlight::clear('id');// Clears all variablesFlight::clear();

Flight 还可以修改配置变量

Flight::set('flight.log_errors', true);

视图

默认情况下 Flight 提供了一些基本的模板功能。调用 “render” 方法来显示一个视图模板并可传递一些数据:

Flight::render('hello.php', array('name' => 'Bob'));

你传入的模板数据将作为一个局部变量自动注入到引用的模板。模板文件是简单的 .php 文件。如果模板文件 “hello.php” 是这样的:

Hello, '<?php echo $name; ?>'!

她将输出:

Hello, Bob!

你也可以用 set 方法手动设置视图变量:

Flight::view()->set('name', 'Bob');

name 变量可以用在你的所有视图中。所以你可以更简单的写成这样:

Flight::render('hello');

注意,当在 render 方法中指定模板的名称时, 你可以不用写 .php 文件后缀。

默认情况下 Flight 将寻找一个 “views” 的文件目录。你可以通过以下配置设置一个替代的模板路径:

Flight::set('flight.views.path', '/path/to/views');

布局

网站有一个常见的布局模板文件用来交换内容。在呈现一个布局时,你可以传递一个可选参数到 “render” 方法。

Flight::render('header', array('heading' => 'Hello'), 'header_content');Flight::render('body', array('body' => 'World'), 'body_content');

你的视图将被保存在名为 “header_content” 和 “body_content” 的变量中,你可以在布局中这样做:

Flight::render('layout', array('title' => 'Home Page'));

如果模板文件像这样:

header.php:

<h1><?php echo $heading; ?></h1>

body.php:

<div><?php echo $body; ?></div>

layout.php:

<html><head><title><?php echo $title; ?></title></head><body><?php echo $header_content; ?><?php echo $body_content; ?></body></html>

她将输出:

<html><head><title>Home Page</title></head><body><h1>Hello</h1><div>World</div></body></html>

自定义视图

Flight 允许你替换默认的视图引擎,只需注册自己的视图类。下面是如何使用 Smarty 模板引擎到你的视图:

// Load Smarty libraryrequire './Smarty/libs/Smarty.class.php';// Register Smarty as the view class// Also pass a callback function to configure Smarty on loadFlight::register('view', 'Smarty', array(), function($smarty){$smarty->template_dir = './templates/';$smarty->compile_dir = './templates_c/';$smarty->config_dir = './config/';$smarty->cache_dir = './cache/';});// Assign template dataFlight::view()->assign('name', 'Bob');// Display the templateFlight::view()->display('hello.tpl');

出于完整性的考虑,你也应该覆盖 Flight 的默认渲染方法:

Flight::map('render', function($template, $data){Flight::view()->assign($data);Flight::view()->display($template);});

错误处理

错误和异常

所有的错误和异常都 Flight 传递到 “error” 方法中。 默认行为是发送一个通用 “HTTP 500 Internal Server Error” 响应,来显示一些简单的错误信息。

你可以根据自己的需求覆盖此行为:

Flight::map('error', function(Exception $ex){// Handle errorecho $ex->getTraceAsString();});

默认情况下,错误没有被记录到 web server。您可以通过改变配置启用她:

Flight::set('flight.log_errors', true);

没有找到

当一个 URL 没有被找到, Flight 将调用 notFound 方法。默认行为是发送一个 HTTP 404 Not Found 响应,来显示一些简单的错误信息。

你可以根据自己的需求覆盖此行为:

Flight::map('notFound', function(){// Handle not found});

重定向

您可以传递一个新的 URL 通过 “redirect” 方法重定向。:

Flight::redirect('/new/location');

默认情况下 Flight 发送一个 HTTP 303 状态码。你可以自定义一个代码:

Flight::redirect('/new/location', 401);

请求

Flight 封装 HTTP 请求到一个对象, 你可以通过这样访问:

$request = Flight::request();

请求对象提供了以下属性:

url - 被请求的 URLbase - 被请求 URL 的父目录method - 请求方法 (GET, POST, PUT, DELETE)referrer - 引用的 URLip - 客户机的 IP 地址ajax - 是不是一个 AJAX 请求scheme - 服务器协议 (http, https)user_agent - 浏览器的信息body - 请求主体的原始数据type - 内容类型length - 内容长度query - 查询字符串参数data - Post 参数cookies - Cookie 参数files - 上传的文件secure - 连接是否安全accept - HTTP 接受参数proxy_ip - 代理客户机的 IP 地址

你可以通过数组或对象访问 querydatacookies 和 files 属性。

因此,要查询一个参数, 你可以这样:

$id = Flight::request()->query['id'];

或者这样:

$id = Flight::request()->query->id;

HTTP 缓存

Flight 提供了内置的 HTTP 缓存。如果缓存条件满足, Flight 将返回一个 HTTP 304 Not Modified 响应。下次客户端请求相同的资源时,她们会提示使用本地缓存版本。

最后修改

你可以使用 lastModified 传递一个 UNIX 时间戳来设置页面最后修改日期和时间。客户端将继续使用缓存,直到最后修改值发生了改变。

Flight::route('/news', function(){Flight::lastModified(1234567890);echo 'This content will be cached.';});

ETag

ETag 缓存同 Last-Modified 类似,除了你可以指定任何你想要的id资源:

Flight::route('/news', function(){Flight::etag('my-unique-id');echo 'This content will be cached.';});

记住,使用 lastModified 或 etag 时都将设置并检查缓存值。如果缓存值于请求之间是相同的, Flight 将立即发送一个 HTTP 304 响应并停止处理。

停止

你可以在任何时候调用 halt 方法停止框架:

Flight::halt();

你还可以指定一个可选的 HTTP 状态代码和信息:

Flight::halt(200, 'Be right back...');

调用 halt 方法将丢弃任何响应内容。如果你想要停止框架并输出当前的响应,使用 stop 方法:

Flight::stop();

JSON

Flight 支持发送 JSON 和 JSONP 响应。 你可以通过 json 方法传递一些JSON编码的数据:

Flight::json(array('id' => 123));

你可以使用 jsonp 方法用于 JSONP 请求。你可以通过传递查询参数名来定义你正在使用的回调函数:

Flight::jsonp(array('id' => 123), 'q');

所以,当制造一个GET请求,使用 ?q=my_func ,你会得到这样的输出:

my_func({"id":123});

如果你不传递查询参数名将默认使用 jsonp 。


配置

您可以自定义 Flight 的某些行为,通过使用 set 方法。

Flight::set('flight.log_errors', true);

下面是一个所有可用配置的列表。

flight.base_url - 覆盖 base url 请求。 (默认: null)flight.handle_errors - 允许 Flight 处理所有内部错误。 (默认: true)flight.log_errors - 将错误日志记录到 web server 的错误日志文件。 (默认: false)flight.views.path - 包含视图模板文件的目录 (默认: ./views)

框架方法

Flight 被设计为易于使用和理解。下面是框架的全套方法。它包含的核心方法,常规的静态方法,和可扩展的方法,可以过滤或覆盖。

核心方法

Flight::map($name, $callback) // 创建一个自定义框架的方法。Flight::register($name, $class, [$params], [$callback]) // 注册一个类的框架方法。Flight::before($name, $callback) // 在一个框架方法之前添加一个过滤器。Flight::after($name, $callback) // 在一个框架方法之后添加一个过滤器。Flight::path($path) // 添加了一个半自动的类路径。Flight::get($key) // 得到一个变量。Flight::set($key, $value) // 设置一个变量。Flight::has($key) // 检查一个变量是否设置。Flight::clear([$key]) // 清除一个变量。

可扩展的方法

Flight::start() // 开始框架Flight::stop() // 停止该框架并发送一个响应。Flight::halt([$code], [$message]) // 停止该框架并带一个可选的状态代码和消息。Flight::route($pattern, $callback) // 映射一个 URL 模式到回调。Flight::redirect($url, [$code]) // 重定向到另一个URL。Flight::render($file, [$data], [$key]) // 呈现一个模板文件。Flight::error($exception) // 发送一个 HTTP 500 响应。Flight::notFound() // 发送一个 HTTP 404 响应。Flight::etag($id, [$type]) // 执行 ETag HTTP 缓存。Flight::lastModified($time) // 执行最后更改的 HTTP 缓存。Flight::json($data, [$code], [$encode]) // 发送一个 JSON 响应。Flight::jsonp($data, [$param], [$code], [$encode]) // 发送一个 JSONP 响应。

任何被 map 和 register 的自定义方法都可以被过滤。

框架实例

Flight 并不是作为一个全局静态类运行,您可以选择作为一个对象实例运行它。

require 'flight/autoload.php';use flight\Engine;$app = new Engine();$app->route('/', function(){echo 'hello world!';});$app->start();

现在所有的静态方法都可以被作为常规的类方法。





待续.