fastsol Posted April 9, 2015 Share Posted April 9, 2015 I am trying to build a Input class mainly for POST and GET. I am not real proficient with classes. I know I don't understand a number of the principles of a class but I am learning. This is just a fairly basic class that I will expand on over time. Could those of you that know a good amount about classes please review the code for me and hopefully give me some pointers and point out any real shortcomings, blah blah. class Input { protected $post = array(); protected $get = array(); protected $_p = 'post'; protected $_g = 'get'; function __construct() { $this->post = $_POST; $this->get = $_GET; } // Checks is the given $name isset(). Defaults to $_POST unless $type is given public function is_set($name, $type = 'post') { switch($type) { case $this->_p: return (isset($this->{$this->_p}[$name])) ? TRUE : FALSE; break; case $this->_g: return (isset($this->{$this->_g}[$name])) ? TRUE : FALSE; break; default: return FALSE; } } // Checks is the given $name has an empty value. Defaults to $_POST unless $type is given public function is_empty($name, $type = 'post') { switch($type) { case $this->_p: return (empty($this->{$this->_p}[$name])) ? TRUE : FALSE; break; case $this->_g: return (empty($this->{$this->_g}[$name])) ? TRUE : FALSE; break; default: return FALSE; } } protected function input_value($name, $type, $clean) { if($name !== FALSE) { if($this->is_set($name, $type) === TRUE) { return ($clean === TRUE) ? sanitize($this->{$type}[$name]) : $this->{$type}[$name]; } else { return FALSE; } } else { return $this->all($type); } } // Returns all input values for the given $type protected function all($type) { return $this->$type; } // Returns the value for the given $name or FALSE if the name is not set in the $_POST array. // Will return all $_POST vars if no $name is given. public function post($name = FALSE, $clean = FALSE) { return $this->input_value($name, $this->_p, $clean); } // Returns the value for the given $name or FALSE if the name is not set in the $_GET array. // Will return all $_GET vars if no $name is given. public function get($name = FALSE, $clean = FALSE) { return $this->input_value($name, $this->_g, $clean); } public function files() { } // Used to check if a form has been submitted by checking for the given $button_name public function submitted($button_name = 'submit', $type = 'post') { return ($this->is_set($button_name, $type) == TRUE) ? TRUE : FALSE; } } Quote Link to comment Share on other sites More sharing options...
Destramic Posted April 9, 2015 Share Posted April 9, 2015 (edited) you case should look like this surly case 'post': return (isset($this->_p[$name]) ? TRUE : FALSE; break; case 'get': return (isset($this->_g[$name]) ? TRUE : FALSE; break; unless i missed something in your code? or even better public function is_set($name, $type="POST") { $method = $_{$type}; if (in_array($name, $method)) { return true; } return false; } try using something like this...should work...although i'm doubting myself on $method variable and cant test code at the moment. Fingers Crossed but have a look at the manual http://php.net/manual/en/language.oop5.php Edited April 9, 2015 by Destramic Quote Link to comment Share on other sites More sharing options...
fastsol Posted April 9, 2015 Author Share Posted April 9, 2015 No, your case example would not work. I am dynamically setting the $this-> var, so it needs the full version I have. I do like the in_array method though, I didn't consider that when designing, might be easier to understand too. Quote Link to comment Share on other sites More sharing options...
fastsol Posted April 10, 2015 Author Share Posted April 10, 2015 After some more review, there isn't a need for the switch() or in_array() in the is_set method. A simple one line isset works just as good. public function is_set($name, $type = 'post') { return (isset($this->{$type}[$name])) ? TRUE : FALSE; } Same goes for the is_empty method public function is_empty($name, $type = 'post') { return (empty($this->{$type}[$name])) ? TRUE : FALSE; } Any other suggestions are very welcomed. Quote Link to comment Share on other sites More sharing options...
Destramic Posted April 10, 2015 Share Posted April 10, 2015 (edited) simplicity is the way forward...you can also use your class to capture sessions...but that looks good to me Edited April 10, 2015 by Destramic Quote Link to comment Share on other sites More sharing options...
Destramic Posted April 10, 2015 Share Posted April 10, 2015 (edited) also i wouldn't set POST or GET array in a property but just get it directly from the global variable $_SERVER $_REQUEST $_POST $_GET $_FILES $_ENV $_COOKIE $_SESSION Edited April 10, 2015 by Destramic Quote Link to comment Share on other sites More sharing options...
fastsol Posted April 10, 2015 Author Share Posted April 10, 2015 I'm not sure what you're getting at with your last post. The construct is setting internal vars from the globals already. At this moment I have only chosen to focus on get and post. I am researching other reasons why the other super globals might be useful within the class or an extended class. Quote Link to comment Share on other sites More sharing options...
Destramic Posted April 10, 2015 Share Posted April 10, 2015 <?php $_POST['name'] = "test"; $input = new Input; $_POST['age'] = "99"; if ($input->is_set('age', 'POST')) { echo "set"; } else { echo "not set"; } if you call class and a global is set after then your class isn't gonna pick up Quote Link to comment Share on other sites More sharing options...
fastsol Posted April 10, 2015 Author Share Posted April 10, 2015 Well yeah, but that's how the entire php language works too, so I'm not seeing your point. I can't think of an reason or instance (at least for POST, GET anyway) that you would directly modify the original array. Typically any modification to an orignal array element, like POST and GET, would be assigned to a new var anyway, still leaving the original array intact. I am very interested in a real world scenario if you can provide one Quote Link to comment Share on other sites More sharing options...
Psycho Posted April 11, 2015 Share Posted April 11, 2015 After some more review, there isn't a need for the switch() or in_array() in the is_set method. A simple one line isset works just as good. public function is_set($name, $type = 'post') { return (isset($this->{$type}[$name])) ? TRUE : FALSE; } Same goes for the is_empty method public function is_empty($name, $type = 'post') { return (empty($this->{$type}[$name])) ? TRUE : FALSE; } Any other suggestions are very welcomed. Having a condition that returns TRUE/FALSE is a waste of bytes. Simply return the results of the condition (which would be TRUE or FALSE). public function is_set($name, $type = 'post') { return (isset($this->{$type}[$name])); } public function is_empty($name, $type = 'post') { return (empty($this->{$type}[$name])); } 2 Quote Link to comment Share on other sites More sharing options...
Destramic Posted April 11, 2015 Share Posted April 11, 2015 (edited) instead of using protected $post = array(); protected $get = array(); just allow you methods to get results directly from the $_POST or $_GET variable...that way it will always have up to date values when using my example above, the "age" value will then be picked up. <?php function test($name, $type = "POST") { $array = $_{$type}; return $array[$name]; } echo test('age'); Edited April 11, 2015 by Destramic Quote Link to comment Share on other sites More sharing options...
fastsol Posted April 11, 2015 Author Share Posted April 11, 2015 instead of using protected $post = array(); protected $get = array(); just allow you methods to get results directly from the $_POST or $_GET variable...that way it will always have up to date values when using my example above, the "age" value will then be picked up. <?php function test($name, $type = "POST") { $array = $_{$type}; return $array[$name]; } echo test('age'); This doesn't work. You can't use variable variables on superglobals like POST and GET, I've tried and it states it in the php manual too. I understand why you see this as a solution but I still can't imagine an instance that you would ever need to update/change the posted array. That data is provided by the user, so why would you want/need to modify it, then it wouldn't be what they sent you. You could simply assign the added value to another variable in the script or have it posted as a hidden input in the first place. Quote Link to comment Share on other sites More sharing options...
ignace Posted April 11, 2015 Share Posted April 11, 2015 (edited) Here's an example of a class that does the same thing but keeps testability in mind: Request.php Edited April 11, 2015 by ignace Quote Link to comment Share on other sites More sharing options...
fastsol Posted May 2, 2015 Author Share Posted May 2, 2015 (edited) Well after a couple weeks of messing around and reconstructing my cms to use the new Input class and working out the bugs, I have a final product (at least for now, always improving ). class Input { protected $post = array(); protected $get = array(); protected $_p = 'post'; protected $_g = 'get'; protected $_casts = array('int', 'integer', 'string', 'object', 'float', 'array', 'null', 'boolean', 'bool'); function __construct() { $this->post = $_POST; $this->get = $_GET; } public static function super($name) { switch($name) { case 'post': $array = $_POST; break; case 'get': $array = $_GET; break; } return $array; } // Checks is the given $name isset(). Defaults to $_POST unless $type is given // Returns TRUE if the var IS set, FALSE if NOT set. // Type can be post or get public function is_set($name, $type = 'post') { return isset($this->{$type}[$name]); } // Returns TRUE if IS set, FALSE if NOT set // Must provide a name with a | and single letter notation of p, g, c, s (i.e name|p) public static function exists($name) { return self::set_type($name, 'exists'); } // Returns TRUE if NOT set, FALSE if IS set // Must provide a name with a | and single letter notation of p, g, c, s (i.e name|p) public static function notExists($name) { return self::set_type($name, 'notExists'); } // Returns TRUE if var is NOT empty, and FALSE if IS empty // Must provide a name with a | and single letter notation of p, g, c, s (i.e name|p) public static function hasVal($name) { return self::set_type($name, 'hasVal'); } // Returns TRUE if var IS empty, and FALSE if NOT empty // Must provide a name with a | and single letter notation of p, g, c, s (i.e name|p) public static function noVal($name) { return self::set_type($name, 'noVal'); } // Use this to verify if an array has values. Uses array_filter_recursive to go through the entire multi-dimensional array // Returns TRUE if var is NOT empty, and FALSE if IS empty // Must provide a name with a | and single letter notation of p, g, c, s (i.e name|p) public static function arrayHasVal($name) { return self::set_type($name, 'arrayHasVal'); } // Use this to verify if an array has values. Uses array_filter_recursive to go through the entire multi-dimensional array // Returns TRUE if var IS empty, and FALSE if NOT empty // Must provide a name with a | and single letter notation of p, g, c, s (i.e name|p) public static function arrayNoVal($name) { return self::set_type($name, 'arrayNoVal'); } // Checks is the given $name has an empty value. Defaults to $_POST unless $type is given // Returns TRUE if var the IS empty, FALSE if NOT empty. // Type can be post or get public function is_empty($name, $type = 'post') { return empty($this->{$type}[$name]); } // Checks is the given $name has an empty value. Defaults to $_POST unless $type is given // Returns TRUE if var the is NOT empty, FALSE if IS empty. // Type can be post or get public function not_empty($name, $type = 'post') { return !empty($this->{$type}[$name]); } // Returns the value of the given name and type // Must provide a name with a | and single letter notation of p, g, c, s (i.e name|p) public static function val($name) { return self::set_type($name, 'val'); } // Splits the $name to grab the type of superglobal requested protected static function split_name($name) { return explode('|', $name); } // Grabs the superglobals array for the given type. protected static function set_type($type, $func = '') { $split = self::split_name($type); if(count($split) == 2 && !empty($split[1])) { switch($split[1]) { case 'p': $_items = $_POST; break; case 'g': $_items = $_GET; break; case 'c': $_items = $_COOKIE; break; case 's': $_items = $_SESSION; break; } if(!isset($_items)) { throw new Exception('Invalid input type specified for Input::'.$func.'()'); return FALSE; } switch($func) { case 'exists': $return = isset($_items[$split[0]]); break; case 'notExists': $return = !isset($_items[$split[0]]); break; // Only used if the item is an array case 'arrayHasVal': $item = (isset($_items[$split[0]]) && is_array($_items[$split[0]])) ? $_items[$split[0]] : FALSE; $return = !empty(array_filter_recursive($item)); break; // Only used if the item is an array case 'arrayNoVal': $item = (isset($_items[$split[0]]) && is_array($_items[$split[0]])) ? $_items[$split[0]] : FALSE; $return = empty(array_filter_recursive($item)); break; // Should not be used if the value of the item is an array /* Will always return FALSE if an array is given to prevent warnings being thrown Warnings could easily occur if a user tried to edit a POST or GET element into an array when it shouldn't be. This will prevent the warnings. */ case 'hasVal': $item = (isset($_items[$split[0]]) && !is_array($_items[$split[0]])) ? trim($_items[$split[0]]) : FALSE; $return = ($item == '') ? FALSE : !empty($_items[$split[0]]); break; // Should not be used if the value of the item is an array /* Will always return FALSE if an array is given to prevent warnings being thrown Warnings could easily occur if a user tried to edit a POST or GET element into an array when it shouldn't be. This will prevent the warnings. */ case 'noVal': $item = (isset($_items[$split[0]]) && !is_array($_items[$split[0]])) ? trim($_items[$split[0]]) : TRUE; $return = ($item == '' || (isset($_items[$split[0]]) && is_array($_items[$split[0]]))) ? TRUE : empty($_items[$split[0]]); break; case 'val': $return = (isset($_items[$split[0]])) ? ((is_array($_items[$split[0]])) ? $_items[$split[0]] : trim($_items[$split[0]])) : FALSE; break; default: $return = (isset($_items[$split[0]])) ? $_items[$split[0]] : FALSE; } return $return; } else { throw new Exception('No input type provided for Input::'.$func.'()'); return FALSE; } } /* Returns an input value. $name is the key name to return $type is the input type (get or post) at this time. $clean set to TRUE will use the sanitize function then return. $cast will cast the value to the given $cast type i.e. int, string */ protected function input_value($name, $type, $clean, $cast) { if($this->is_set($name, $type) === TRUE) { if($clean === TRUE) { $this->{$type}[$name] = sanitize($this->{$type}[$name]); } elseif(!empty($cast) && in_array($cast, $this->_casts)) { $this->cast($name, $type, $cast); } } return $this; } public function cast($name, $type = 'post', $cast) { (in_array($cast, $this->_casts)) ? settype($this->{$type}[$name], $cast) : ''; return $this; } public function setBool($name, $type = 'post') { return ($this->is_set($name, $type)) ? 1 : 0; } // Returns all input values for the given $type // Type can be post or get public function all($type) { return $this->$type; } // Returns the value for the given $name or FALSE if the name is not set in the $_POST array. // Set argument 2 to TRUE to automatically use the sanitize() on the returned value. // Set agument 3 to a valid $_casts type to automatically settype() the returned value. public function post($name, $clean = FALSE, $cast = FALSE) { $this->input_value($name, $this->_p, $clean, $cast); return ($this->is_set($name)) ? $this->post[$name] : FALSE; } // Returns the value for the given $name or FALSE if the name is not set in the $_GET array. // Set argument 2 to TRUE to automatically use the sanitize() on the returned value. // Set agument 3 to a valid $_casts type to automatically settype() the returned value. public function get($name, $clean = FALSE, $cast = FALSE) { $this->input_value($name, $this->_g, $clean, $cast); return ($this->is_set($name, $this->_g)) ? $this->get[$name] : FALSE; } // Used to check if a form has been submitted by checking for the given $button_name public function submitted($button_name = 'submit', $type = 'post') { return ($this->is_set($button_name, $type) == TRUE) ? TRUE : FALSE; } } It ended up being a mixture of a couple similar methods, static and regular. I wanted to be able to use a few static methods through out the cms constantly without having to instantiate a global var or on each page I needed it. Those statics are generally for basic quick checking if a var is empty or set and getting it's value to run a block of code. I am no expert in php but am no dummy either, but I did learn a lot about classes building this. I tested each method along the way with different scenarios to make sure it always returned the proper value it was designed for, lord knows there were a few that didn't initially and needed to be edited after the fact, but that's part of building and testing. I even threw in a couple custom exceptions for certain methods to help with debugging when using the class in the future. If anyone has more critique or suggestions on how to improve it, I am all ears. Edited May 2, 2015 by fastsol Quote Link to comment Share on other sites More sharing options...
QuickOldCar Posted May 5, 2015 Share Posted May 5, 2015 Is there another reason to define $name in the super function? I can see doing something like this public static function super() { $name = $_SERVER['REQUEST_METHOD']; switch($name) { case 'POST': $array = $_POST; break; case 'GET': $array = $_GET; break; case 'REQUEST': $array = $_REQUEST; break; case 'COOKIE': $array = $_COOKIE; break; case 'SESSION': $array = $_SESSION; break; case 'PUT': $array = $_PUT; break; } return $array; } Since are using $array for everything can eliminate the $get and $post defines. Just a reminder that the default is always an empty GET array. The value from $_SERVER['REQUEST_METHOD'] is uppercased Quote Link to comment Share on other sites More sharing options...
fastsol Posted May 6, 2015 Author Share Posted May 6, 2015 Is there another reason to define $name in the super function? I can see doing something like this public static function super() { $name = $_SERVER['REQUEST_METHOD']; switch($name) { case 'POST': $array = $_POST; break; case 'GET': $array = $_GET; break; case 'REQUEST': $array = $_REQUEST; break; case 'COOKIE': $array = $_COOKIE; break; case 'SESSION': $array = $_SESSION; break; case 'PUT': $array = $_PUT; break; } return $array; } Since are using $array for everything can eliminate the $get and $post defines. Just a reminder that the default is always an empty GET array. The value from $_SERVER['REQUEST_METHOD'] is uppercased With this method though, I'm not using it to get the array based on the request method, but rather the ability to get any or the arrays at any time. Hence the reason for the $name. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.