├── .gitattributes ├── .gitignore ├── README.md └── flight.doc.cn.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # ========================= 18 | # Operating System Files 19 | # ========================= 20 | 21 | # OSX 22 | # ========================= 23 | 24 | .DS_Store 25 | .AppleDouble 26 | .LSOverride 27 | 28 | # Icon must ends with two \r. 29 | Icon 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Flight框架中文文档 2 | 3 | ##Flight官网 4 | [Flight框架官网](http://flightphp.com/) 5 | 6 | ##什么是Flight 7 | 8 | Flight是一个快速,简易,可扩展的微型PHP框架。 9 | Flight能够让你快速而简便的创建出RESTful的web应用。 10 | 11 | 12 | ```php 13 | require 'flight/Flight.php'; 14 | 15 | Flight::route('/', function(){ 16 | echo 'hello world!'; 17 | }); 18 | 19 | Flight::start(); 20 | ``` 21 | 22 | ##中文文档 23 | 24 | [文档地址](https://github.com/baizhebz/flight-doc-cn/blob/master/flight.doc.cn.md) 25 | 26 | 27 | 有关翻译的任何问题,敬请指正! -------------------------------------------------------------------------------- /flight.doc.cn.md: -------------------------------------------------------------------------------- 1 | # Flight是什么? 2 | 3 | Flight是一个快速,简易,可扩展的PHP框架。Flight能使你快速和轻松地创建RESTful Web应用。 4 | 5 | ```php 6 | require 'flight/Flight.php'; 7 | 8 | Flight::route('/', function(){ 9 | echo 'hello world!'; 10 | }); 11 | 12 | Flight::start(); 13 | ``` 14 | 15 | 16 | # 需求 17 | 18 | Flight需要`PHP 5.3`或更高版本。 19 | 20 | # License 21 | 22 | Flight is released under the [MIT](http://flightphp.com/license) license. 23 | 24 | # 安装 25 | 26 | 1\.框架下载 27 | 28 | 如果你在使用[Composer](https://getcomposer.org/),你可以运行如下命令: 29 | 30 | ``` 31 | composer require mikecao/flight 32 | ``` 33 | 34 | 或者你可以直接[下载](https://github.com/mikecao/flight/tarball/master),之后将Flight框架文件放入你的web目录中。 35 | 36 | 2\. 配置你的web服务器 37 | 38 | 对于*Apache*服务器,编辑你的`.htaccess`文件添加如下内容: 39 | 40 | ``` 41 | RewriteEngine On 42 | RewriteCond %{REQUEST_FILENAME} !-f 43 | RewriteCond %{REQUEST_FILENAME} !-d 44 | RewriteRule ^(.*)$ index.php [QSA,L] 45 | ``` 46 | 47 | 对于*Nginx*服务器,添加如下内容到你的server声明中: 48 | 49 | ``` 50 | server { 51 | location / { 52 | try_files $uri $uri/ /index.php; 53 | } 54 | } 55 | ``` 56 | 3\. 创建你的`index.php`文件(示例) 57 | 58 | 首先引入这个框架。 59 | 60 | ```php 61 | require 'flight/Flight.php'; 62 | ``` 63 | 64 | 接着定义一个路由并且注册一个函数去处理对应请求。 65 | 66 | ```php 67 | Flight::route('/', function(){ 68 | echo 'hello world!'; 69 | }); 70 | ``` 71 | 72 | 最后,启动框架。 73 | 74 | ```php 75 | Flight::start(); 76 | ``` 77 | 78 | # 路由 79 | 80 | Flight中的路由是指将一个URL模式(pattern)匹配到一个回调函数中。 81 | 82 | ```php 83 | Flight::route('/', function(){ 84 | echo 'hello world!'; 85 | }); 86 | ``` 87 | 88 | 只要能被调用,都可以当做回调函数。所以可以使用一个普通的函数当做回调: 89 | 90 | ```php 91 | function hello(){ 92 | echo 'hello world!'; 93 | } 94 | 95 | Flight::route('/', 'hello'); 96 | ``` 97 | 98 | 也可以是某一个类的方法: 99 | 100 | ```php 101 | class Greeting { 102 | public static function hello() { 103 | echo 'hello world!'; 104 | } 105 | } 106 | 107 | Flight::route('/', array('Greeting','hello')); 108 | ``` 109 | 110 | 如果定义了多个路由,路由依照定义它们的顺序进行匹配。第一个匹配到该请求的路由将被调用。 111 | 112 | ## HTTP METHOD路由 113 | 114 | 在默认不指定的情况下,路由会对相应请求的所有Method(例如:GET POST PUT DELETE...)进行匹配。你可以通过在URL前面加一个方法标识符的方式来响应指定的Method。 115 | 116 | ```php 117 | Flight::route('GET /', function(){ 118 | echo 'I received a GET request.'; 119 | }); 120 | 121 | Flight::route('POST /', function(){ 122 | echo 'I received a POST request.'; 123 | }); 124 | ``` 125 | 126 | 你还可以使用`|`分隔符来映射多个Method到同一个回调中。 127 | 128 | ```php 129 | Flight::route('GET|POST /', function(){ 130 | echo 'I received either a GET or a POST request.'; 131 | }); 132 | ``` 133 | 134 | ## 正则表达式 135 | 136 | 在路由中你可以使用正则表达式: 137 | 138 | ```php 139 | Flight::route('/user/[0-9]+', function(){ 140 | // 这个将匹配到 /user/1234 141 | }); 142 | ``` 143 | 144 | ## 命名参数 145 | 146 | 你可以在路由中指定命名参数,它们会被传递到你的回调函数里。 147 | 148 | ```php 149 | Flight::route('/@name/@id', function($name, $id){ 150 | echo "hello, $name ($id)!"; 151 | }); 152 | ``` 153 | 154 | 你也可以通过使用`:`分隔符在命名变量中引入正则表达式 155 | 156 | ```php 157 | Flight::route('/@name/@id:[0-9]{3}', function($name, $id){ 158 | // 这个将匹配到 /bob/123 159 | // 但是不会匹配到 /bob/12345 160 | }); 161 | ``` 162 | 163 | ## 可选参数 164 | 165 | 你可以通过将URL段(segments)包在括号里的方式来指定哪些命名参数是可选的。 166 | 167 | ```php 168 | Flight::route('/blog(/@year(/@month(/@day)))', function($year, $month, $day){ 169 | // 它将匹配如下URLS: 170 | // /blog/2012/12/10 171 | // /blog/2012/12 172 | // /blog/2012 173 | // /blog 174 | }); 175 | ``` 176 | 177 | 任何没有被匹配到的可选参数将以NULL值传入。 178 | 179 | ## 通配符 180 | 181 | 匹配只发生在单独的URL段(segments)。如果你想匹配多段,可以使用`*`通配符。 182 | 183 | ```php 184 | Flight::route('/blog/*', function(){ 185 | // 这个将匹配到 /blog/2000/02/01 186 | }); 187 | ``` 188 | 189 | 要将所有的请求路由到单一的回调上,你可以这么做: 190 | 191 | ```php 192 | Flight::route('*', function(){ 193 | // Do something 194 | }); 195 | ``` 196 | 197 | ## 路由的传递 198 | 199 | 当从一个被匹配到的回调函数中返回`true`时,路由功能将继续执行,传递到下一个能匹配的路由中。 200 | 201 | ```php 202 | Flight::route('/user/@name', function($name){ 203 | // 检查某些条件 204 | if ($name != "Bob") { 205 | // 延续到下一个路由 206 | return true; 207 | } 208 | }); 209 | 210 | Flight::route('/user/*', function(){ 211 | // 这里会被调用到 212 | }); 213 | ``` 214 | 215 | ## 路由信息 216 | 217 | 如果你想检视匹配到的路由信息,可以请求将路由对象传递到你的回调函数中:你需要把 218 | route方法的第三个参数设置成`true`。这个路由对象总是会作为最后一个参数传入你的回调函数。 219 | 220 | ```php 221 | Flight::route('/', function($route){ 222 | // 匹配到的HTTP方法的数组 223 | $route->methods; 224 | 225 | // 命名参数数组 226 | $route->params; 227 | 228 | // 匹配的正则表达式 229 | $route->regex; 230 | 231 | // Contains the contents of any '*' used in the URL pattern 232 | $route->splat; 233 | }, true); 234 | ``` 235 | 236 | # 扩展 237 | 238 | Fligth被设计成一个可扩展的框架。这个框架带来了一系列的默认方法和组件,但是它允许你 239 | 映射你自己的方法,注册你自己的类,甚至可以重写已有的类和方法。 240 | 241 | ## 方法的映射 242 | 243 | 你可以使用`map`函数去映射你自定义的方法: 244 | 245 | ```php 246 | // 映射你自己的方法 247 | Flight::map('hello', function($name){ 248 | echo "hello $name!"; 249 | }); 250 | 251 | // 调用你的自定义方法 252 | Flight::hello('Bob'); 253 | ``` 254 | 255 | ## 类的注册 256 | 257 | 你可以使用`register`函数去注册你自己的类: 258 | 259 | ```php 260 | // 注册你定义的类 261 | Flight::register('user', 'User'); 262 | 263 | // 得到你定义的类的一个实例 264 | $user = Flight::user(); 265 | ``` 266 | 267 | register方法允许你向类的构造函数传递参数。所以当你加载自定义类的时候,它将会 268 | 预初始化(pre-initialized)。你可以通过一个追加的数组来传递定义的构造函数参数。 269 | 这是一个加载数据库连接的例子: 270 | 271 | ```php 272 | // 注册一个带有构造函数参数的类 273 | Flight::register('db', 'PDO', array('mysql:host=localhost;dbname=test','user','pass')); 274 | 275 | // 得到你定义的类的一个实例 276 | // 这里将创建一个带有你定义的参数的对象 277 | // 278 | // new PDO('mysql:host=localhost;dbname=test','user','pass'); 279 | // 280 | $db = Flight::db(); 281 | ``` 282 | 283 | 如果你传递了额外的回调函数参数,它将会在类构造完之后立即执行。这就允许你为这个新对象去 284 | 执行任何的安装过程(set up procedures)。这个回调函数会被传递一个参数,就是这个新对象的实例。 285 | 286 | ```php 287 | // 这个回调函数将会传递到这个被构造的对象中 288 | Flight::register('db', 'PDO', array('mysql:host=localhost;dbname=test','user','pass'), function($db){ 289 | $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 290 | }); 291 | ``` 292 | 293 | 默认情况下,每次你加载一个类,你会得到一个共享的实例。如果要得到一个类的新实例, 294 | 简单的传递一个`false`参数就行了。 295 | 296 | ```php 297 | // 类的共享实例 298 | $shared = Flight::db(); 299 | 300 | // 类的新实例 301 | $new = Flight::db(false); 302 | ``` 303 | 304 | 需要记住的是,被映射的方法优先于被注册的类。如果你用相同的名字将它们都声明了,那么只有 305 | 映射的方法会被调用。 306 | 307 | # 重写(Overriding) 308 | 309 | Flight允许你按照自己的需要去重写它的默认功能,而不用修改任何框架的代码。 310 | 311 | 例如,当Flight的路由功能没有匹配到一个URL时,它会调用`notFound`方法,发出一个通用的 312 | `HTTP 404`响应。你可以使用`map`方法去重写这个行为。 313 | 314 | ```php 315 | Flight::map('notFound', function(){ 316 | // 显示自定义的404页面 317 | include 'errors/404.html'; 318 | }); 319 | ``` 320 | 321 | Flight也允许你替换这个框架的核心组件。例如你可以将默认的Router类替换成你自定义的类: 322 | 323 | ```php 324 | // 注册成你自定义的类 325 | Flight::register('router', 'MyRouter'); 326 | 327 | // When Flight loads the Router instance, it will load your class 328 | // 当Flight加载Router实例时,将会加载到你自定义的类 329 | $myrouter = Flight::router(); 330 | ``` 331 | 332 | 然而框架的方法诸如`map`和`register`是不能够被重写的。如果你尝试这么做的话你会得到一个error。 333 | 334 | # 过滤 335 | 336 | Flight允许你在方法调用之前和之后去过滤它。框架里没有任何你需要记住的预定义的钩子。你可以 337 | 过滤任何被映射的自定义方法和框架中的方法。 338 | 339 | 一个过滤器函数是像这样的: 340 | 341 | ```php 342 | function(&$params, &$output) { 343 | // Filter code 344 | } 345 | ``` 346 | 347 | 通过传入的变量,你可以操作输入参数和/或输出参数。 348 | 349 | 这样做就可以在一个方法运行之前运行一个过滤器: 350 | 351 | ```php 352 | Flight::before('start', function(&$params, &$output){ 353 | // Do something 354 | }); 355 | ``` 356 | 357 | 这样做就可以在一个方法运行之后运行一个过滤器: 358 | 359 | ```php 360 | Flight::after('start', function(&$params, &$output){ 361 | // Do something 362 | }); 363 | ``` 364 | 365 | 你可以给任何函数添加任意数量的过滤器。它们将按照声明的顺序依次被调用。 366 | 367 | 这里是一个过滤器处理的例子: 368 | 369 | ```php 370 | // 映射一个自定义的方法 371 | Flight::map('hello', function($name){ 372 | return "Hello, $name!"; 373 | }); 374 | 375 | // 添加一个前置的过滤器 376 | Flight::before('hello', function(&$params, &$output){ 377 | // 操作这里的params 378 | $params[0] = 'Fred'; 379 | }); 380 | 381 | // 添加一个后置的过滤器 382 | Flight::after('hello', function(&$params, &$output){ 383 | // 操作这里的output 384 | $output .= " Have a nice day!"; 385 | }); 386 | 387 | // 调用这个自定义方法 388 | echo Flight::hello('Bob'); 389 | ``` 390 | 391 | 这个将会输出: 392 | 393 | Hello Fred! Have a nice day! 394 | 395 | 如果你定义了多个过滤器,你可以通过在任意一个过滤器函数中返回`false`来终结这个过滤器链。 396 | 397 | ```php 398 | Flight::before('start', function(&$params, &$output){ 399 | echo 'one'; 400 | }); 401 | 402 | Flight::before('start', function(&$params, &$output){ 403 | echo 'two'; 404 | 405 | // 如下将会终止这个过滤器链 406 | return false; 407 | }); 408 | 409 | // 这里将不会得到调用 410 | Flight::before('start', function(&$params, &$output){ 411 | echo 'three'; 412 | }); 413 | ``` 414 | 415 | 记住,核心函数诸如`map`和`register`是不能够被过滤的,因为它们是被直接调用而非动态调用的。 416 | 417 | # 变量 418 | 419 | Flight允许你定义变量,使得它能在应用内的任何地方被使用。 420 | 421 | ```php 422 | // 保存你定义的变量 423 | Flight::set('id', 123); 424 | 425 | // 在应用的其他地方使用 426 | $id = Flight::get('id'); 427 | ``` 428 | 去检测一个变量是否被设置了可以这么做: 429 | 430 | ```php 431 | if (Flight::has('id')) { 432 | // Do something 433 | } 434 | ``` 435 | 436 | 去清除一个变量你可以这么做: 437 | 438 | ```php 439 | // 清除这个id变量 440 | Flight::clear('id'); 441 | 442 | // 清除所有的变量 443 | Flight::clear(); 444 | ``` 445 | 446 | Flight框架使用变量的目的还包括了配置。 447 | 448 | ```php 449 | Flight::set('flight.log_errors', true); 450 | ``` 451 | 452 | # 视图 453 | 454 | Flight默认提供了一些基础的模板功能。调用带有模板文件和 455 | 可选的模板数据的`render`函数,去显示一个视图模板。 456 | 457 | ```php 458 | Flight::render('hello.php', array('name' => 'Bob')); 459 | ``` 460 | 461 | 你传进来的模板数据,会被自动的注入到模板当中,并且可以像一个本地变量一样去引用。 462 | 模板文件就是简单的PHP文件。如果一个文件名为`hello.php`的模板文件的内容是这样的: 463 | 464 | ```php 465 | Hello, ''! 466 | ``` 467 | 468 | 输出会是: 469 | 470 | Hello, Bob! 471 | 472 | 你可以使用set函数来手动的设置视图中的变量: 473 | 474 | ```php 475 | Flight::view()->set('name', 'Bob'); 476 | ``` 477 | 478 | 这个`name` 变量现在在你所有的视图中都是可用的了。所以就可以简化成这样了: 479 | 480 | ```php 481 | Flight::render('hello'); 482 | ``` 483 | 484 | 注意当你在render函数中指定模板名时,你可以去掉这个`.php`的扩展名。 485 | 486 | 默认情况下Flight会在`views`目录下寻找模板文件。你可以通过如下配置的设定来为你的模板 487 | 设置另外一个路径。 488 | 489 | ```php 490 | Flight::set('flight.views.path', '/path/to/views'); 491 | ``` 492 | 493 | ## 布局(Layouts) 494 | 495 | 对网站来说,拥有一个单独的可交换内容的布局(layout)模板文件是很常见的。要在布局中使用渲染的内容, 496 | 你可以给`render`函数传递一个可选的参数。 497 | 498 | ```php 499 | Flight::render('header', array('heading' => 'Hello'), 'header_content'); 500 | Flight::render('body', array('body' => 'World'), 'body_content'); 501 | ``` 502 | 503 | 紧接着你的视图就有了命名为`header_content`和`body_content`的已保存的变量。接下来你就可以 504 | 这样渲染你的布局了: 505 | 506 | ```php 507 | Flight::render('layout', array('title' => 'Home Page')); 508 | ``` 509 | 510 | 如果你的模板文件是这样的: 511 | 512 | `header.php`: 513 | 514 | ```php 515 |
516 | ``` 517 | 518 | `body.php`: 519 | 520 | ```php 521 | 522 | ``` 523 | 524 | `layout.php`: 525 | 526 | ```php 527 | 528 | 529 |