PHP Micro-framework
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

368 lines
11 KiB

<?php
class Harmonious_Components_Request implements IHarmonious_Component{
const METHOD_HEAD = 'HEAD';
const METHOD_GET = 'GET';
const METHOD_POST = 'POST';
const METHOD_PUT = 'PUT';
const METHOD_DELETE = 'DELETE';
const METHOD_OPTIONS = 'OPTIONS';
const METHOD_OVERRIDE = '_METHOD';
/**
* @var string Request method (ie. "GET", "POST", "PUT", "DELETE", "HEAD")
*/
protected $method;
/**
* @var array Key-value array of HTTP request headers
*/
protected $headers;
/**
* @var array Names of additional headers to parse from the current
* HTTP request that are not prefixed with "HTTP_"
*/
protected $additionalHeaders = array('content-type', 'content-length', 'php-auth-user', 'php-auth-pw', 'auth-type', 'x-requested-with');
/**
* @var array Key-value array of cookies sent with the
* current HTTP request
*/
protected $cookies;
/**
* @var array Key-value array of HTTP GET parameters
*/
protected $get;
/**
* @var array Key-value array of HTTP POST parameters
*/
protected $post;
/**
* @var array Key-value array of HTTP PUT parameters
*/
protected $put;
/**
* @var string Raw body of HTTP request
*/
protected $body;
/**
* @var string Content type of HTTP request
*/
protected $contentType;
/**
* @var string Resource URI (ie. "/person/1")
*/
protected $resource;
/**
* @var string The root URI of the Slim application without trailing slash.
* This will be "" if the app is installed at the web
* document root. If the app is installed in a
* sub-directory "/foo", this will be "/foo".
*/
protected $root;
/**
* Constructor
*/
public function __construct(Harmonious $app) {
$this->method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : false;
$this->headers = $this->loadHttpHeaders();
$this->body = @file_get_contents('php://input');
$this->get = self::stripSlashesIfMagicQuotes($_GET);
$this->post = self::stripSlashesIfMagicQuotes($_POST);
$this->put = self::stripSlashesIfMagicQuotes($this->loadPutParameters());
$this->cookies = self::stripSlashesIfMagicQuotes($_COOKIE);
$this->root = Slim_Http_Uri::getBaseUri(true);
$this->resource = Slim_Http_Uri::getUri(true);
$this->checkForHttpMethodOverride();
}
/**
* Is this a GET request?
* @return bool
*/
public function isGet() {
return $this->method === self::METHOD_GET;
}
/**
* Is this a POST request?
* @return bool
*/
public function isPost() {
return $this->method === self::METHOD_POST;
}
/**
* Is this a PUT request?
* @return bool
*/
public function isPut() {
return $this->method === self::METHOD_PUT;
}
/**
* Is this a DELETE request?
* @return bool
*/
public function isDelete() {
return $this->method === self::METHOD_DELETE;
}
/**
* Is this a HEAD request?
* @return bool
*/
public function isHead() {
return $this->method === self::METHOD_HEAD;
}
/**
* Is this a OPTIONS request?
* @return bool
*/
public function isOptions() {
return $this->method === self::METHOD_OPTIONS;
}
/**
* Is this a XHR request?
* @return bool
*/
public function isAjax() {
return ( $this->params('isajax') || $this->headers('X_REQUESTED_WITH') === 'XMLHttpRequest' );
}
/**
* Fetch a PUT|POST|GET parameter value
*
* The preferred method to fetch the value of a
* PUT, POST, or GET parameter (searched in that order).
*
* @param string $key The paramter name
* @return string|null The value of parameter, or NULL if parameter not found
*/
public function params( $key ) {
foreach ( array('put', 'post', 'get') as $dataSource ) {
$source = $this->$dataSource;
if ( isset($source[(string)$key]) ) {
return $source[(string)$key];
}
}
return null;
}
/**
* Fetch GET parameter(s)
* @param string $key Name of parameter
* @return array|string|null All parameters, parameter value if $key
* and parameter exists, or NULL if $key
* and parameter does not exist.
*/
public function get( $key = null ) {
return $this->arrayOrArrayValue($this->get, $key);
}
/**
* Fetch POST parameter(s)
* @param string $key Name of parameter
* @return array|string|null All parameters, parameter value if $key
* and parameter exists, or NULL if $key
* and parameter does not exist.
*/
public function post( $key = null ) {
return $this->arrayOrArrayValue($this->post, $key);
}
/**
* Fetch PUT parameter(s)
* @param string $key Name of parameter
* @return array|string|null All parameters, parameter value if $key
* and parameter exists, or NULL if $key
* and parameter does not exist.
*/
public function put( $key = null ) {
return $this->arrayOrArrayValue($this->put, $key);
}
/**
* Fetch COOKIE value(s)
* @param string $key The cookie name
* @return array|string|null All parameters, parameter value if $key
* and parameter exists, or NULL if $key
* and parameter does not exist.
*/
public function cookies( $key = null ) {
return $this->arrayOrArrayValue($this->cookies, $key);
}
/**
* Get HTTP request header
* @param string $key The header name
* @return array|string|null All parameters, parameter value if $key
* and parameter exists, or NULL if $key
* and parameter does not exist.
*/
public function headers( $key = null ) {
return is_null($key) ? $this->headers : $this->arrayOrArrayValue($this->headers, $this->convertHttpHeaderName($key));
}
/**
* Get HTTP request body
* @return string|false String, or FALSE if body could not be read
*/
public function getBody() {
return $this->body;
}
/**
* Get HTTP method
* @return string
*/
public function getMethod() {
return $this->method;
}
/**
* Get HTTP request content type
* @return string
*/
public function getContentType() {
if ( !isset($this->contentType) ) {
$contentType = 'application/x-www-form-urlencoded';
$header = $this->headers('CONTENT_TYPE');
if ( !is_null($header) ) {
$headerParts = preg_split('/\s*;\s*/', $header);
$contentType = $headerParts[0];
}
$this->contentType = $contentType;
}
return $this->contentType;
}
/**
* Get HTTP request resource URI
* @return string
*/
public function getResourceUri() {
return $this->resource;
}
/**
* Get HTTP request root URI
* @return string
*/
public function getRootUri() {
return $this->root;
}
/**
* Fetch array or array value
* @param array $array
* @param string $key
* @return array|mixed Array if key is null, else array value
*/
protected function arrayOrArrayValue( array &$array, $key = null ) {
return is_null($key) ? $array : $this->arrayValueForKey($array, $key);
}
/**
* Fetch value from array
* @return mixed|null
*/
protected function arrayValueForKey( array &$array, $key ) {
return isset($array[(string)$key]) ? $array[(string)$key] : null;
}
/**
* Strip slashes from string or array of strings
* @param array|string $rawData
* @return array|string
*/
public static function stripSlashesIfMagicQuotes( $rawData ) {
/* if ( get_magic_quotes_gpc() ) {
return is_array($rawData) ? array_map(array('self', 'stripSlashesIfMagicQuotes'), $rawData) : stripslashes($rawData);
} else {
return $rawData;
}*/
if (is_array($rawData)) {
return array_map(array('self', 'stripSlashesIfMagicQuotes'), $rawData);
} else {
$data = $rawData;
// $data = stripslashes($rawData);
// $data = htmlspecialchars($data);
// $data = strip_tags($data);
return $data;
}
}
/**
* Get PUT parameters
* @return array Key-value array of HTTP request PUT parameters
*/
protected function loadPutParameters() {
if ( $this->getContentType() === 'application/x-www-form-urlencoded' ) {
$input = is_string($this->body) ? $this->body : '';
if ( function_exists('mb_parse_str') ) {
mb_parse_str($input, $output);
} else {
parse_str($input, $output);
}
return $output;
} else {
return array();
}
}
/**
* Get HTTP request headers
* @return array Key-value array of HTTP request headers
*/
protected function loadHttpHeaders() {
$headers = array();
foreach ( $_SERVER as $key => $value ) {
$key = $this->convertHttpHeaderName($key);
if ( strpos($key, 'http-') === 0 || in_array($key, $this->additionalHeaders) ) {
$name = str_replace('http-', '', $key);
$headers[$name] = $value;
}
}
return $headers;
}
/**
* Convert HTTP header name
* @return string
*/
protected function convertHttpHeaderName( $name ) {
return str_replace('_', '-', strtolower($name));
}
/**
* Check for HTTP request method override
*
* Because traditional web browsers do not support PUT and DELETE
* HTTP methods, we use a hidden form input field to
* mimic PUT and DELETE requests. We check for this override here.
*
* @return void
*/
protected function checkForHttpMethodOverride() {
if ( isset($this->post[self::METHOD_OVERRIDE]) ) {
$this->method = $this->post[self::METHOD_OVERRIDE];
unset($this->post[self::METHOD_OVERRIDE]);
if ( $this->isPut() ) {
$this->put = $this->post;
}
}
}
}
?>