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.
 
 
 
 
 

361 lines
11 KiB

  1. <?php
  2. /***************************************************************************
  3. *
  4. * Copyright (c) 2014 Baidu.com, Inc. All Rights Reserved
  5. *
  6. **************************************************************************/
  7. /**
  8. *
  9. * @file AssertHelper.php
  10. * @encoding UTF-8
  11. *
  12. * @date 2014年12月31日
  13. *
  14. */
  15. /**
  16. * 断言一个值是否符合指定条件
  17. */
  18. class AssertHelper {
  19. private $lastFailed = false;
  20. /**
  21. * 可以组合使用的方法名称列表
  22. * @var array<string>
  23. */
  24. private $checkName = array (
  25. 'type',
  26. 'moreThat',
  27. 'lessThat',
  28. 'between',
  29. 'match',
  30. 'equal',
  31. 'equalStrict',
  32. 'maybe',
  33. 'not',
  34. );
  35. public function __call($name, $args) {
  36. if($rs = call_user_func_array(array($this,$name), $args)){
  37. $this -> lastFailed = false;
  38. }else{
  39. $this -> lastFailed = "assert check failed, [$name] return false";
  40. }
  41. return $rs;
  42. }
  43. public function __get($name){
  44. if($name == 'lastFailed'){
  45. return $this -> lastFailed;
  46. }
  47. }
  48. /**
  49. * 检查变量类型是否为指定类型;
  50. *
  51. * @param mixed $value
  52. * @param string | array $type
  53. *
  54. * @return boolean
  55. */
  56. private function type($value, $type) {
  57. switch (func_num_args()) {
  58. case 0 :
  59. case 1 :
  60. return false;
  61. case 2 :
  62. // 二个参数时, 才执行正常处理逻辑
  63. if (is_array($type)) {
  64. foreach ( $type as $t ) {
  65. if ($this -> type($value, $t)) {
  66. return true;
  67. }
  68. }
  69. return false;
  70. }
  71. $t = strtolower(gettype($value));
  72. $type = strtolower($type);
  73. if ($type == $t) {
  74. return true;
  75. } else if ($type == 'mixed') {
  76. return true;
  77. } else {
  78. switch ($t) {
  79. case "integer" :
  80. if ($type == 'int') {
  81. return true;
  82. }
  83. case "double" :
  84. return $type == 'number';
  85. case "boolean" :
  86. return $type == 'bool';
  87. case "user function" :
  88. return $type == 'function';
  89. case "string" :
  90. case "array" :
  91. case "object" :
  92. case "resource" :
  93. case "null" :
  94. case "unknown type" :
  95. default :
  96. return false;
  97. }
  98. }
  99. return false;
  100. default :
  101. // 多于两个参数,认为第二个及其后的统统为可能的值.
  102. $varList = func_get_args();
  103. $value = array_shift($varList);
  104. return $this -> type($value, $varList);
  105. }
  106. }
  107. /**
  108. *
  109. * 断言一个值大于另一个值
  110. *
  111. * @param int $value
  112. * @param int $checkValue
  113. * @return boolean
  114. */
  115. private function moreThat($value, $checkValue){
  116. return $value > $checkValue;
  117. }
  118. /**
  119. *
  120. * 断言一个值小于另一个值
  121. *
  122. * @param int $value
  123. * @param int $checkValue
  124. * @return boolean
  125. */
  126. private function lessThat($value, $checkValue){
  127. return $value < $checkValue;
  128. }
  129. /**
  130. * 断言一个数值在另外两个数值之间
  131. * @param int $value
  132. * @param int $min
  133. * @param int $max
  134. * @return boolean
  135. */
  136. private function between($value, $min = null, $max = null) {
  137. $value = intval($value);
  138. if ($min !== null && $max !== null) {
  139. return $value >= intval($min) && $value <= intval($max);
  140. }
  141. if ($min !== null) {
  142. return intval($min) <= $value;
  143. }
  144. if ($max !== null) {
  145. return $value <= intval($max);
  146. }
  147. return false;
  148. }
  149. /**
  150. * 断言一个字符串匹配指定的正则表达式格式
  151. *
  152. * @param string $value
  153. * @param regexpString $regStr
  154. * @return boolean
  155. */
  156. private function match($value, $regStr) {
  157. return $this -> type($value, 'string', 'number') && ($this -> equal($value, $regStr) || (preg_match(strval($regStr), strval($value)) > 0));
  158. }
  159. /**
  160. * 断言两个值相等
  161. * @param mixed $value
  162. * @param mixed $checkValue
  163. * @return boolean
  164. */
  165. private function equal($value, $checkValue) {
  166. return $value == $checkValue;
  167. }
  168. /**
  169. * 断言两个值严格相等
  170. * @param mixed $value
  171. * @param mixed $checkValue
  172. * @return boolean
  173. */
  174. private function equalStrict($value, $checkValue) {
  175. return $value === $checkValue;
  176. }
  177. /**
  178. * 断言不等于或非
  179. *
  180. * @param mixed $value
  181. * @param mixed $checkValue
  182. * @return boolean
  183. */
  184. private function not($value) {
  185. switch (func_num_args()) {
  186. case 0 :
  187. return true;
  188. case 1 :
  189. return ! $value;
  190. case 2 :
  191. $varList = func_get_arg(1);
  192. if (is_array($varList)) {
  193. return $this -> not($this -> maybe($value, $varList));
  194. }
  195. return $value == $varList;
  196. default :
  197. $varList = func_get_args();
  198. $value = array_shift($varList);
  199. return $this -> not($this -> maybe($value, $varList));
  200. }
  201. }
  202. /**
  203. * 断言一个值在给定的一组值之中. 如果只给定一个非数组的值, 那么则进行equal判断;
  204. *
  205. * @param mixed $value
  206. * @param mixed $varList
  207. * @return boolean
  208. */
  209. private function maybe($value, $varList) {
  210. switch(func_num_args()){
  211. case 0:
  212. return false;
  213. case 1:
  214. return !!$value;
  215. case 2:
  216. if (is_array($varList)) {
  217. return array_search($value, $varList, true) !== false;
  218. }
  219. return $value == $varList;
  220. default:
  221. $varList = func_get_args();
  222. $value = array_shift($varList);
  223. return $this->maybe($value, $varList);
  224. }
  225. }
  226. /**
  227. * 断言一个值会符合一组条件中的任意一项.
  228. * @param unknown $value
  229. * @param unknown $condition
  230. * @return boolean
  231. */
  232. private function possible($value,$conditions = true){
  233. switch(func_num_args()){
  234. case 0:
  235. return false;
  236. case 1:
  237. return !!$value;
  238. case 2:
  239. if (is_array($conditions)) {
  240. $notInAssert = true;
  241. foreach ( $conditions as $type => $checkValue ) {
  242. if ($this -> maybe($type, $this -> checkName)) {
  243. // mark the process type
  244. $notInAssert = $notInAssert || true;
  245. if (is_array($checkValue)) {
  246. array_unshift($checkValue, $value);
  247. } else {
  248. $checkValue = array (
  249. $value,
  250. $checkValue,
  251. );
  252. }
  253. // call other assert, if true return else continue;
  254. if (call_user_func_array(array (
  255. $this,
  256. $type,
  257. ), $checkValue)) {
  258. return true;
  259. }
  260. }
  261. }
  262. // 如果未进行过assert判断,则进行value search
  263. return $notInAssert ? $this -> maybe($value, $conditions) : false;
  264. }
  265. return $value == $conditions;
  266. default:
  267. $conditions = func_get_args();
  268. $value = array_shift($conditions);
  269. foreach ($conditions as $c){
  270. if($this->possible($value, $c)){
  271. return true;
  272. }
  273. }
  274. // 如果未进行过assert判断,则进行value search
  275. return $this->maybe($value, $conditions);
  276. }
  277. }
  278. /**
  279. * 判断一个值是否完全符合一组条件
  280. * @param mixed $value
  281. * @param array $conditions
  282. * @return boolean
  283. */
  284. private function makesure($value, $conditions = false) {
  285. switch (func_num_args()) {
  286. case 0 :
  287. return false;
  288. case 1 :
  289. return ! ! $value;
  290. case 2 :
  291. if (is_array($conditions)) {
  292. // 必须全部返回true, 结果才能为true; 任意false结果为false
  293. foreach ( $conditions as $type => $checkValue ) {
  294. // 可以调用断言
  295. if ($this -> maybe($type, $this -> checkName)) {
  296. // print_r($type);
  297. // print_r($conditions);
  298. if (is_array($checkValue)) {
  299. array_unshift($checkValue, $value);
  300. } else {
  301. $checkValue = array (
  302. $value,
  303. $checkValue,
  304. );
  305. }
  306. // call other assert, if true return else continue;
  307. if (! call_user_func_array(array (
  308. $this,
  309. $type,
  310. ), $checkValue)) {
  311. return false;
  312. }
  313. } else {
  314. // 如果任意值不能调用assert判断, 直接判断值相等.. 如果不等, 直接返回false
  315. if ($value !== $type) {
  316. return false;
  317. }
  318. }
  319. }
  320. return true;
  321. }
  322. return $value == $conditions;
  323. }
  324. }
  325. }