mirror of
https://github.com/jimeh/php-rack.git
synced 2026-02-18 19:36:39 +00:00
initial commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.DS_Store
|
||||
|
||||
19
app/api.php
Normal file
19
app/api.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
class Api {
|
||||
|
||||
function __construct (&$app) {
|
||||
$this->app =& $app;
|
||||
}
|
||||
|
||||
function call (&$env) {
|
||||
if ( preg_match("/^\/api\/([a-z]{1}[a-z0-9]*)/i", $env["PATH_INFO"], $match) ) {
|
||||
return array(200, array("Content-Type" => "text/json"), array("{api_call: \"".$match[1]."\"}"));
|
||||
} else {
|
||||
return $this->app->call($env);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
16
app/app.php
Normal file
16
app/app.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
class App {
|
||||
|
||||
function call (&$env) {
|
||||
if ( $env["PATH_INFO"] == "/" ) {
|
||||
return array(200, array("Content-Type" => "text/html"), array("Welcome Home"));
|
||||
} elseif ( preg_match("/^\/about\/?/i", $env["PATH_INFO"]) ) {
|
||||
return array(200, array("Content-Type" => "text/html"), array("Rack-style middleware is cool."));
|
||||
}
|
||||
return Rack::not_found();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
29
app/format.php
Normal file
29
app/format.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
class Format {
|
||||
|
||||
function __construct (&$app) {
|
||||
$this->app =& $app;
|
||||
}
|
||||
|
||||
function call (&$env) {
|
||||
|
||||
// available formats
|
||||
$formats = array("txt" => "text/plain", "xml" => "application/xml");
|
||||
|
||||
// call the next middleware in the stack
|
||||
list($status, $headers, $body) = $this->app->call($env);
|
||||
|
||||
// do something with response headers
|
||||
foreach( $formats as $key => $value ) {
|
||||
if ( !empty($env["request.vars"]["format"]) && $env["request.get"]["format"] == $key ) {
|
||||
$headers["Content-Type"] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return array($status, $headers, $body);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
176
lib/rack.php
Normal file
176
lib/rack.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
/*
|
||||
|
||||
PHP Rack
|
||||
|
||||
Copyright (c) 2010 Jim Myhrberg.
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
class Rack {
|
||||
|
||||
public static
|
||||
$middleware = array(),
|
||||
$env = array();
|
||||
|
||||
private static
|
||||
# default headers
|
||||
$headers = array("Content-Type" => "text/html"),
|
||||
$constructed = false,
|
||||
$ob_started = false;
|
||||
|
||||
|
||||
public static function init ($middleware = array()) {
|
||||
|
||||
// quick initialization
|
||||
if ( !empty($middleware) && is_array($middleware) ) {
|
||||
self::$middleware = array_merge(self::$middleware, $middleware);
|
||||
}
|
||||
|
||||
// don't output anything before Rack has output it's headers
|
||||
ob_start();
|
||||
self::$ob_started = true;
|
||||
}
|
||||
|
||||
|
||||
public static function add ($name, $file = null) {
|
||||
if ( !self::$ob_started ) self::init();
|
||||
if ( !self::$constructed ) {
|
||||
self::$middleware[$name] = true;
|
||||
self::require_file($file);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static function insert_before ($target, $name, $file = null) {
|
||||
if ( !self::$ob_started ) self::init();
|
||||
if ( !self::$constructed ) {
|
||||
if ( array_key_exists($target, self::$middleware) ) {
|
||||
$keys = array_keys(self::$middleware);
|
||||
$length = count($keys);
|
||||
$middleware = array();
|
||||
for ( $i=0; $i < $length; $i++ ) {
|
||||
if ( $keys[$i] == $target ) {
|
||||
$middleware[$name] = true;
|
||||
}
|
||||
$middleware[$keys[$i]] =& self::$middleware[$keys[$i]];
|
||||
}
|
||||
self::$middleware = $middleware;
|
||||
self::require_file($file);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static function insert_after ($target, $name, $file = null) {
|
||||
if ( !self::$ob_started ) self::init();
|
||||
if ( !self::$constructed ) {
|
||||
if ( array_key_exists($target, self::$middleware) ) {
|
||||
$keys = array_keys(self::$middleware);
|
||||
$length = count($keys);
|
||||
$middleware = array();
|
||||
for ( $i=0; $i < $length; $i++ ) {
|
||||
$middleware[$keys[$i]] =& self::$middleware[$keys[$i]];
|
||||
if ( $keys[$i] == $target ) {
|
||||
$middleware[$name] = true;
|
||||
}
|
||||
}
|
||||
self::$middleware = $middleware;
|
||||
self::require_file($file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static function not_found () {
|
||||
return array(404, array("Content-Type" => "text/html"), "Not Found");
|
||||
}
|
||||
|
||||
|
||||
public static function run () {
|
||||
|
||||
// build ENV
|
||||
self::$env =& $_SERVER;
|
||||
if ( strstr($_SERVER['REQUEST_URI'], '?') ) {
|
||||
self::$env["PATH_INFO"] = substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], '?'));
|
||||
} else {
|
||||
self::$env["PATH_INFO"] = $_SERVER['REQUEST_URI'];
|
||||
}
|
||||
self::$env["request.vars"] =& $_REQUEST;
|
||||
self::$env["request.get"] =& $_GET;
|
||||
self::$env["request.post"] =& $_POST;
|
||||
self::$env["request.files"] =& $_FILES;
|
||||
self::$env["request.method"] =& $_SERVER["REQUEST_METHOD"];
|
||||
self::$env["cookies"] =& $_COOKIE;
|
||||
|
||||
// construct middlewares
|
||||
self::$constructed = true;
|
||||
$middleware = array_reverse(self::$middleware);
|
||||
$previous = null;
|
||||
foreach( $middleware as $key => $value ) {
|
||||
self::$middleware[$key] = new $key($previous);
|
||||
$previous =& self::$middleware[$key];
|
||||
}
|
||||
|
||||
// call the middleware stack
|
||||
reset(self::$middleware);
|
||||
$first = current(array_keys(self::$middleware));
|
||||
list($status, $headers, $body) = self::$middleware[$first]->call(self::$env);
|
||||
|
||||
// send headers
|
||||
header(self::$env["SERVER_PROTOCOL"]." ".$status);
|
||||
$headers = array_merge(self::$headers, $headers);
|
||||
foreach( $headers as $key => $value ) {
|
||||
header($key.": ".$value);
|
||||
}
|
||||
|
||||
// output any buffered content from middlewares
|
||||
$buffer = ob_get_contents();
|
||||
ob_end_clean();
|
||||
if ( !empty($buffer) ) {
|
||||
echo $buffer;
|
||||
}
|
||||
|
||||
// output body
|
||||
if ( is_array($body) ) {
|
||||
echo implode("", $body);
|
||||
} else {
|
||||
echo $body;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static function require_file ($file = null) {
|
||||
if ( $file != null && is_file($file) ) {
|
||||
require($file);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
10
public/.htaccess
Normal file
10
public/.htaccess
Normal file
@@ -0,0 +1,10 @@
|
||||
RewriteEngine On
|
||||
|
||||
RewriteRule ^.*\.svn.*$ /404
|
||||
|
||||
RewriteRule ^$ index.html [QSA]
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !favicon.ico
|
||||
RewriteCond %{REQUEST_FILENAME} !robots.txt
|
||||
RewriteRule ^(.*)$ /rackup.php [QSA,L]
|
||||
16
public/rackup.php
Normal file
16
public/rackup.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
define("ROOT", dirname(dirname(__FILE__)));
|
||||
|
||||
require(ROOT."/lib/rack.php");
|
||||
|
||||
// add some middlewares
|
||||
Rack::add("Format", ROOT."/app/format.php");
|
||||
Rack::add("App", ROOT."/app/app.php");
|
||||
|
||||
// insert the Api middleware before App
|
||||
Rack::insert_before("App", "Api", ROOT."/app/api.php");
|
||||
|
||||
Rack::run();
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user