Development

- Optimised Input and Input-related features.
- Removed InputCollection class.
- Changed more foreach to for.
- Updated documentation.
This commit is contained in:
Simon Sessingø
2016-11-24 22:44:58 +01:00
parent b2f23c6c7d
commit abe427ff59
11 changed files with 263 additions and 188 deletions
+15
View File
@@ -0,0 +1,15 @@
<?php
namespace Pecee\Http\Input;
interface IInputItem
{
public function getIndex();
public function getName();
public function getValue();
public function __toString();
}
+79 -49
View File
@@ -6,19 +6,19 @@ use Pecee\Http\Request;
class Input
{
/**
* @var \Pecee\Http\Input\InputCollection
* @var array
*/
public $get;
public $get = [];
/**
* @var \Pecee\Http\Input\InputCollection
* @var array
*/
public $post;
public $post = [];
/**
* @var \Pecee\Http\Input\InputCollection
* @var array
*/
public $file;
public $file = [];
/**
* @var Request
@@ -36,10 +36,6 @@ class Input
{
$this->request = $request;
$this->post = new InputCollection();
$this->get = new InputCollection();
$this->file = new InputCollection();
if ($request->getMethod() !== 'get') {
$requestContentType = $request->getHeader('http-content-type');
@@ -60,6 +56,7 @@ class Input
if ($this->invalidContentType === false) {
$this->parseInputs();
}
}
protected function parseInputs()
@@ -76,7 +73,21 @@ class Input
$key = $keys[$i];
$value = $_GET[$key];
$this->get->{$key} = new InputItem($key, $value);
// Handle array input
if (is_array($value) === false) {
$this->get[$key] = new InputItem($key, $value);
continue;
}
$subMax = count($value) - 1;
$keys = array_keys($value);
$output = [];
for ($i = $subMax; $i >= 0; $i--) {
$output[$keys[$i]] = new InputItem($key, $value[$keys[$i]]);
}
$this->get[$key] = $output;
}
}
@@ -99,7 +110,21 @@ class Input
$key = $keys[$i];
$value = $postVars[$key];
$this->post->{strtolower($key)} = new InputItem($key, $value);
// Handle array input
if (is_array($value) === false) {
$this->post[$key] = new InputItem($key, $value);
continue;
}
$subMax = count($value) - 1;
$keys = array_keys($value);
$output = [];
for ($i = $subMax; $i >= 0; $i--) {
$output[$keys[$i]] = new InputItem($key, $value[$keys[$i]]);
}
$this->post[$key] = $output;
}
}
@@ -119,56 +144,66 @@ class Input
// Handle array input
if (is_array($value['name']) === false) {
$values['index'] = $key;
$this->file->{strtolower($key)} = InputFile::createFromArray($values);
$this->file[$key] = InputFile::createFromArray(array_merge($value, $values));
continue;
}
$output = new InputCollection();
$subMax = count($value['name']) - 1;
$keys = array_keys($value['name']);
$output = [];
foreach ($value['name'] as $k => $val) {
for ($i = $subMax; $i >= 0; $i--) {
$output->{$k} = InputFile::createFromArray([
$output[$keys[$i]] = InputFile::createFromArray([
'index' => $key,
'error' => $value['error'][$k],
'tmp_name' => $value['tmp_name'][$k],
'type' => $value['type'][$k],
'size' => $value['size'][$k],
'name' => $value['name'][$k],
'error' => $value['error'][$keys[$i]],
'tmp_name' => $value['tmp_name'][$keys[$i]],
'type' => $value['type'][$keys[$i]],
'size' => $value['size'][$keys[$i]],
'name' => $value['name'][$keys[$i]],
]);
}
$this->file->{strtolower($key)} = $output;
$this->file[$key] = $output;
}
}
}
public function getObject($index, $default = null)
public function findPost($index, $default = null)
{
$key = (strpos($index, '[') > -1) ? substr($index, strpos($index, '[') + 1, strpos($index, ']') - strlen($index)) : null;
$index = (strpos($index, '[') > -1) ? substr($index, 0, strpos($index, '[')) : $index;
return isset($this->post[$index]) ? $this->post[$index] : $default;
}
$element = $this->get->findFirst($index);
public function findFile($index, $default = null)
{
return isset($this->file[$index]) ? $this->file[$index] : $default;
}
if ($element !== null) {
return ($key !== null) ? $element[$key] : $element;
public function findGet($index, $default = null)
{
return isset($this->get[$index]) ? $this->get[$index] : $default;
}
public function getObject($index, $default = null, $method = null)
{
$element = null;
if ($method === null || strtolower($method) === 'get') {
$element = $this->findGet($index);
}
if ($this->request->getMethod() !== 'get') {
$element = $this->post->findFirst($index);
if ($element !== null) {
return ($key !== null) ? $element[$key] : $element;
}
$element = $this->file->findFirst($index);
if ($element !== null) {
return ($key !== null) ? $element[$key] : $element;
}
if ($element === null && $method === null || strtolower($method) === 'post') {
$element = $this->findPost($index);
}
return $default;
if ($element === null && $method === null || strtolower($method) === 'file') {
$element = $this->findFile($index);
}
return ($element === null) ? $default : $element;
}
/**
@@ -180,18 +215,13 @@ class Input
*/
public function get($index, $default = null)
{
$item = $this->getObject($index);
$input = $this->getObject($index, $default);
if ($item !== null) {
if ($item instanceof InputCollection || $item instanceof InputFile) {
return $item;
}
return (!is_array($item->getValue()) && trim($item->getValue()) === '') ? $default : $item;
if ($input instanceof InputItem) {
return (trim($input->getValue()) === '') ? $default : $input->getValue();
}
return $default;
return $input;
}
public function exists($index)
-91
View File
@@ -1,91 +0,0 @@
<?php
namespace Pecee\Http\Input;
class InputCollection implements \IteratorAggregate
{
protected $data = [];
/**
* Search for input element matching index.
*
* @param string $index
* @param string|null $default
* @return InputItem|mixed
*/
public function findFirst($index, $default = null)
{
if (count($this->data) > 0) {
if (isset($this->data[$index])) {
return $this->data[$index];
}
foreach ($this->data as $key => $input) {
if (strtolower($index) === strtolower($key)) {
return $input;
}
}
}
return $default;
}
/**
* Get input element value matching index
*
* @param string $index
* @param string|null $default
* @return string|null
*/
public function get($index, $default = null)
{
$input = $this->findFirst($index);
if ($input !== null && trim($input->getValue()) !== '') {
return $input->getValue();
}
return $default;
}
/**
* @param string $index
* @throws \InvalidArgumentException
* @return InputItem
*/
public function __get($index)
{
$item = $this->findFirst($index);
// Ensure that item are always available
if ($item === null) {
$this->data[$index] = new InputItem($index, null);
return $this->data[$index];
}
return $item;
}
public function __set($index, $value)
{
$this->data[$index] = $value;
}
public function getData()
{
return $this->data;
}
/**
* Retrieve an external iterator
* @link http://php.net/manual/en/iteratoraggregate.getiterator.php
* @return \Traversable An instance of an object implementing <b>Iterator</b> or
* <b>Traversable</b>
* @since 5.0.0
*/
public function getIterator()
{
return new \ArrayIterator($this->data);
}
}
+56 -13
View File
@@ -1,13 +1,39 @@
<?php
namespace Pecee\Http\Input;
class InputFile extends InputItem
class InputFile implements IInputItem
{
public $index;
public $name;
public $size;
public $type;
public $error;
public $tmpName;
public function __construct($index)
{
$this->index = $index;
// Make the name human friendly, by replace _ with space
$this->name = ucfirst(str_replace('_', ' ', $this->index));
}
/**
* @return string
*/
public function getIndex()
{
return $this->index;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return string
*/
@@ -60,6 +86,13 @@ class InputFile extends InputItem
return file_get_contents($this->tmpName);
}
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Set file temp. name
* @param string $name
@@ -68,6 +101,7 @@ class InputFile extends InputItem
public function setTmpName($name)
{
$this->tmpName = $name;
return $this;
}
@@ -79,6 +113,7 @@ class InputFile extends InputItem
public function setSize($size)
{
$this->size = $size;
return $this;
}
@@ -90,6 +125,7 @@ class InputFile extends InputItem
public function setType($type)
{
$this->type = $type;
return $this;
}
@@ -101,6 +137,7 @@ class InputFile extends InputItem
public function setError($error)
{
$this->error = (int)$error;
return $this;
}
@@ -109,7 +146,8 @@ class InputFile extends InputItem
return $this->getTmpName();
}
public function hasError() {
public function hasError()
{
return ($this->getError() !== 0);
}
@@ -120,28 +158,33 @@ class InputFile extends InputItem
*/
public static function createFromArray(array $values)
{
if(!isset($values['index'])) {
if (!isset($values['index'])) {
throw new \InvalidArgumentException('Index key is required');
}
$input = new static($values['index']);
$input->setError((isset($values['error']) ? $values['error'] : null));
$input->setName((isset($values['name']) ? $values['name'] : null));
$input->setSize((isset($values['size']) ? $values['size'] : null));
$input->setType((isset($values['type']) ? $values['type'] : null));
$input->setTmpName((isset($values['tmp_name']) ? $values['tmp_name'] : null));
$input->setError(isset($values['error']) ? $values['error'] : null);
$input->setName(isset($values['name']) ? $values['name'] : null);
$input->setSize(isset($values['size']) ? $values['size'] : null);
$input->setType(isset($values['type']) ? $values['type'] : null);
$input->setTmpName(isset($values['tmp_name']) ? $values['tmp_name'] : null);
return $input;
}
public function toArray() {
public function toArray()
{
return [
'tmp_name' => $this->tmpName,
'type' => $this->type,
'size' => $this->size,
'name' => $this->name,
'error' => $this->error,
'type' => $this->type,
'size' => $this->size,
'name' => $this->name,
'error' => $this->error,
];
}
public function __toString()
{
return $this->getValue();
}
}
+9 -9
View File
@@ -1,7 +1,7 @@
<?php
namespace Pecee\Http\Input;
class InputItem
class InputItem implements IInputItem
{
public $index;
public $name;
@@ -16,6 +16,14 @@ class InputItem
$this->name = ucfirst(str_replace('_', ' ', $this->index));
}
/**
* @return string
*/
public function getIndex()
{
return $this->index;
}
/**
* @return string
*/
@@ -32,14 +40,6 @@ class InputItem
return $this->value;
}
/**
* @return string
*/
public function getIndex()
{
return $this->index;
}
/**
* Set input name
* @param string $name
@@ -34,7 +34,11 @@ class BaseCsrfVerifier implements IMiddleware
return false;
}
foreach ($this->except as $url) {
$max = count($this->except) - 1;
for ($i = $max; $i >= 0; $i--) {
$url = $this->except[$i];
$url = rtrim($url, '/');
if ($url[strlen($url) - 1] === '*') {
$url = rtrim($url, '*');
@@ -43,7 +47,7 @@ class BaseCsrfVerifier implements IMiddleware
$skip = ($url === rtrim($request->getUri(), '/'));
}
if ($skip) {
if ($skip === true) {
return true;
}
}
@@ -56,14 +60,14 @@ class BaseCsrfVerifier implements IMiddleware
if ($request->getMethod() !== 'get' && !$this->skip($request)) {
$token = $request->getInput()->post->get(static::POST_KEY);
$token = $request->getInput()->get(static::POST_KEY, null, 'post');
// If the token is not posted, check headers for valid x-csrf-token
if ($token === null) {
$token = $request->getHeader(static::HEADER_KEY);
}
if (!$this->csrfToken->validate($token)) {
if ($this->csrfToken->validate($token) === false) {
throw new TokenMismatchException('Invalid csrf-token.');
}
+9 -3
View File
@@ -25,9 +25,15 @@ class Request
{
$this->headers = [];
foreach ($_SERVER as $name => $value) {
$this->headers[strtolower($name)] = $value;
$this->headers[strtolower(str_replace('_', '-', $name))] = $value;
$max = count($_SERVER) - 1;
$keys = array_keys($_SERVER);
for($i = $max; $i >= 0; $i--) {
$key = $keys[$i];
$value = $_SERVER[$key];
$this->headers[strtolower($key)] = $value;
$this->headers[strtolower(str_replace('_', '-', $key))] = $value;
}
}
@@ -59,7 +59,12 @@ class RouteController extends LoadableRoute implements IControllerRoute
/* Remove requestType from method-name, if it exists */
if ($method !== null) {
foreach (static::$requestTypes as $requestType) {
$max = count(static::$requestTypes);
for ($i = 0; $i < $max; $i++) {
$requestType = static::$requestTypes[$i];
if (stripos($method, $requestType) === 0) {
$method = substr($method, strlen($requestType));
break;
+5 -1
View File
@@ -19,8 +19,12 @@ class RouteGroup extends Route implements IGroupRoute
public function matchDomain(Request $request)
{
if (count($this->domains) > 0) {
foreach ($this->domains as $domain) {
$max = count($this->domains);
for ($i = 0; $i < $max; $i++) {
$domain = $this->domains[$i];
$parameters = $this->parseParameters($domain, $request->getHost(), '.*');
if ($parameters !== null) {
+7 -3
View File
@@ -140,8 +140,12 @@ class Router
protected function processRoutes(array $routes, IGroupRoute $group = null, IRoute $parent = null)
{
// Loop through each route-request
$max = count($routes) - 1;
/* @var $route IRoute */
foreach ($routes as $route) {
for ($i = $max; $i >= 0; $i--) {
$route = $routes[$i];
if ($route instanceof IGroupRoute) {
@@ -238,10 +242,10 @@ class Router
$this->originalUrl = $this->request->getUri();
}
$max = count($this->processedRoutes);
$max = count($this->processedRoutes) - 1;
/* @var $route IRoute */
for ($i = 0; $i < $max; $i++) {
for ($i = $max; $i >= 0; $i--) {
$route = $this->processedRoutes[$i];