Added new Collection class, updated documentation

pull/11/head
Mike Cao 13 years ago
parent 67ad454592
commit b70f831c0e

@ -178,7 +178,7 @@ The register method also allows you to pass along parameters to your class const
// Get an instance of your class
// This will create an object with the defined parameters
//
// new Database('localhost', 'test', 'user', 'pass');
// new Database('localhost', 'mydb', 'user', 'pass');
//
$db = Flight::db();
@ -192,11 +192,11 @@ If you pass in an additional callback parameter, it will be executed immediately
By default, every time you load your class you will get a shared instance.
To get a new instance of a class, simply pass in `false` as a parameter:
// Shared instance of User
$shared = Flight::user();
// Shared instance of Database class
$shared = Flight::db();
// New instance of User
$new = Flight::user(false);
// New instance of Database class
$new = Flight::db(false);
Keep in mind that mapped methods have precedence over registered classes. If you declare both
using the same name, only the mapped method will be invoked.
@ -213,13 +213,6 @@ You can override this behavior by using the `map` method:
include 'errors/404.html';
});
Flight also has custom error handling which you can override:
Flight::map('error', function($e){
// Log error somewhere
log_error($e);
});
Flight also allows you to replace core components of the framework.
For example you can replace the default Router class with your own custom class:
@ -286,7 +279,7 @@ This should display:
Hello Fred! Have a nice day!
If you have defined multiple filters, you can break the chain by returning `false`:
If you have defined multiple filters, you can break the chain by returning `false` in any of your filter functions:
Flight::before('start', function(&$params, &$output){
echo 'one';
@ -372,9 +365,9 @@ It is common for websites to have a single layout template file with interchangi
Your view will then have saved variables called `header_content` and `body_content`. You can then render your layout by doing:
Flight::render('layout', array('title' => 'Home');
Flight::render('layout', array('title' => 'Home'));
If the template file looks like this:
If the template files looks like this:
header.php:
@ -460,7 +453,7 @@ When a URL can't be found, Flight calls the `notFound` method. The default behav
send an HTTP `404 Not Found` response with a simple message. You can override this behavior for your own needs:
Flight::map('notFound', function(){
// Display custom error page
// Handle not found
});
# Redirects
@ -469,6 +462,38 @@ You can redirect the current request by using the `redirect` method and passing
Flight::redirect('/new/location');
# Requests
Flight encapsulates the HTTP request into a single object, which can be accessed by doing:
$request = Flight::request();
The request object provides the following properties:
url - The URL being requested
base - The parent subdirectory of the URL
method - The request method (GET, POST, PUT, DELETE)
referrer - The referrer URL
ip - IP address of the client
ajax - Whether the request is an AJAX request
scheme - The server protocol (http, https)
user_agent - Browser information
body - Raw data from the request body
type - The content type
length - The content length
query - Query string parameters
data - Post parameters
cookies - Cookie parameters
files - Uploaded files
To access query string parameters, you can do:
$id = Flight::request()->query['id'];
You can also get the data using object notation:
$id = Flight::request()->query->id;
# HTTP Caching
Flight provides built-in support for HTTP level caching. If the caching condition is met,
@ -512,3 +537,55 @@ Calling `halt` will discard any response content up to that point.
If you want to stop the framework and output the current response, use the `stop` method:
Flight::stop();
# Framework Methods
## Core Methods
The following are Flight's core methods:
Flight::map($name, $callback) - Creates a custom framework method.
Flight::register($name, $class, [$params], [$callback]) - Registers a class to a framework method.
Flight::before($name, $callback) - Adds a filter before a framework method.
Flight::after($name, $callback) - Adds a filter after a framework method.
Flight::path($path) - Adds a path for autoloading classes.
Flight::get($key) - Gets a variable.
Flight::set($key, $value) - Sets a variable.
Flight::has($key) - Checks if a variable is set.
Flight::clear([$key]) - Clears a variable.
## Extensible Methods
The following methods are extensible, meaning you can filter and override them:
Flight::start() - Starts the framework.
Flight::stop() - Stops the framework and sends a response.
Flight::halt([$code], [$message]) - Stop the framework with an optional status code and message.
Flight::route($pattern, $callback) - Maps a URL pattern to a callback.
Flight::redirect($url, [$code]) - Redirects to another URL.
Flight::render($file, [$data], [$key]) - Renders a template file.
Flight::error($exception) - Sends an HTTP 500 response.
Flight::notFound() - Sends an HTTP 400 response.
Flight::etag($id, [$type]) - Performs ETag HTTP caching.
Flight::lastModified($time) - Performs last modified HTTP caching.
Flight::json($data) - Sends a JSON response.
All custom methods added with `map` and `register` can also be filtered.

@ -181,7 +181,7 @@ class Flight {
set_error_handler(array(__CLASS__, 'handleError'));
// Handle exceptions internally
set_exception_handler(array(__CLASS__, 'handleException'));
set_exception_handler(array(__CLASS__, 'error'));
// Turn off notices
error_reporting (E_ALL ^ E_NOTICE);
@ -241,22 +241,6 @@ class Flight {
}
}
/**
* Custom exception handler.
*/
public static function handleException(Exception $e) {
try {
static::error($e);
}
catch (Exception $ex) {
exit(
'<h1>500 Internal Server Error</h1>'.
'<h3>'.$ex->getMessage().'</h3>'.
'<pre>'.$ex->getTraceAsString().'</pre>'
);
}
}
/**
* Starts the framework.
*/
@ -295,26 +279,16 @@ class Flight {
->send();
}
/**
* Routes a URL to a callback function.
*
* @param string $pattern URL pattern to match
* @param callback $callback Callback function
*/
public static function _route($pattern, $callback) {
self::router()->map($pattern, $callback);
}
/**
* Stops processing and returns a given response.
*
* @param int $code HTTP status code
* @param int $msg Response text
* @param int $message Response message
*/
public static function _halt($code = 200, $text = '') {
public static function _halt($code = 200, $message = '') {
self::response(false)
->status($code)
->write($text)
->write($message)
->cache(false)
->send();
}
@ -322,20 +296,25 @@ class Flight {
/**
* Sends an HTTP 500 response for any errors.
*
* @param object $ex Exception
* @param object $e Exception
*/
public static function _error(Exception $e) {
if (self::get('flight.log_errors')) {
error_log($e->getMessage());
$msg = '<h1>500 Internal Server Error</h1>'.
'<h3>'.$e->getMessage().'</h3>'.
'<pre>'.$e->getTraceAsString().'</pre>';
try {
if (self::get('flight.log_errors')) {
error_log($e->getMessage());
}
self::response(false)
->status(500)
->write($msg)
->send();
}
catch (Exception $ex) {
exit($msg);
}
self::response(false)
->status(500)
->write(
'<h1>500 Internal Server Error</h1>'.
'<h3>'.$e->getMessage().'</h3>'.
'<pre>'.$e->getTraceAsString().'</pre>'
)
->send();
}
/**
@ -352,6 +331,16 @@ class Flight {
->send();
}
/**
* Routes a URL to a callback function.
*
* @param string $pattern URL pattern to match
* @param callback $callback Callback function
*/
public static function _route($pattern, $callback) {
self::router()->map($pattern, $callback);
}
/**
* Redirects the current request to another URL.
*
@ -381,6 +370,19 @@ class Flight {
}
}
/**
* Sends a JSON response.
*
* @param mixed $data Data to JSON encode
*/
public static function _json($data) {
self::response(false)
->status(200)
->header('Content-Type', 'application/json')
->write(json_encode($data))
->send();
}
/**
* Handles ETag HTTP caching.
*
@ -409,19 +411,6 @@ class Flight {
self::halt(304);
}
}
/**
* Sends a JSON response.
*
* @param mixed $data Data to JSON encode
*/
public static function _json($data) {
self::response(false)
->status(200)
->header('Content-Type', 'application/json')
->write(json_encode($data))
->send();
}
}
// Initialize the framework on include

@ -8,6 +8,8 @@
namespace flight\net;
use flight\util\Collection;
/**
* The Request class represents an HTTP request. Data from
* all the super globals $_GET, $_POST, $_COOKIE, and $_FILES
@ -51,10 +53,10 @@ class Request {
'body' => file_get_contents('php://input'),
'type' => $_SERVER['CONTENT_TYPE'],
'length' => $_SERVER['CONTENT_LENGTH'],
'query' => $_GET,
'data' => $_POST,
'cookies' => $_COOKIE,
'files' => $_FILES
'query' => new Collection($_GET),
'data' => new Collection($_POST),
'cookies' => new Collection($_COOKIE),
'files' => new Collection($_FILES)
);
}
@ -79,8 +81,9 @@ class Request {
$this->url = '/';
}
else {
$this->query = self::parseQuery($this->url);
$_GET = $this->query;
$_GET = self::parseQuery($this->url);
$this->query->setData($_GET);
}
}

@ -0,0 +1,206 @@
<?php
/**
* Flight: An extensible micro-framework.
*
* @copyright Copyright (c) 2011, Mike Cao <mike@mikecao.com>
* @license http://www.opensource.org/licenses/mit-license.php
*/
namespace flight\util;
/**
* The Collection class allows you to access a set of data
* using both array and object notation.
*/
class Collection implements \ArrayAccess, \Iterator, \Countable {
/**
* Collection data.
*
* @var array
*/
private $data;
/**
* Constructor.
*
* @param array $data Initial data
*/
public function __construct(array $data = array()) {
$this->data = $data;
}
/**
* Gets an item.
*
* @param string $key Key
* @return mixed Value
*/
public function __get($key) {
return $this->data[$key];
}
/**
* Set an item.
*
* @param string $key Key
* @param mixed $value Value
*/
public function __set($key, $value) {
$this->data[$key] = $value;
}
/**
* Checks if an item exists.
*
* @param string $key Key
* @return bool Item status
*/
public function __isset($key) {
return isset($this->data[$key]);
}
/**
* Removes an item.
*
* @param string $key Key
*/
public function __unset($key) {
unset($this->data[$key]);
}
/**
* Gets an item at the offset.
*
* @param string $offset Offset
* @return mixed Value
*/
public function offsetGet($offset) {
return isset($this->data[$offset]) ? $this->data[$offset] : null;
}
/**
* Sets an item at the offset.
*
* @param string $offset Offset
* @param mixed $value Value
*/
public function offsetSet($offset, $value) {
if (is_null($offset)) {
$this->data[] = $value;
}
else {
$this->data[$offset] = $value;
}
}
/**
* Checks if an item exists at the offset.
*
* @param string $offset Offset
* @return bool Item status
*/
public function offsetExists($offset) {
return isset($this->data[$offset]);
}
/**
* Removes an item at the offset.
*
* @param string $offset Offset
*/
public function offsetUnset($offset) {
unset($this->data[$offset]);
}
/**
* Resets the collection.
*/
public function rewind() {
reset($this->data);
}
/**
* Gets current collection item.
*
* @return mixed Value
*/
public function current() {
return current($this->data);
}
/**
* Gets current collection key.
*
* @return mixed Value
*/
public function key() {
return key($this->data);
}
/**
* Gets the next collection value.
*
* @return mixed Value
*/
public function next()
{
return next($this->data);
}
/**
* Checks if the current collection key is valid.
*
* @return bool Key status
*/
public function valid()
{
$key = key($this->data);
return ($key !== NULL && $key !== FALSE);
}
/**
* Gets the size of the collection.
*
* @return int Collection size
*/
public function count() {
$count = iterator_count($this);
$this->rewind();
return $count;
}
/**
* Gets the item keys.
*
* @return array Collection keys
*/
public function keys() {
return array_keys($this->data);
}
/**
* Gets the collection data.
*
* @return array Collection data
*/
public function getData() {
return $this->data;
}
/**
* Sets the collection data.
*
* @param array $data New collection data
*/
public function setData(array $data) {
$this->data = $data;
}
/**
* Removes all items from the collection.
*/
public function clear() {
$this->data = array();
}
}
?>
Loading…
Cancel
Save