nebo15/micro-yii

基于Klein的带有Yii2组件的轻量级框架

维护者

详细信息

github.com/Nebo15/micro-yii

源代码

v2.0.2 2013-06-16 23:32 UTC

This package is not auto-updated.

Last update: 2024-09-14 14:14:22 UTC


README

Build Status

klein.php 是一个适用于PHP 5.3+的闪电般的路由器

  • 灵活的正则表达式路由(灵感来源于 Sinatra
  • 一套用于快速构建Web应用的模板方法
  • 几乎无开销 => 2500+ 请求/秒

入门指南

  1. 需要PHP 5.4.x
  2. 使用 Composer (推荐) 或手动安装 Klein
  3. 设置 URL重写 以确保所有请求都由 index.php 处理
  4. (可选) 加入一些 APC 以增强性能

Composer安装

  1. 获取 Composer
  2. 使用 php composer.phar require klein/klein v2.0.x 安装 Klein
  3. 使用 php composer.phar install 安装依赖

示例

你好世界 - 必须的“你好世界”示例

<?php
require_once __DIR__ . '/vendor/autoload.php';

$klein = new \Klein\Klein();

$klein->respond('GET', '/hello-world', function () {
    return 'Hello World!';
});

$klein->dispatch();

示例 1 - 响应所有请求

$klein->respond(function () {
    return 'All the things';
});

示例 2 - 命名参数

$klein->respond('/[:name]', function ($request) {
    return 'Hello ' . $request->name;
});

示例 3 - 如此RESTful

$klein->respond('GET', '/posts', $callback);
$klein->respond('POST', '/posts', $callback);
$klein->respond('PUT', '/posts/[i:id]', $callback);
$klein->respond('DELETE', '/posts/[i:id]', $callback);
$klein->respond('OPTIONS', null, $callback);

// To match multiple request methods:
$klein->respond(array('POST','GET'), $route, $callback);

// Or you might want to handle the requests in the same place
$klein->respond('/posts/[create|edit:action]?/[i:id]?', function ($request, $response) {
    switch ($request->action) {
        //
    }
});

示例 4 - 发送对象/文件

$klein->respond(function ($request, $response, $service) {
    $service->xml = function ($object) {
        // Custom xml output function
    }
    $service->csv = function ($object) {
        // Custom csv output function
    }
});

$klein->respond('/report.[xml|csv|json:format]?', function ($request, $response, $service) {
    // Get the format or fallback to JSON as the default
    $send = $request->param('format', 'json');
    $service->$send($report);
});

$klein->respond('/report/latest', function ($request, $response, $service) {
    $service->file('/tmp/cached_report.zip');
});

示例 5 - 一切皆有可能

$klein->respond(function ($request, $response, $service, $app) use ($klein) {
    // Handle exceptions => flash the message and redirect to the referrer
    $klein->onError(function ($klein, $err_msg) {
        $klein->service()->flash($err_msg);
        $klein->service()->back();
    });

    // The third parameter can be used to share scope and global objects
    $app->db = new PDO(...);

    // $app also can store lazy services, e.g. if you don't want to
    // instantiate a database connection on every response
    $app->register('db', function() {
        return new PDO(...);
    });
});

$klein->respond('POST', '/users/[i:id]/edit', function ($request, $response, $service, $app) {
    // Quickly validate input parameters
    $service->validateParam('username', 'Please enter a valid username')->isLen(5, 64)->isChars('a-zA-Z0-9-');
    $service->validateParam('password')->notNull();

    $app->db->query(...); // etc.

    // Add view properties and helper methods
    $service->title = 'foo';
    $service->escape = function ($str) {
        return htmlentities($str); // Assign view helpers
    };

    $service->render('myview.phtml');
});

// myview.phtml:
<title><?php echo $this->escape($this->title) ?></title>

路由命名空间

$klein->with('/users', function () use ($klein) {

    $klein->respond('GET', '/?', function ($request, $response) {
        // Show all users
    });

    $klein->respond('GET', '/[:id]', function ($request, $response) {
        // Show a single user
    });

});

foreach(array('projects', 'posts') as $controller) {
    // Include all routes defined in a file under a given namespace
    $klein->with("/$controller", "controllers/$controller.php");
}

包含的文件在Klein的范围内运行($klein),因此可以使用 $this 访问所有Klein方法/属性

示例文件: "controllers/projects.php"

// Routes to "/projects/?"
$this->respond('GET', '/?', function ($request, $response) {
    // Show all projects
});

懒加载服务

服务可以 懒加载,这意味着它们只在第一次使用时才被实例化。

<?php
$klein->respond(function ($request, $response, $service, $app) {
    $app->register('lazyDb', function() {
        $db = new stdClass();
        $db->name = 'foo';
        return $db;
    });
});

//Later

$klein->respond('GET', '/posts', function ($request, $response, $service, $app) {
    // $db is initialised on first request
    // all subsequent calls will use the same instance
    return $app->lazyDb->name;
});

验证器

要添加自定义验证器,请使用 addValidator($method, $callback)

$service->addValidator('hex', function ($str) {
    return preg_match('/^[0-9a-f]++$/i', $str);
});

您可以使用 is<$method>()not<$method>() 验证参数,例如。

$service->validateParam('key')->isHex();

或者,您可以使用相同的流程验证任何字符串。

$service->validate($username)->isLen(4,16);

验证方法是可链式的,并且可以指定自定义异常消息以供验证失败时使用

$service->validateParam('key', 'The key was invalid')->isHex()->isLen(32);

路由

[ match_type : param_name ]

一些示例

*                    // Match all request URIs
[i]                  // Match an integer
[i:id]               // Match an integer as 'id'
[a:action]           // Match alphanumeric characters as 'action'
[h:key]              // Match hexadecimal characters as 'key'
[:action]            // Match anything up to the next / or end of the URI as 'action'
[create|edit:action] // Match either 'create' or 'edit' as 'action'
[*]                  // Catch all (lazy)
[*:trailing]         // Catch all as 'trailing' (lazy)
[**:trailing]        // Catch all (possessive - will match the rest of the URI)
.[:format]?          // Match an optional parameter 'format' - a / or . before the block is also optional

更多复杂示例

/posts/[*:title][i:id]     // Matches "/posts/this-is-a-title-123"
/output.[xml|json:format]? // Matches "/output", "output.xml", "output.json"
/[:controller]?/[:action]? // Matches the typical /controller/action format

注意 - 所有 与请求URI匹配的路由都将被调用 - 这允许您结合复杂的条件逻辑,例如用户身份验证或视图布局。例如,以下代码将包装其他路由的头部和尾部

$klein->respond('*', function ($request, $response, $service) { $service->render('header.phtml'); });
//other routes
$klein->respond('*', function ($request, $response, $service) { $service->render('footer.phtml'); });

路由自动匹配整个请求URI。如果您需要匹配请求URI的一部分或使用自定义正则表达式,请使用 @ 操作符。如果您需要否定路由,请使用 ! 操作符

// Match all requests that end with '.json' or '.csv'
$klein->respond('@\.(json|csv)$', ...

// Match all requests that _don't_ start with /admin
$klein->respond('!@^/admin/', ...

视图

您可以通过将属性或助手分配给 $service 对象,或使用 $service->render() 的第二个参数将属性或助手发送到视图。

$service->escape = function ($str) {
    return htmlentities($str);
};

$service->render('myview.phtml', array('title' => 'My View'));

// Or just: $service->title = 'My View';

myview.phtml

<title><?php echo $this->escape($this->title) ?></title>

视图在 $service 的范围内编译和运行,因此可以使用 $this 访问所有服务方法

$this->render('partial.html')           // Render partials
$this->sharedData()->get('myvar')       // Access stored service variables
echo $this->query(array('page' => 2))   // Modify the current query string

API

以下是在常见类中您最可能使用到的公共方法列表。有关更正式的类/方法文档,请参阅 PHPdoc 生成的文档

$request->
    id($hash = true)                    // Get a unique ID for the request
    paramsGet()                         // Return the GET parameter collection
    paramsPost()                        // Return the POST parameter collection
    paramsNamed()                       // Return the named parameter collection
    cookies()                           // Return the cookies collection
    server()                            // Return the server collection
    headers()                           // Return the headers collection
    files()                             // Return the files collection
    body()                              // Get the request body
    params()                            // Return all parameters
    params($mask = null)                // Return all parameters that match the mask array - extract() friendly
    param($key, $default = null)        // Get a request parameter (get, post, named)
    isSecure()                          // Was the request sent via HTTPS?
    ip()                                // Get the request IP
    userAgent()                         // Get the request user agent
    uri()                               // Get the request URI
    pathname()                          // Get the request pathname
    method()                            // Get the request method
    method($method)                     // Check if the request method is $method, i.e. method('post') => true
    query($key, $value = null)          // Get, add to, or modify the current query string
    <param>                             // Get / Set (if assigned a value) a request parameter

$response->
    protocolVersion($protocol_version = null)       // Get the protocol version, or set it to the passed value
    body($body = null)                              // Get the response body's content, or set it to the passed value
    status()                                        // Get the response's status object
    headers()                                       // Return the headers collection
    cookies()                                       // Return the cookies collection
    code($code = null)                              // Return the HTTP response code, or set it to the passed value
    prepend($content)                               // Prepend a string to the response body
    append($content)                                // Append a string to the response body
    isLocked()                                      // Check if the response is locked
    requireUnlocked()                               // Require that a response is unlocked
    lock()                                          // Lock the response from further modification
    unlock()                                        // Unlock the response
    sendHeaders($override = false)                  // Send the HTTP response headers
    sendCookies($override = false)                  // Send the HTTP response cookies
    sendBody()                                      // Send the response body's content
    send()                                          // Send the response and lock it
    isSent()                                        // Check if the response has been sent
    chunk($str = null)                              // Enable response chunking (see the wiki)
    header($key, $value = null)                     // Set a response header
    cookie($key, $value = null, $expiry = null)     // Set a cookie
    cookie($key, null)                              // Remove a cookie
    noCache()                                       // Tell the browser not to cache the response
    redirect($url, $code = 302)                     // Redirect to the specified URL
    dump($obj)                                      // Dump an object
    file($path, $filename = null)                   // Send a file
    json($object, $jsonp_prefix = null)             // Send an object as JSON or JSONP by providing padding prefix

$app->
    <callback>($arg1, ...)                          //Call a user-defined helper

## Unit Testing

Unit tests are a crucial part of developing a routing engine such as Klein.
Added features or bug-fixes can have adverse effects that are hard to find
without a lot of testing, hence the importance of unit testing.

This project uses [PHPUnit](https://github.com/sebastianbergmann/phpunit/) as
its unit testing framework.

The tests all live in `/tests` and each test extends an abstract class
`AbstractKleinTest`

To test the project, simply run `php composer.phar install --dev` to download
a common version of PHPUnit with composer and run the tests from the main
directory with `./vendor/bin/phpunit`

## Contributing

See the [contributing guide](CONTRIBUTING.md) for more info

## More information

See the [wiki](https://github.com/chriso/klein.php/wiki) for more information

## Contributors

- [Trevor N. Suarez](https://github.com/Rican7)

## License

(MIT License)

Copyright (c) 2010 Chris O'Hara <cohara87@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.