diff --git a/README.md b/README.md
index 628aef2..010838e 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,7 @@ The goal of this project is to create a router that is 100% compatible with the
- Optional parameters
- Sub-domain routing
- Custom boot managers to redirect urls to other routes
+- Input manager; to manage `GET`, `POST` params.
## Initialising the router
@@ -325,6 +326,75 @@ $route->setClass('Example\MyCustomClass');
$route->setMethod('hello');
```
+## Using the Input class to manage parameters
+
+We've added the `Input` class to easy access parameters from your Controller-classes.
+
+**Return single parameter value (matches both GET, POST, FILE):**
+```php
+$value = Request::getInstance()->getInput()->get('name');
+```
+
+**Return parameter object (matches both GET, POST, FILE):**
+```php
+$object = Request::getInstance()->getInput()->getObject('name');
+```
+
+**Return specific GET parameter (where name is the name of your parameter):**
+```php
+$object = Request::getInstance()->getInput()->get->name;
+$object = Request::getInstance()->getInput()->post->name;
+$object = Request::getInstance()->getInput()->file->name;
+```
+
+**Return all parameters:**
+```php
+// Get all
+$objects = Request::getInstance()->getInput()->all();
+
+// Only match certain keys
+$objects = Request::getInstance()->getInput()->all([
+ 'company_name',
+ 'user_id'
+]);
+```
+
+All object inherits from `InputItem` class and will always contain these methods:
+- `getValue()` - returns the value of the input.
+- `getIndex()` - returns the index/key of the input.
+- `getName()` - returns a human friendly name for the input (company_name will be Company Name etc).
+
+`InputFile` has some of the same methods as above along with some other file-specific methods like:
+- `getTmpName()` - get file temporary name.
+- `getSize()` - get file size.
+- `move($destination)` - move file to destination.
+- `getContents()` - get file content.
+- `getType()` - get mime-type for file.
+- `getError()` - get file upload error.
+
+
+### Easy access your input
+Create a helper function to easily get access to the input elements.
+
+Example:
+
+```php
+/**
+ * Get input class
+ * @return \Pecee\Http\Input\Input
+ */
+function input() {
+ return new \Pecee\Http\Input\Input();
+}
+```
+
+Then you can easily do something like this in your controller:
+
+```php
+// Get parameter site_id or default-value 2
+$value = input()->get('site_id', '2');
+```
+
## Sites
This is some sites that uses the simple-router project in production.
diff --git a/src/Pecee/Http/Input/Input.php b/src/Pecee/Http/Input/Input.php
new file mode 100644
index 0000000..09872be
--- /dev/null
+++ b/src/Pecee/Http/Input/Input.php
@@ -0,0 +1,191 @@
+setGet();
+ $this->setPost();
+ $this->setFile();
+ }
+
+ /**
+ * Get all get/post items
+ * @param array|null $filter Only take items in filter
+ * @return array
+ */
+ public function all(array $filter = null) {
+ $output = $this->get->getData();
+ $output = array_merge($output, $this->post->getData());
+
+ if($filter !== null) {
+ $tmp = array();
+ foreach($output as $key => $val) {
+ if(in_array($key, $filter)) {
+ $tmp[$key] = $val;
+ }
+ }
+ return $tmp;
+ }
+
+ return $output;
+ }
+
+ public function getObject($index, $default = null) {
+ $index = (strpos($index, '[') > -1) ? substr($index, 0, strpos($index, '[')) : $index;
+
+ $element = $this->get->findFirst($index);
+
+ if($element !== null) {
+ return $element;
+ }
+
+ $element = $this->post->findFirst($index);
+
+ if($element !== null) {
+ return $element;
+ }
+
+ $element = $this->file->findFirst($index);
+
+ if($element !== null) {
+ return $element;
+ }
+
+ return $default;
+ }
+
+ /**
+ * Get input element value matching index
+ * @param string $index
+ * @param string|null $default
+ * @return string|null
+ */
+ public function get($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;
+
+ $item = $this->getObject($index);
+
+ if($item !== null) {
+
+ if (is_array($item->getValue())) {
+ return ($key !== null && isset($item->getValue()[$key])) ? $item->getValue()[$key] : $item->getValue();
+ }
+
+ return ($item->getValue() === null) ? $default : $item->getValue();
+ }
+
+ return $default;
+ }
+
+ public function setGet() {
+ $this->get = new InputCollection();
+
+ if(count($_GET)) {
+ foreach($_GET as $key => $get) {
+ if(!is_array($get)) {
+ $this->get->{$key} = new InputItem($key, $get);
+ continue;
+ }
+
+ $output = array();
+
+ foreach($get as $k => $g) {
+ $output[$k] = new InputItem($k, $g);
+ }
+
+ $this->get->{$key} = new InputItem($key, $output);
+ }
+ }
+ }
+
+ public function setPost() {
+ $this->post = new InputCollection();
+
+ $postVars = array();
+
+ if(in_array($_SERVER['REQUEST_METHOD'], ['PUT', 'PATCH', 'DELETE'])) {
+ parse_str(file_get_contents('php://input'), $postVars);
+ } else {
+ $postVars = $_POST;
+ }
+
+ if(count($postVars)) {
+
+ foreach($postVars as $key => $post) {
+ if(!is_array($post)) {
+ $this->post->{strtolower($key)} = new InputItem($key, $post);
+ continue;
+ }
+
+ $output = array();
+
+ foreach($post as $k=>$p) {
+ $output[$k] = new InputItem($k, $p);
+ }
+
+ $this->post->{strtolower($key)} = new InputItem($key, $output);
+ }
+ }
+ }
+
+ public function setFile() {
+ $this->file = new InputCollection();
+
+ if(count($_FILES)) {
+ foreach($_FILES as $key => $value) {
+ // Multiple files
+ if(!is_array($value['name'])) {
+ // Strip empty values
+ if($value['error'] != '4') {
+ $file = new InputFile();
+ $file->setIndex($key);
+ $file->setName($value['name']);
+ $file->setSize($value['size']);
+ $file->setType($value['type']);
+ $file->setTmpName($value['tmp_name']);
+ $file->setError($value['error']);
+ $this->file->{strtolower($key)} = $file;
+ }
+ continue;
+ }
+
+ $output = array();
+
+ foreach($value['name'] as $k=>$val) {
+ // Strip empty values
+ if($value['error'][$k] != '4') {
+ $file = new InputFile();
+ $file->setIndex($k);
+ $file->setName($value['name'][$k]);
+ $file->setSize($value['size'][$k]);
+ $file->setType($value['type'][$k]);
+ $file->setTmpName($value['tmp_name'][$k]);
+ $file->setError($value['error'][$k]);
+ $output[$k] = $file;
+ }
+ }
+
+ $this->file->{strtolower($key)} = new InputItem($key, $output);
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/Pecee/Http/Input/InputCollection.php b/src/Pecee/Http/Input/InputCollection.php
new file mode 100644
index 0000000..d531aba
--- /dev/null
+++ b/src/Pecee/Http/Input/InputCollection.php
@@ -0,0 +1,67 @@
+data)) {
+
+ if(isset($this->data[$index])) {
+ return $this->data[$index];
+ }
+
+ foreach($this->data as $key => $value) {
+ if(strtolower($index) === strtolower($key)) {
+ return $value;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @param $index
+ * @throws \InvalidArgumentException
+ * @return IInputItem
+ */
+ 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 Iterator or
+ * Traversable
+ * @since 5.0.0
+ */
+ public function getIterator() {
+ return new \ArrayIterator($this->data);
+ }
+
+}
\ No newline at end of file
diff --git a/src/Pecee/Http/Input/InputFile.php b/src/Pecee/Http/Input/InputFile.php
new file mode 100644
index 0000000..734ffc5
--- /dev/null
+++ b/src/Pecee/Http/Input/InputFile.php
@@ -0,0 +1,88 @@
+index;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSize() {
+ return $this->size;
+ }
+
+ /**
+ * @return string
+ */
+ public function getType() {
+ return $this->type;
+ }
+
+ /**
+ * @return string
+ */
+ public function getError() {
+ return $this->error;
+ }
+
+ /**
+ * @return string
+ */
+ public function getTmpName() {
+ return $this->tmpName;
+ }
+
+ public function getExtension() {
+ return pathinfo($this->getName(), PATHINFO_EXTENSION);
+ }
+
+ public function move($destination) {
+ return move_uploaded_file($this->tmpName, $destination);
+ }
+
+ public function getContents() {
+ return file_get_contents($this->tmpName);
+ }
+
+ public function setIndex($index) {
+ $this->index = $index;
+ }
+
+ public function setName($name) {
+ $this->name = $name;
+ }
+
+ public function setTmpName($name) {
+ $this->tmpName = $name;
+ }
+
+ public function setSize($size) {
+ $this->size = $size;
+ }
+
+ public function setType($type) {
+ $this->type = $type;
+ }
+
+ public function setError($error) {
+ $this->error = $error;
+ }
+
+}
\ No newline at end of file
diff --git a/src/Pecee/Http/Input/InputItem.php b/src/Pecee/Http/Input/InputItem.php
new file mode 100644
index 0000000..3d3e912
--- /dev/null
+++ b/src/Pecee/Http/Input/InputItem.php
@@ -0,0 +1,53 @@
+index = $index;
+ $this->value = $value;
+
+ // Make the name human friendly, by replace _ with space
+ $this->name = ucfirst(str_replace('_', ' ', $this->index));
+ }
+
+ /**
+ * @return array
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * @return array
+ */
+ public function getValue() {
+ return $this->value;
+ }
+
+ /**
+ * @return string
+ */
+ public function getIndex() {
+ return $this->index;
+ }
+
+ /**
+ * Set input name
+ * @param string $name
+ * @return static $this
+ */
+ public function setName($name) {
+ $this->name = $name;
+ return $this;
+ }
+
+ public function __toString() {
+ return (string)$this->getValue();
+ }
+
+}
\ No newline at end of file
diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php
index 31c101e..75417d8 100644
--- a/src/Pecee/Http/Request.php
+++ b/src/Pecee/Http/Request.php
@@ -1,6 +1,8 @@
uri = $_SERVER['REQUEST_URI'];
$this->method = (isset($_POST['_method'])) ? strtolower($_POST['_method']) : strtolower($_SERVER['REQUEST_METHOD']);
$this->headers = $this->getAllHeaders();
+ $this->input = new Input();
}
protected function getAllHeaders() {