validate.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <?php
  2. // vim: set expandtab cindent tabstop=4 shiftwidth=4 fdm=marker:
  3. // +----------------------------------------------------------------------+
  4. // | The Function Inc |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 2014, Function Inc. All rights reserved. |
  7. // +----------------------------------------------------------------------+
  8. // | Authors: The PHP Dev Team, ISRD, Function Inc. |
  9. // | |
  10. // +----------------------------------------------------------------------+
  11. /**
  12. * @version 1.0
  13. * @author wade
  14. * @date 2014-04-03
  15. */
  16. /**
  17. * $config = array(
  18. * 'test1' => array('required' => 1, 'type' => 'number', 'min' => 1000, 'max' => 10000),
  19. * 'test2' => array('required' => 1, 'inArray' => array('sms', 'mno')),
  20. * 'test3' => array('required' => 1, 'minLength' => 10, 'maxLength' => 20),
  21. * 'test4' => array('reg' => '/^\d+$/'),
  22. * 'test5' => array('reg' => '/^\d+$/'),
  23. * 'test6' => array('type' => 'email'),
  24. * 'test7' => array('type' => 'url'),
  25. * 'test8' => array('type' => 'float'),
  26. * 'test9' => array('type' => 'bool'),
  27. * 'test10' => array('type' => 'ip'),
  28. * 'test11' => array('type' => 'wrongType'),
  29. * );
  30. *
  31. * $_POST = array(
  32. * 'test1' => '1004',
  33. * 'test2' => 'sms',
  34. * 'test3' => '111111111111',
  35. * 'test4' => '1111',
  36. * 'test5' => array(
  37. * 0 => array(
  38. * 0 => '11111',
  39. * ),
  40. * 1 => '11111',
  41. * ),
  42. * 'test6' => 'billfeller@gmail.com',
  43. * 'test7' => 'http://www.baidu.com/',
  44. * 'test8' => 11,
  45. * 'test9' => 1,
  46. * 'test10' => '127.0.0.1',
  47. * 'test11' => '111',
  48. * );
  49. *
  50. * $validationForm = new IValidate();
  51. * $ret = $validationForm->run($config);
  52. * var_dump($ret);
  53. * if($ret === FALSE) {
  54. * var_dump($validationForm->getErrorString());
  55. * }
  56. */
  57. class validate {
  58. private $validationData;
  59. private $errorMsg;
  60. public function __construct(array $data = array()) {
  61. if(!empty($data)) {
  62. $this->validationData = $data;
  63. }
  64. }
  65. public function setMsg($message) {
  66. if(empty($this->errorMsg)) {
  67. $this->errorMsg = array();
  68. }
  69. $this->errorMsg[] = $message;
  70. }
  71. public function getMsg() {
  72. return $this->errorMsg;
  73. }
  74. public function getErrorString() {
  75. if (count($this->errorMsg) === 0) {
  76. return '';
  77. }
  78. return implode("\n", $this->errorMsg);
  79. }
  80. public function run(array $config = array(), &$data = array()) {
  81. $validationArray = empty($this->validationData) ? $_POST : $this->validationData;
  82. if(count($validationArray) === 0 || count($config) === 0) {
  83. return TRUE;
  84. }
  85. foreach($config as $key => $checkList) {
  86. if(empty($checkList)) {
  87. continue;
  88. }
  89. $value = @$validationArray[$key];
  90. $this->_execute($value, $checkList, $key);
  91. $data[$key] = $value;
  92. }
  93. return (count($this->errorMsg) === 0);
  94. }
  95. protected function _execute($value, $checkList, $key = '') {
  96. if(is_array($value)) {
  97. foreach($value as $childKey => $val) {
  98. $newKey = sprintf('%s[%s]', $key, $childKey);
  99. $this->_execute($val, $checkList, $newKey);
  100. }
  101. return ;
  102. }
  103. // 非必填项 允许为空
  104. if(empty($checkList['required']) && ($value === NULL || $value === '')) {
  105. return ;
  106. }
  107. // 必填项
  108. if(!empty($checkList['required']) && ($value === NULL || $value === '')) {
  109. $message = sprintf('%s=%s: required', $key, $value);
  110. $this->setMsg($message);
  111. return ;
  112. }
  113. if(!empty($checkList['type'])) {
  114. $ret = $this->_checkType($checkList['type'], $value);
  115. if($ret === FALSE) {
  116. $message = sprintf('%s=%s: the type should be %s', $key, $value, $checkList['type']);
  117. $this->setMsg($message);
  118. return ;
  119. }
  120. }
  121. if(isset($checkList['minLength'])) {
  122. if(!is_numeric($checkList['minLength'])) {
  123. $message = sprintf('%s=%s: the minLength configuration: %s', $key, $value, $checkList['minLength']);
  124. $this->setMsg($message);
  125. return ;
  126. }
  127. $minLength = (int)$checkList['minLength'];
  128. $ret = mb_strlen($value) >= $minLength;
  129. if($ret === FALSE) {
  130. $message = sprintf('%s=%s: the string length should be greater than %d', $key, $value, $minLength);
  131. $this->setMsg($message);
  132. return ;
  133. }
  134. }
  135. if(isset($checkList['maxLength'])) {
  136. if(!is_numeric($checkList['maxLength'])) {
  137. $message = sprintf('%s=%s: the maxLength configuration: %s', $key, $value, $checkList['maxLength']);
  138. $this->setMsg($message);
  139. return ;
  140. }
  141. $maxLength = (int)$checkList['maxLength'];
  142. $ret = mb_strlen($value) <= $maxLength;
  143. if($ret === FALSE) {
  144. $message = sprintf('%s=%s: the string length should be less than %d', $key, $value, $maxLength);
  145. $this->setMsg($message);
  146. return ;
  147. }
  148. }
  149. if(!empty($checkList['type']) && $checkList['type'] === 'number') {
  150. if(isset($checkList['min'])) {
  151. if(!is_numeric($checkList['min'])) {
  152. $message = sprintf('%s=%s: wrong min configuration: %d', $key, $value, $checkList['min']);
  153. $this->setMsg($message);
  154. return ;
  155. }
  156. $min = (int)$checkList['min'];
  157. $ret = intval($value) >= $min;
  158. if($ret === FALSE) {
  159. $message = sprintf('%s=%s: the value should be greater than %d', $key, $value, $min);
  160. $this->setMsg($message);
  161. return ;
  162. }
  163. }
  164. if(isset($checkList['max'])) {
  165. if(!is_numeric($checkList['max'])) {
  166. $message = sprintf('%s=%s: wrong max configuration: %d', $key, $value, $checkList['max']);
  167. $this->setMsg($message);
  168. return ;
  169. }
  170. $max = (int)$checkList['max'];
  171. $ret = intval($value) <= $max;
  172. if($ret === FALSE) {
  173. $message = sprintf('%s=%s: the value should be less than %d', $key, $value, $max);
  174. $this->setMsg($message);
  175. return ;
  176. }
  177. }
  178. }
  179. if(!empty($checkList['inArray'])) {
  180. if(!is_array($checkList['inArray'])) {
  181. $message = sprintf('%s=%s: wrong inArray configuration: %s', $key, $value, gettype($checkList['inArray']));
  182. $this->setMsg($message);
  183. return ;
  184. }
  185. if(!in_array($value, $checkList['inArray'])) {
  186. $message = sprintf('%s=%s: not inArray %s', $key, $value, json_encode($checkList['inArray']));
  187. $this->setMsg($message);
  188. return ;
  189. }
  190. }
  191. if(!empty($checkList['reg'])) {
  192. $ret = $this->_checkReg($checkList['reg'], $value);
  193. if($ret === FALSE) {
  194. $message = sprintf('%s=%s: the type should be like %s', $key, $value, $checkList['reg']);
  195. $this->setMsg($message);
  196. return ;
  197. }
  198. }
  199. return ;
  200. }
  201. private function _checkType($type, $value) {
  202. switch($type) {
  203. case 'number' :
  204. $ret = is_numeric($value);
  205. break;
  206. case 'bool' :
  207. $ret = (bool)filter_var($value, FILTER_VALIDATE_BOOLEAN);
  208. break;
  209. case 'email' :
  210. $ret = (bool)filter_var($value, FILTER_VALIDATE_EMAIL);
  211. break;
  212. case 'float' :
  213. $ret = (bool)filter_var($value, FILTER_VALIDATE_FLOAT);
  214. break;
  215. case 'ip' :
  216. $ret = (bool)filter_var($value, FILTER_VALIDATE_IP);
  217. break;
  218. case 'url' :
  219. $ret = (bool)filter_var($value, FILTER_VALIDATE_URL);
  220. break;
  221. default :
  222. $ret = FALSE;
  223. $message = sprintf('unknown type: %s', $type);
  224. $this->setMsg($message);
  225. break;
  226. }
  227. return $ret;
  228. }
  229. protected function _checkReg($regex, $string) {
  230. return (bool)preg_match($regex, $string);
  231. }
  232. }