免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7792 | 回复: 19

一个用于验证数据的工具程序 [复制链接]

论坛徽章:
0
发表于 2004-04-20 11:33 |显示全部楼层

  1. <?php

  2. // @author Liao Yu Lei <daut@dualface.com>;

  3. /**
  4. * 验证规则由两部分组成:
  5. *
  6. * 首先是数据类型:
  7. *
  8. * NUMBER                数字
  9. * INT                        整数
  10. * FLOAT                        浮点数
  11. * ASCII                        ASCII字符串
  12. * EMAIL                        Email地址
  13. * DATE                        日期
  14. * TIME                        时间
  15. * IPv4                        IPv4地址
  16. * OCTAL                        八进制数值
  17. * BINARY                二进制数值
  18. * HEX                        十六进制数值
  19. * DOMAIN                Internet域名
  20. * ANY                        任意类型(等同于字符串)
  21. * STRING                字符串
  22. * 如果类型字符串前面有一个?,表示这个数据可以是空值
  23. *
  24. * 然后要用于验证的验证函数:
  25. *
  26. * min                        最小值检查
  27. * max                        最大值检查
  28. * len                        有效长度检查
  29. *                                 len(最小长度,[最大长度])
  30. * equ                        等于
  31. *                                equ(值)
  32. * equitem                等于另一个项目的值
  33. *                                equitem(项目名)
  34. * exist                        检查项目是否存在
  35. *                                 exist(项目名称)
  36. * not                        上述函数返回结果取反
  37. *                                 not(exist(项目名称))
  38. *
  39. * 验证方法:
  40. * 1. 首先检查数据类型,如果未通过则不再验证函数,直接返回false。
  41. *    如果数据类型字符串前面有?,那么当值为空时返回true。
  42. * 2. 接着验证函数,从左到右,如果验证过程中有函数返回false,
  43. *    则不再验证剩下的函数,直接返回false。
  44. * 3. 函数允许嵌套,但除了not函数,其他函数嵌套结果未定义。
  45. *
  46. * 示例:
  47. * $c = & new Checker();
  48. *
  49. * $c->;check($_POST['title'], 'ANY', 'len(1,32)');
  50. * 验证$_POST['title']的长度是否在1和32之间。
  51. *
  52. * $c->;check($_POST['begin_date'], 'DATE', 'min("2004-1-1");max("2004-1-4")');
  53. * 验证$_POST['begin_date']是否是日期数据,并且最早不早于2004-1-1,
  54. * 最晚不晚于2004-1-4
  55. *
  56. * $c->;check($_POST['password'], 'ANY', 'len(1,32);equitem("confirm_password")');
  57. * 验证$_POST['password']是否是字符串,并且长度位于1到32个字符之间。
  58. * 最后还要是否和$_POST['confirm_password']相等
  59. *
  60. * $c->;check($_POST['created_time'], 'TIME', 'not(exist("remove_time"))');
  61. * 验证$_POST['created_time']是否是时间,其次检查$_POST['remove_time']是否不存在。
  62. */

  63. define ('VT_INT',                1);
  64. define ('VT_FLOAT',                2);
  65. define ('VT_ASCII',                3);
  66. define ('VT_EMAIL',                4);
  67. define ('VT_DATE',                5);
  68. define ('VT_TIME',                6);
  69. define ('VT_IPv4',                7);
  70. define ('VT_OCTAL',                8);
  71. define ('VT_BINARY',        9);
  72. define ('VT_HEX',                10);
  73. define ('VT_DOMAIN',        11);
  74. define ('VT_ANY',                12);
  75. define ('VT_STRING',        13);

  76. class Checker
  77. {
  78.         var $_data = null;
  79.         var $_current_value = null;
  80.         var $_value_type = null;
  81.         var $_result = false;
  82.        
  83.         // 函数定义
  84.         function _min($min) {
  85.                 switch ($this->;_value_type) {
  86.                 case VT_DATE:
  87.                 case VT_TIME:
  88.                         return strtotime($this->;_current_value) >;= strtotime($min);
  89.                 case VT_OCTAL:
  90.                 case VT_BINARY:
  91.                 case VT_HEX:
  92.                         return false;
  93.                         return strcasecmp($this->;_current_value, $min) >;= 0;
  94.                 default:
  95.                         return $this->;_current_value >;= $min;
  96.                 }
  97.         }
  98.        
  99.         function _max($max) {
  100.                 switch ($this->;_value_type) {
  101.                 case VT_DATE:
  102.                 case VT_TIME:
  103.                         return strtotime($this->;_current_value) <= strtotime($max);
  104.                 case VT_OCTAL:
  105.                 case VT_BINARY:
  106.                 case VT_HEX:
  107.                         return false;
  108.                         return strcasecmp($this->;_current_value, $max) <= 0;
  109.                 default:
  110.                         return $this->;_current_value <= $max;
  111.                 }
  112.         }
  113.        
  114.         function _len($min, $max = -1) {
  115.                 $len = strlen($this->;_current_value);
  116.                 if ($len < $min) {
  117.                         return false;
  118.                 }
  119.                 if ($max != -1) {
  120.                         if ($len >; $max) {
  121.                                 return false;
  122.                         }
  123.                 }
  124.                 return true;
  125.         }
  126.        
  127.         function _equ($calue) {
  128.                 return $this->;_current_value === $calue;
  129.         }
  130.        
  131.         function _equitem($key) {
  132.                 return $this->;_current_value === $this->;_data[$key];
  133.         }
  134.        
  135.         function _exist($key) {
  136.                 return isset($this->;_data[$key]);
  137.         }
  138.        
  139.         function _not($calue) {
  140.                 return !$calue;
  141.         }
  142.        
  143.         // 数据类型检查
  144.         function _is_assic($value) {
  145.                 $len = strlen($value);
  146.                 for ($i = 0; $i < $len; $i++) {
  147.                         $ord = ord(substr($value, $i, 1));
  148.                         if ($ord >; 127) {
  149.                                 return false;
  150.                         }
  151.                 }
  152.                 return true;
  153.         }
  154.        
  155.         function _is_email($value) {
  156.                 return eregi("^[0-9a-z]+@([0-9a-z]+\.)+[0-9a-z]+$", $value);
  157.         }

  158.         function _is_date($value) {
  159.                 if (!eregi("^[1-9][0-9][0-9][0-9]-[0-9]+-[0-9]+$", $value)) {
  160.                         return false;
  161.                 }
  162.                 $time = strtotime($value);
  163.                 if ($time === -1) {
  164.                         return false;
  165.                 }
  166.                 $time_e = explode('-', $value);
  167.                 $time_ex = explode('-', Date('Y-m-d', $time));
  168.                 for ($i = 0; $i < count($time_e); $i++) {
  169.                         if ((int)$time_e[$i] != (int)$time_ex[$i]) {
  170.                                 return false;
  171.                         }
  172.                 }
  173.                 return true;
  174.         }

  175.         function _is_time($value) {
  176.                 if (!eregi("^[0-9]{1,2}(:[0-9]{1,2}){1,2}$", $value)) {
  177.                         return false;
  178.                 }
  179.                 $time = strtotime($value);
  180.                 if ($time === -1) {
  181.                         return false;
  182.                 }
  183.                 $time_e = explode(':', $value);
  184.                 $time_ex = explode(':', Date('H:i:s', $time));
  185.                 for ($i = 0; $i < count($time_e); $i++) {
  186.                         if ((int)$time_e[$i] != (int)$time_ex[$i]) {
  187.                                 return false;
  188.                         }
  189.                 }
  190.                 return true;
  191.         }

  192.         function _is_ipv4($value) {
  193.                 return ereg("^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$", $value);
  194.         }

  195.         function _is_octal($value) {
  196.                 return ereg("^0[1-7]*[0-7]+$", $value);
  197.         }

  198.         function _is_binary($value) {
  199.                 return ereg("^[01]+$", $value);
  200.         }

  201.         function _is_hex($value) {
  202.                 return eregi("^0x[0-9a-f]+$", $value);
  203.         }

  204.         function _is_domain($value) {
  205.                 return eregi("^@([0-9a-z\-_]+\.)+[0-9a-z\-_]+$", $value);
  206.         }
  207.        
  208.         function _is_int($value) {
  209.                 return ereg("^[0-9]+$", $value);
  210.         }
  211.        
  212.         function _is_float($value) {
  213.                 return ereg("^[0-9]+\\.[0-9]+$", $value);
  214.         }

  215.         /**
  216.         * @return Checker
  217.         * @desc 构造一个 Checker 对象
  218.         */
  219.         function Checker(& $data) {
  220.                 $this->;_data = & $data;
  221.         }
  222.        
  223.         /**
  224.         * @retrun boolean
  225.         * @param string $key
  226.         * @param string $rule
  227.         * @desc 检查数组指定键的值是否有效
  228.         */
  229.         function checkWithKey($key, $rule = 'STRING') {
  230.                 if (!isset($this->;_data[$key])) {
  231.                         return $this->;check('', $rule);
  232.                 }
  233.                 return $this->;check($this->;_data[$key], $rule);
  234.         }

  235.         /**
  236.         * @return boolean
  237.         * @param string $value
  238.         * @param string $rule
  239.         * @desc 检查指定数据是否有效
  240.         */
  241.         function check($value, $rule = 'STRING') {
  242.                 $pos = strpos($rule, ';');
  243.                 if ($pos === false) {
  244.                         $type = $rule;
  245.                         $rule = '';
  246.                 } else {
  247.                         $type = substr($rule, 0, $pos);
  248.                         $rule = substr($rule, $pos + 1);
  249.                 }
  250.                
  251.                 // 检查是否允许NULL值
  252.                 if (substr($type, 0, 1) == '?') {
  253.                         if (empty($value)) {
  254.                                 return true;
  255.                         }
  256.                         $type = substr($type, 1);
  257.                 }
  258.                 // 检查数据类型
  259.                 if (!$this->;isType($value, $type)) {
  260.                         return false;
  261.                 }
  262.                 // 检查数据是否符合规则
  263.                 if (empty($rule)) {
  264.                         return true;
  265.                 }
  266.                 $rule_list = explode(';', $rule);
  267.                 foreach ($rule_list as $rule_item) {
  268.                         if (!$this->;runRule($value, $rule_item)) {
  269.                                 return false;
  270.                         }
  271.                 }
  272.                 return true;
  273.         }
  274.        
  275.         /**
  276.         * @return boolean
  277.         * @param string $value
  278.         * @param string $type
  279.         * @desc 检查数据类型
  280.         */
  281.         function isType($value, $type) {
  282.                 $type = strtoupper($type);
  283.                 switch ($type) {
  284.                 case 'NUMBER':
  285.                 case 'INT':
  286.                         $this->;_value_type = VT_INT;
  287.                         return $this->;_is_int($value);
  288.                 case 'FLOAT':
  289.                         $this->;_value_type = VT_FLOAT;
  290.                         return $this->;_is_float($value);
  291.                 case 'ASCII':
  292.                         $this->;_value_type = VT_ASCII;
  293.                         return $this->;_is_assic($value);
  294.                 case 'EMAIL':
  295.                         $this->;_value_type = VT_EMAIL;
  296.                         return $this->;_is_email($value);
  297.                 case 'DATE':
  298.                         $this->;_value_type = VT_DATE;
  299.                         return $this->;_is_date($value);
  300.                 case 'TIME':
  301.                         $this->;_value_type = VT_TIME;
  302.                         return $this->;_is_time($value);
  303.                 case 'IPV4':
  304.                         $this->;_value_type = VT_IPv4;
  305.                         return $this->;_is_ipv4($value);
  306.                 case 'OCTAL':
  307.                         $this->;_value_type = VT_OCTAL;
  308.                         return $this->;_is_octal($value);
  309.                 case 'BINARY':
  310.                         $this->;_value_type = VT_BINARY;
  311.                         return $this->;_is_binary($value);
  312.                 case 'HEX':
  313.                         $this->;_value_type = VT_HEX;
  314.                         return $this->;_is_hex($value);
  315.                 case 'DOMAIN':
  316.                         $this->;_value_type = VT_DOMAIN;
  317.                         return $this->;_is_domain($value);
  318.                 case 'ANY':
  319.                         $this->;_value_type = VT_ANY;
  320.                 case 'STRING':
  321.                         $this->;_value_type = VT_STRING;
  322.                         return true;
  323.                 }
  324.         }
  325.        
  326.         /**
  327.         * @return boolean
  328.         * @param string $value
  329.         * @param string $rule
  330.         * @desc 在数据上执行验证规则
  331.         */
  332.         function runRule($value, $rule) {
  333.                 if (trim($rule) == '') {
  334.                         return true;
  335.                 }
  336.                 $this->;_current_value = $value;
  337.                 $this->;_result = false;
  338.                 $eval_rule = '$this->;_result = ' . ereg_replace('([a-z]+)\\(', '$this->;_\1(', $rule) . ';';
  339.                 // echo "\$value<br />;$value<br />;<br />;\n";
  340.                 // echo "\$eval_rule:<br />;$eval_rule<br />;<br />;\n";
  341.                 ob_start();
  342.                 $eval_result = eval($eval_rule);
  343.                 ob_end_clean();
  344.                 if ($eval_result === false) {
  345.                         echo "eval failed.<br />;\n";
  346.                         die;
  347.                         //throw (new Exception("规则执行失败\n\$rule = $rule"));
  348.                 } else {
  349.                         // echo "\$result<br />;$result<br />;<br />;\n";
  350.                         return $this->;_result;
  351.                 }
  352.         }
  353. }

  354. ?>;
复制代码



用起来如何,大家试试看。还不够完善,不过足够我用了,所以暂时没有改进的动力(没有压力就没有动力)。

论坛徽章:
0
发表于 2004-04-20 11:41 |显示全部楼层

一个用于验证数据的工具程序

可以这样验证POST数据



  1. $rule_list = array(
  2.           'name' =>; 'STRING;len(1,32)',
  3.           'gender' =>; '?INT;min(1);max(2)',
  4.           'birthday' =>; '?DATE',
  5.           'birthday_alert' =>; '?STRING;equ("1")',
  6.           'company' =>; '?STRING;len(1,256)',
  7.           'dept' =>; '?STRING;len(1,256)',
  8.           'headship' =>; '?STRING;len(1,64)',
  9.           'tel_business' =>; '?STRING;len(1,64)',
  10.           'tel_house' =>; '?STRING;len(1,64)',
  11.           'fax' =>; '?STRING;len(1,64)',
  12.           'mobilephone' =>; '?STRING;len(1,64)',
  13.           'email' =>; '?EMAIL;len(1,128)',
  14.           'email2' =>; '?EMAIL;len(1,128)',
  15.           'postcode' =>; '?NUMBER;len(1,16)',
  16.           'province' =>; '?STRING;len(1,64)',
  17.           'country' =>; '?STRING;len(1,64)',
  18.           'address' =>; '?STRING;len(1,256)',
  19.           'city' =>; '?STRING;len(1,32)');

  20. $check = & new Checker($_POST);
  21. foreach ($rule_list as $key =>; $rule) {
  22.         if (!$check->;checkWithKey($key, $rule)) {
  23.                 $result['error_' . $key] = true;
  24.         }
  25. }

  26. echo nl2br(print_r($result));

复制代码

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
发表于 2004-04-20 12:41 |显示全部楼层

一个用于验证数据的工具程序

呵呵,好啊.我以后能省不少事啊.按需改造.

论坛徽章:
0
发表于 2004-04-20 13:07 |显示全部楼层

一个用于验证数据的工具程序

改造了也放出来大家吐口水哈,呵呵

论坛徽章:
0
发表于 2004-04-20 14:13 |显示全部楼层

一个用于验证数据的工具程序

呵呵,贴我自己的一部分:
  1. <?php

  2. /*=======================================================================*\
  3. *  OpenDate 数据验证类
  4. \*=======================================================================*/

  5.         class OpenData
  6.         {
  7.                 //  转化预定义变量
  8.                 function GetData($data = "page", $action = "post")
  9.                 {
  10.                         //  转为_GET、_POST等
  11.                         $action = "_" . strtoupper($action);

  12.                         //  全局化$_GET、$_POST等变量
  13.                         global $$action;

  14.                         //  判断变量是否声明并返回结果值
  15.                         if (isset(${$action}[$data]))
  16.                         {
  17.                                 return ${$action}[$data];
  18.                         }
  19.                         elseif($data == "" && isset(${$action}))
  20.                         {
  21.                             return ${$action};
  22.                         }
  23.                         return false;
  24.                 }

  25.                 function CheckStrLen($str, $max, $min = 0)
  26.                 {
  27.                         if (strlen($str) >; $max)
  28.                         {
  29.                                 //  如果大于设置的最大长度,返回1
  30.                                 return 1;
  31.                         }
  32.                         elseif (strlen($str) < $min)
  33.                         {
  34.                                 //  如果小于最小长度,返回-1
  35.                                 return -1;
  36.                         }
  37.                         else
  38.                         {
  39.                                 //  匹配长度返回0
  40.                                 return 0;
  41.                         }
  42.                 }

  43.                 function CheckDate($date, $InputFormat = "YMD-")
  44.                 {
  45.                         //  转为大写字符
  46.                         $InputFormat = strtoupper($InputFormat);

  47.                         //  将日期分割存入数组,并以输入格式的字母为键
  48.                         list($datepart[$InputFormat[0]], $datepart[$InputFormat[1]], $datepart[$InputFormat[2]]) = explode($InputFormat[3], $date);

  49.                         //  判断是否数字组成
  50.                         if (is_numeric($datepart[$InputFormat[0]]) && is_numeric($datepart[$InputFormat[1]]) && is_numeric($datepart[$InputFormat[2]]))
  51.                         {
  52.                                 if (checkdate($datepart["M"], $datepart["D"], $datepart["Y"]))
  53.                                 {
  54.                                         //  返回日期
  55.                                         return $date;
  56.                                 }
  57.                                 else
  58.                                 {
  59.                                         return false;
  60.                                 }
  61.                         }
  62.                         else
  63.                         {
  64.                                 return false;
  65.                         }
  66.                 }

  67.                 function CheckEmail($email)
  68.                 {
  69.                         //  以@分割Email地址
  70.                         $to_work_out = explode("@", $email);

  71.                         //  判断地址是否为空
  72.                         if (!isset($to_work_out[0]) || !isset($to_work_out[1]))
  73.                         {
  74.                                 return false;
  75.                         }

  76.                         //  正则匹配
  77.                         $pattern_local = '^([0-9a-z]*([-|_]?[0-9a-z]+)*)(([-|_]?)\.([-|_]?)[0-9a-z]*([-|_]?[0-9a-z]+)+)*([-|_]?)$';
  78.                         $pattern_domain = '^([0-9a-z]+([-]?[0-9a-z]+)*)(([-]?)\.([-]?)[0-9a-z]*([-]?[0-9a-z]+)+)*\.[a-z]{2,4}$';

  79.                         //  是否完全匹配
  80.                         if (eregi($pattern_local, $to_work_out[0]) && eregi($pattern_domain, $to_work_out[1]))
  81.                         {
  82.                                 return $email;
  83.                         }
  84.                           return false;
  85.                 }

  86.                 function CheckUrl($url)
  87.                 {
  88.                         if (empty($url))
  89.                         {
  90.                                 return false;
  91.                         }
  92.                         elseif ((preg_match("/^(http|https|ftp|mms|rtsp|pnm):\/\/[\w\.\/\=\?%\-&~`@':+!]+([^ ]+)$/i", $url)))
  93.                         {
  94.                                 return $url;
  95.                         }
  96.                         return false;
  97.                 }

  98.                 function CleanStr($str)
  99.                     {
  100.                         if ($str == "")
  101.                         {
  102.                                 return "";
  103.                         }       
  104.                         $str = str_replace("&" , "&", $str);
  105.                         $str = str_replace(">;", "&", $str);
  106.                         $str = str_replace("<", "&", $str);
  107.                         $str = str_replace("\"", "&", $str);
  108.                         $str = str_replace("|", "|" , $str);
  109.                         $str = str_replace("\n", "", $str);
  110.                         $str = str_replace("$", "", $str);
  111.                         $str = str_replace("\r", "", $str);
  112.                         $str = str_replace("!", "!", $str);
  113.                         $str = str_replace("'", "'", $str);
  114.                         $str = stripslashes($str);
  115.                         $str = str_replace("\\", "\0", $str);
  116.                         return $str;
  117.                 }
  118.         }

  119. ?>;
复制代码
longnetpro 该用户已被删除
发表于 2004-04-20 22:59 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
发表于 2004-04-20 23:07 |显示全部楼层

一个用于验证数据的工具程序

我有个问题,这样的代码如何对付POST来的数组值呢?比如说通过checkbox和多选菜单<select>;的值呢。如果需要上传文件怎么办呢?
longnetpro 该用户已被删除
发表于 2004-04-20 23:18 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
发表于 2004-04-21 00:09 |显示全部楼层

一个用于验证数据的工具程序

[quote]原帖由 "shukebeita"]我有个问题,这样的代码如何对付POST来的数组值呢?比如说通过checkbox和多选菜单<select>;的值呢。如果需要上传文件怎么办呢?[/quote 发表:


上传文件处理还没有做,呵呵。
数组值.....我还没想到这个问题,一定加上。

论坛徽章:
0
发表于 2004-04-21 00:12 |显示全部楼层

一个用于验证数据的工具程序

[quote]原帖由 "longnetpro"]如果POST数据有字符串键值应当是没有什么问题的,如果键值用数组的话当然就会有问题了,一个东西不可能完美嘛。如果真要支持这些,不妨继承扩展一下就可以了。[/quote 发表:


我设计这个class我觉得最有特色的地方就是可以使用各种函数来进行进一步的验证。
我现在只实现了几个简单函数,但是按照这个原理完全可以加上很复杂的验证函数。通过组合这些函数就可以完成比较复杂的验证了。

目前的主要问题是如果两个或者更多的项互相有关联,还没法进行验证。例如
我的表单有两个radio,选择不同radio时应该对其他项应用不同的验证规则。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP