1 <?php 2 /* Copyright (c) 2012, Geert Bergman (geert@scrivo.nl) 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. Neither the name of "Scrivo" nor the names of its contributors may be 14 * used to endorse or promote products derived from this software without 15 * specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * 29 * $Id: ArgumentsCheck.php 546 2013-03-01 12:51:42Z geert $ 30 */ 31 32 /** 33 * Implementation of the \Scrivo\ArgumentCheck class. 34 */ 35 36 namespace Scrivo; 37 38 /** 39 * The ArgumentCheck class contains utility functions for type checking 40 * of arguments. All public methods in the Scrivo library should implement 41 * type checking of function arguments, either by PHP type hinting for 42 * non-scalar types or runtime type checking of scalar types. 43 */ 44 class ArgumentCheck { 45 46 /** 47 * Constant to denote an integer type. 48 */ 49 const TYPE_INTEGER = 1; 50 51 /** 52 * Constant to denote a boolean type. 53 */ 54 const TYPE_BOOLEAN = 2; 55 56 /** 57 * Constant to denote a float type. 58 */ 59 const TYPE_FLOAT = 3; 60 61 /** 62 * Constant to denote a string type. 63 */ 64 const TYPE_STRING = 4; 65 66 /** 67 * Check the argument count, types and values of all arguments passed 68 * to a method or function. See also ArgumentCheck::assert. 69 * 70 * function aFunc(\Scrivo\String $aStr, $anInt=0) { 71 * \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( 72 * // String already tested by type hint 73 * null 74 * // Test for integer type and in the set (1,4,9) 75 * array(\Scrivo\ArgumentCheck::TYPE_INTEGER, array(1,4,9) 76 * ), 77 * // At least one argument needs to be given. 78 * 1); 79 * 80 * @param array $arguments Argument list (func_get_args). 81 * @param array $args An array with values that the arguments need to 82 * comply with. Use null to skip the test. 83 * @param number $minCount If a variable length argument list was used, 84 * can use this to set the minimum number of arguments. 85 */ 86 87 public static function assertArgs($arguments, array $args, $minCount=-1) { 88 $c = count($arguments); 89 if ($c > count($args)) { 90 throw new \Scrivo\SystemException("Too many arguments."); 91 } else if ($minCount >= 0 && $c < $minCount) { 92 throw new \Scrivo\SystemException("Missing arguments."); 93 } else { 94 for ($i=0; $i<$c; $i++) { 95 $a = $args[$i]; 96 if ($a !== null) { 97 if ($minCount >= 0 && $i >= $minCount 98 && $arguments[$i] === null) { 99 // optional argument with null value. 100 } else { 101 self::assert( 102 $arguments[$i], $a[0], isset($a[1]) ? $a[1] : null); 103 } 104 } 105 } 106 } 107 } 108 109 /** 110 * Test if a variable or set of variables in an array comply to a 111 * certain (set of) type(s), and optionally test if the variable value(s) 112 * exist in a given set of values. 113 * 114 * function aFunc($arg) { 115 * // Test for boolean type 116 * \Scrivo\ArgumentCheck::assert( 117 * $arg, \Scrivo\ArgumentCheck::TYPE_BOOLEAN); 118 * 119 * function aFunc($arg) { 120 * // Test for integer type and in the set (1,4,9) 121 * \Scrivo\ArgumentCheck::assert( 122 * $arg, \Scrivo\ArgumentCheck::TYPE_INTEGER, array(1,4,9)); 123 * 124 * function aFunc($arg) { 125 * // Test for integer or string type 126 * \Scrivo\ArgumentCheck::assert( 127 * $arg, array(\Scrivo\ArgumentCheck::TYPE_BOOLEAN, 128 * \Scrivo\ArgumentCheck::TYPE_STRING)); 129 * 130 * function aFunc(array $arg) { 131 * // Test for array of string type: note array in function arguments 132 * \Scrivo\ArgumentCheck::assert( 133 * $arg, \Scrivo\ArgumentCheck::TYPE_STRING)); 134 * 135 * 136 * @param mixed|mixed[] $arg The variable to test. 137 * @param mixed|mixed[] $type The assumed type(s) of the variable, one 138 * or more (array) out of the \Scrivo\ArgumentsCheck::TYPE_* constants. 139 * @param mixed[] $set Optional to test if the given argument exists in 140 * a specific set. 141 * @return boolean True argument is of the given type(s) and optionally 142 * exists in the given set, false if not. 143 */ 144 public static function assert($arg, $type, array $set=null) { 145 $res = true; 146 if (is_array($arg)) { 147 for ($i=0; $i<count($arg) && $res; $i++) { 148 $res = self::assertArg($arg[$i], $type, $set); 149 } 150 } else { 151 $res = self::assertArg($arg, $type, $set); 152 } 153 if (!$res) { 154 throw new \Scrivo\SystemException("Invalid argument type"); 155 } 156 } 157 158 /** 159 * Test if a variable complies to a certain (set of) type(s), and 160 * optionally test if it exists in a given set. 161 * 162 * @param mixed $arg The variable to test. 163 * @param mixed|mixed[] $type The assumed type(s) of the variable, one 164 * or more (array) out of the \Scrivo\ArgumentsCheck::TYPE_* constants. 165 * @param mixed[] $set Optional to test if the given argument exists in 166 * a specific set. 167 * @return boolean True argument is of the given type(s) and optionally 168 * exists in the given set, false if not. 169 */ 170 private static function assertArg($arg, $type, array $set=null) { 171 $res = false; 172 if (is_array($type)) { 173 for ($i=0; $i<count($type) && !$res; $i++) { 174 $res = self::isType($arg, $type[$i]); 175 } 176 } else { 177 $res = self::isType($arg, $type); 178 } 179 if (!$set) { 180 return $res; 181 } 182 foreach ($set as $v) { 183 if ($v === $arg) { 184 return true; 185 } 186 } 187 return false; 188 } 189 190 /** 191 * Simple test for scalar types. 192 * 193 * @param mixed $arg The variable to test. 194 * @param int $type The assumed type of the variable, one out of the 195 * \Scrivo\ArgumentsCheck::TYPE_* constants. 196 * @throws \Scrivo\SystemException If the $type argument is not one out of 197 * the \Scrivo\ArgumentsCheck::TYPE_* constants. 198 * @return boolean True if the assumed type is correct, false if not. 199 */ 200 private static function isType($arg, $type) { 201 switch ($type) { 202 case self::TYPE_INTEGER: return is_int($arg); 203 case self::TYPE_BOOLEAN: return is_bool($arg); 204 case self::TYPE_FLOAT: return is_float($arg); 205 case self::TYPE_STRING: return is_string($arg); 206 default: 207 if (is_object($arg) && get_class($arg) === $type) { 208 return true; 209 } 210 } 211 throw new \Scrivo\SystemException("No such argument type"); 212 } 213 214 } 215 216 ?>
Documentation generated by phpDocumentor 2.0.0a12 and ScrivoDocumentor on August 29, 2013