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 // Get an instance of your class
// This will create an object with the defined parameters // This will create an object with the defined parameters
// //
// new Database('localhost', 'test', 'user', 'pass'); // new Database('localhost', 'mydb', 'user', 'pass');
// //
$db = Flight::db(); $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. 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: To get a new instance of a class, simply pass in `false` as a parameter:
// Shared instance of User // Shared instance of Database class
$shared = Flight::user(); $shared = Flight::db();
// New instance of User // New instance of Database class
$new = Flight::user(false); $new = Flight::db(false);
Keep in mind that mapped methods have precedence over registered classes. If you declare both 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. 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'; 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. 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: 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! 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){ Flight::before('start', function(&$params, &$output){
echo 'one'; 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: 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: 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: send an HTTP `404 Not Found` response with a simple message. You can override this behavior for your own needs:
Flight::map('notFound', function(){ Flight::map('notFound', function(){
// Display custom error page // Handle not found
}); });
# Redirects # Redirects
@ -469,6 +462,38 @@ You can redirect the current request by using the `redirect` method and passing
Flight::redirect('/new/location'); 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 # HTTP Caching
Flight provides built-in support for HTTP level caching. If the caching condition is met, 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: If you want to stop the framework and output the current response, use the `stop` method:
Flight::stop(); 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')); set_error_handler(array(__CLASS__, 'handleError'));
// Handle exceptions internally // Handle exceptions internally
set_exception_handler(array(__CLASS__, 'handleException')); set_exception_handler(array(__CLASS__, 'error'));
// Turn off notices // Turn off notices
error_reporting (E_ALL ^ E_NOTICE); 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. * Starts the framework.
*/ */
@ -295,26 +279,16 @@ class Flight {
->send(); ->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. * Stops processing and returns a given response.
* *
* @param int $code HTTP status code * @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) self::response(false)
->status($code) ->status($code)
->write($text) ->write($message)
->cache(false) ->cache(false)
->send(); ->send();
} }
@ -322,20 +296,25 @@ class Flight {
/** /**
* Sends an HTTP 500 response for any errors. * Sends an HTTP 500 response for any errors.
* *
* @param object $ex Exception * @param object $e Exception
*/ */
public static function _error(Exception $e) { public static function _error(Exception $e) {
if (self::get('flight.log_errors')) { $msg = '<h1>500 Internal Server Error</h1>'.
error_log($e->getMessage()); '<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(); ->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. * 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. * Handles ETag HTTP caching.
* *
@ -409,19 +411,6 @@ class Flight {
self::halt(304); 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 // Initialize the framework on include

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