Input.class.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. // $Id: Input.class.php 2528 2012-01-03 14:58:50Z liu21st $
  12. /** 输入数据管理类
  13. * 使用方法
  14. * $Input = Input::getInstance();
  15. * $Input->get('name','md5','0');
  16. * $Input->session('memberId','','0');
  17. *
  18. * 下面总结了一些常用的数据处理方法。以下方法无需考虑magic_quotes_gpc的设置。
  19. *
  20. * 获取数据:
  21. * 如果从$_POST或者$_GET中获取,使用Input::getVar($_POST['field']);,从数据库或者文件就不需要了。
  22. * 或者直接使用 Input::magicQuotes来消除所有的magic_quotes_gpc转义。
  23. *
  24. * 存储过程:
  25. * 经过Input::getVar($_POST['field'])获得的数据,就是干净的数据,可以直接保存。
  26. * 如果要过滤危险的html,可以使用 $html = Input::safeHtml($data);
  27. *
  28. * 页面显示:
  29. * 纯文本显示在网页中,如文章标题<title>$data</title>: $data = Input::forShow($field);
  30. * HTML 在网页中显示,如文章内容:无需处理。
  31. * 在网页中以源代码方式显示html:$vo = Input::forShow($html);
  32. * 纯文本或者HTML在textarea中进行编辑: $vo = Input::forTarea($value);
  33. * html在标签中使用,如<input value="数据" /> ,使用 $vo = Input::forTag($value); 或者 $vo = Input::hsc($value);
  34. *
  35. * 特殊使用情况:
  36. * 字符串要在数据库进行搜索: $data = Input::forSearch($field);
  37. */
  38. class Input {
  39. private $filter = null; // 输入过滤
  40. private static $_input = array('get','post','request','env','server','cookie','session','globals','config','lang','call');
  41. //html标签设置
  42. public static $htmlTags = array(
  43. 'allow' => 'table|td|th|tr|i|b|u|strong|img|p|br|div|strong|em|ul|ol|li|dl|dd|dt|a',
  44. 'ban' => 'html|head|meta|link|base|basefont|body|bgsound|title|style|script|form|iframe|frame|frameset|applet|id|ilayer|layer|name|script|style|xml',
  45. );
  46. static public function getInstance() {
  47. return get_instance_of(__CLASS__);
  48. }
  49. /**
  50. +----------------------------------------------------------
  51. * 魔术方法 有不存在的操作的时候执行
  52. +----------------------------------------------------------
  53. * @access public
  54. +----------------------------------------------------------
  55. * @param string $type 输入数据类型
  56. * @param array $args 参数 array(key,filter,default)
  57. +----------------------------------------------------------
  58. * @return mixed
  59. +----------------------------------------------------------
  60. */
  61. public function __call($type,$args=array()) {
  62. $type = strtolower(trim($type));
  63. if(in_array($type,self::$_input,true)) {
  64. switch($type) {
  65. case 'get': $input =& $_GET;break;
  66. case 'post': $input =& $_POST;break;
  67. case 'request': $input =& $_REQUEST;break;
  68. case 'env': $input =& $_ENV;break;
  69. case 'server': $input =& $_SERVER;break;
  70. case 'cookie': $input =& $_COOKIE;break;
  71. case 'session': $input =& $_SESSION;break;
  72. case 'globals': $input =& $GLOBALS;break;
  73. case 'files': $input =& $_FILES;break;
  74. case 'call': $input = 'call';break;
  75. case 'config': $input = C();break;
  76. case 'lang': $input = L();break;
  77. default:return NULL;
  78. }
  79. if('call' === $input) {
  80. // 呼叫其他方式的输入数据
  81. $callback = array_shift($args);
  82. $params = array_shift($args);
  83. $data = call_user_func_array($callback,$params);
  84. if(count($args)===0) {
  85. return $data;
  86. }
  87. $filter = isset($args[0])?$args[0]:$this->filter;
  88. if(!empty($filter)) {
  89. $data = call_user_func_array($filter,$data);
  90. }
  91. }else{
  92. if(0==count($args) || empty($args[0]) ) {
  93. return $input;
  94. }elseif(array_key_exists($args[0],$input)) {
  95. // 系统变量
  96. $data = $input[$args[0]];
  97. $filter = isset($args[1])?$args[1]:$this->filter;
  98. if(!empty($filter)) {
  99. $data = call_user_func_array($filter,$data);
  100. }
  101. }else{
  102. // 不存在指定输入
  103. $data = isset($args[2])?$args[2]:NULL;
  104. }
  105. }
  106. return $data;
  107. }
  108. }
  109. /**
  110. +----------------------------------------------------------
  111. * 设置数据过滤方法
  112. +----------------------------------------------------------
  113. * @access private
  114. +----------------------------------------------------------
  115. * @param mixed $filter 过滤方法
  116. +----------------------------------------------------------
  117. * @return void
  118. +----------------------------------------------------------
  119. */
  120. public function filter($filter) {
  121. $this->filter = $filter;
  122. return $this;
  123. }
  124. /**
  125. +----------------------------------------------------------
  126. * 字符MagicQuote转义过滤
  127. +----------------------------------------------------------
  128. * @access public
  129. +----------------------------------------------------------
  130. * @return void
  131. +----------------------------------------------------------
  132. */
  133. static public function noGPC() {
  134. if ( get_magic_quotes_gpc() ) {
  135. $_POST = stripslashes_deep($_POST);
  136. $_GET = stripslashes_deep($_GET);
  137. $_COOKIE = stripslashes_deep($_COOKIE);
  138. $_REQUEST= stripslashes_deep($_REQUEST);
  139. }
  140. }
  141. /**
  142. +----------------------------------------------------------
  143. * 处理字符串,以便可以正常进行搜索
  144. +----------------------------------------------------------
  145. * @access public
  146. +----------------------------------------------------------
  147. * @param string $string 要处理的字符串
  148. +----------------------------------------------------------
  149. * @return string
  150. +----------------------------------------------------------
  151. */
  152. static public function forSearch($string) {
  153. return str_replace( array('%','_'), array('\%','\_'), $string );
  154. }
  155. /**
  156. +----------------------------------------------------------
  157. * @access public
  158. +----------------------------------------------------------
  159. * @param string $string 要处理的字符串
  160. +----------------------------------------------------------
  161. * @return string
  162. +----------------------------------------------------------
  163. */
  164. static public function forShow($string) {
  165. return self::nl2Br( self::hsc($string) );
  166. }
  167. /**
  168. +----------------------------------------------------------
  169. * 处理纯文本数据,以便在textarea标签中显示
  170. +----------------------------------------------------------
  171. * @access public
  172. +----------------------------------------------------------
  173. * @param string $string 要处理的字符串
  174. +----------------------------------------------------------
  175. * @return string
  176. +----------------------------------------------------------
  177. */
  178. static public function forTarea($string) {
  179. return str_ireplace(array('<textarea>','</textarea>'), array('&lt;textarea>','&lt;/textarea>'), $string);
  180. }
  181. /**
  182. +----------------------------------------------------------
  183. * 将数据中的单引号和双引号进行转义
  184. +----------------------------------------------------------
  185. * @access public
  186. +----------------------------------------------------------
  187. * @param string $text 要处理的字符串
  188. +----------------------------------------------------------
  189. * @return string
  190. +----------------------------------------------------------
  191. */
  192. static public function forTag($string) {
  193. return str_replace(array('"',"'"), array('&quot;','&#039;'), $string);
  194. }
  195. /**
  196. +----------------------------------------------------------
  197. * 转换文字中的超链接为可点击连接
  198. +----------------------------------------------------------
  199. * @access public
  200. +----------------------------------------------------------
  201. * @param string $string 要处理的字符串
  202. +----------------------------------------------------------
  203. * @return string
  204. +----------------------------------------------------------
  205. */
  206. static public function makeLink($string) {
  207. $validChars = "a-z0-9\/\-_+=.~!%@?#&;:$\|";
  208. $patterns = array(
  209. "/(^|[^]_a-z0-9-=\"'\/])([a-z]+?):\/\/([{$validChars}]+)/ei",
  210. "/(^|[^]_a-z0-9-=\"'\/])www\.([a-z0-9\-]+)\.([{$validChars}]+)/ei",
  211. "/(^|[^]_a-z0-9-=\"'\/])ftp\.([a-z0-9\-]+)\.([{$validChars}]+)/ei",
  212. "/(^|[^]_a-z0-9-=\"'\/:\.])([a-z0-9\-_\.]+?)@([{$validChars}]+)/ei");
  213. $replacements = array(
  214. "'\\1<a href=\"\\2://\\3\" title=\"\\2://\\3\" rel=\"external\">\\2://'.Input::truncate( '\\3' ).'</a>'",
  215. "'\\1<a href=\"http://www.\\2.\\3\" title=\"www.\\2.\\3\" rel=\"external\">'.Input::truncate( 'www.\\2.\\3' ).'</a>'",
  216. "'\\1<a href=\"ftp://ftp.\\2.\\3\" title=\"ftp.\\2.\\3\" rel=\"external\">'.Input::truncate( 'ftp.\\2.\\3' ).'</a>'",
  217. "'\\1<a href=\"mailto:\\2@\\3\" title=\"\\2@\\3\">'.Input::truncate( '\\2@\\3' ).'</a>'");
  218. return preg_replace($patterns, $replacements, $string);
  219. }
  220. /**
  221. +----------------------------------------------------------
  222. * 缩略显示字符串
  223. +----------------------------------------------------------
  224. * @access public
  225. +----------------------------------------------------------
  226. * @param string $string 要处理的字符串
  227. * @param int $length 缩略之后的长度
  228. +----------------------------------------------------------
  229. * @return string
  230. +----------------------------------------------------------
  231. */
  232. static public function truncate($string, $length = '50') {
  233. if ( empty($string) || empty($length) || strlen($string) < $length ) return $string;
  234. $len = floor( $length / 2 );
  235. $ret = substr($string, 0, $len) . " ... ". substr($string, 5 - $len);
  236. return $ret;
  237. }
  238. /**
  239. +----------------------------------------------------------
  240. * 把换行转换为<br />标签
  241. +----------------------------------------------------------
  242. * @access public
  243. +----------------------------------------------------------
  244. * @param string $string 要处理的字符串
  245. +----------------------------------------------------------
  246. * @return string
  247. +----------------------------------------------------------
  248. */
  249. static public function nl2Br($string) {
  250. return preg_replace("/(\015\012)|(\015)|(\012)/", "<br />", $string);
  251. }
  252. /**
  253. +----------------------------------------------------------
  254. * 如果 magic_quotes_gpc 为关闭状态,这个函数可以转义字符串
  255. +----------------------------------------------------------
  256. * @access public
  257. +----------------------------------------------------------
  258. * @param string $string 要处理的字符串
  259. +----------------------------------------------------------
  260. * @return string
  261. +----------------------------------------------------------
  262. */
  263. static public function addSlashes($string) {
  264. if (!get_magic_quotes_gpc()) {
  265. $string = addslashes($string);
  266. }
  267. return $string;
  268. }
  269. /**
  270. +----------------------------------------------------------
  271. * 从$_POST,$_GET,$_COOKIE,$_REQUEST等数组中获得数据
  272. +----------------------------------------------------------
  273. * @access public
  274. +----------------------------------------------------------
  275. * @param string $string 要处理的字符串
  276. +----------------------------------------------------------
  277. * @return string
  278. +----------------------------------------------------------
  279. */
  280. static public function getVar($string) {
  281. return Input::stripSlashes($string);
  282. }
  283. /**
  284. +----------------------------------------------------------
  285. * 如果 magic_quotes_gpc 为开启状态,这个函数可以反转义字符串
  286. +----------------------------------------------------------
  287. * @access public
  288. +----------------------------------------------------------
  289. * @param string $string 要处理的字符串
  290. +----------------------------------------------------------
  291. * @return string
  292. +----------------------------------------------------------
  293. */
  294. static public function stripSlashes($string) {
  295. if (get_magic_quotes_gpc()) {
  296. $string = stripslashes($string);
  297. }
  298. return $string;
  299. }
  300. /**
  301. +----------------------------------------------------------
  302. * 用于在textbox表单中显示html代码
  303. +----------------------------------------------------------
  304. * @access public
  305. +----------------------------------------------------------
  306. * @param string $string 要处理的字符串
  307. +----------------------------------------------------------
  308. * @return string
  309. +----------------------------------------------------------
  310. */
  311. static function hsc($string) {
  312. return preg_replace(array("/&amp;/i", "/&nbsp;/i"), array('&', '&amp;nbsp;'), htmlspecialchars($string, ENT_QUOTES));
  313. }
  314. /**
  315. +----------------------------------------------------------
  316. * 是hsc()方法的逆操作
  317. +----------------------------------------------------------
  318. * @access public
  319. +----------------------------------------------------------
  320. * @param string $text 要处理的字符串
  321. +----------------------------------------------------------
  322. * @return string
  323. +----------------------------------------------------------
  324. */
  325. static function undoHsc($text) {
  326. return preg_replace(array("/&gt;/i", "/&lt;/i", "/&quot;/i", "/&#039;/i", '/&amp;nbsp;/i'), array(">", "<", "\"", "'", "&nbsp;"), $text);
  327. }
  328. /**
  329. +----------------------------------------------------------
  330. * 输出安全的html,用于过滤危险代码
  331. +----------------------------------------------------------
  332. * @access public
  333. +----------------------------------------------------------
  334. * @param string $text 要处理的字符串
  335. * @param mixed $allowTags 允许的标签列表,如 table|td|th|td
  336. +----------------------------------------------------------
  337. * @return string
  338. +----------------------------------------------------------
  339. */
  340. static public function safeHtml($text, $allowTags = null) {
  341. $text = trim($text);
  342. //完全过滤注释
  343. $text = preg_replace('/<!--?.*-->/','',$text);
  344. //完全过滤动态代码
  345. $text = preg_replace('/<\?|\?'.'>/','',$text);
  346. //完全过滤js
  347. $text = preg_replace('/<script?.*\/script>/','',$text);
  348. $text = str_replace('[','&#091;',$text);
  349. $text = str_replace(']','&#093;',$text);
  350. $text = str_replace('|','&#124;',$text);
  351. //过滤换行符
  352. $text = preg_replace('/\r?\n/','',$text);
  353. //br
  354. $text = preg_replace('/<br(\s\/)?'.'>/i','[br]',$text);
  355. $text = preg_replace('/(\[br\]\s*){10,}/i','[br]',$text);
  356. //过滤危险的属性,如:过滤on事件lang js
  357. while(preg_match('/(<[^><]+)(lang|on|action|background|codebase|dynsrc|lowsrc)[^><]+/i',$text,$mat)){
  358. $text=str_replace($mat[0],$mat[1],$text);
  359. }
  360. while(preg_match('/(<[^><]+)(window\.|javascript:|js:|about:|file:|document\.|vbs:|cookie)([^><]*)/i',$text,$mat)){
  361. $text=str_replace($mat[0],$mat[1].$mat[3],$text);
  362. }
  363. if( empty($allowTags) ) { $allowTags = self::$htmlTags['allow']; }
  364. //允许的HTML标签
  365. $text = preg_replace('/<('.$allowTags.')( [^><\[\]]*)>/i','[\1\2]',$text);
  366. //过滤多余html
  367. if ( empty($banTag) ) { $banTag = self::$htmlTags['ban']; }
  368. $text = preg_replace('/<\/?('.$banTag.')[^><]*>/i','',$text);
  369. //过滤合法的html标签
  370. while(preg_match('/<([a-z]+)[^><\[\]]*>[^><]*<\/\1>/i',$text,$mat)){
  371. $text=str_replace($mat[0],str_replace('>',']',str_replace('<','[',$mat[0])),$text);
  372. }
  373. //转换引号
  374. while(preg_match('/(\[[^\[\]]*=\s*)(\"|\')([^\2=\[\]]+)\2([^\[\]]*\])/i',$text,$mat)){
  375. $text=str_replace($mat[0],$mat[1].'|'.$mat[3].'|'.$mat[4],$text);
  376. }
  377. //空属性转换
  378. $text = str_replace('\'\'','||',$text);
  379. $text = str_replace('""','||',$text);
  380. //过滤错误的单个引号
  381. while(preg_match('/\[[^\[\]]*(\"|\')[^\[\]]*\]/i',$text,$mat)){
  382. $text=str_replace($mat[0],str_replace($mat[1],'',$mat[0]),$text);
  383. }
  384. //转换其它所有不合法的 < >
  385. $text = str_replace('<','&lt;',$text);
  386. $text = str_replace('>','&gt;',$text);
  387. $text = str_replace('"','&quot;',$text);
  388. //反转换
  389. $text = str_replace('[','<',$text);
  390. $text = str_replace(']','>',$text);
  391. $text = str_replace('|','"',$text);
  392. //过滤多余空格
  393. $text = str_replace(' ',' ',$text);
  394. return $text;
  395. }
  396. /**
  397. +----------------------------------------------------------
  398. * 删除html标签,得到纯文本。可以处理嵌套的标签
  399. +----------------------------------------------------------
  400. * @access public
  401. +----------------------------------------------------------
  402. * @param string $string 要处理的html
  403. +----------------------------------------------------------
  404. * @return string
  405. +----------------------------------------------------------
  406. */
  407. static public function deleteHtmlTags($string) {
  408. while(strstr($string, '>')) {
  409. $currentBeg = strpos($string, '<');
  410. $currentEnd = strpos($string, '>');
  411. $tmpStringBeg = @substr($string, 0, $currentBeg);
  412. $tmpStringEnd = @substr($string, $currentEnd + 1, strlen($string));
  413. $string = $tmpStringBeg.$tmpStringEnd;
  414. }
  415. return $string;
  416. }
  417. /**
  418. +----------------------------------------------------------
  419. * 处理文本中的换行
  420. +----------------------------------------------------------
  421. * @access public
  422. +----------------------------------------------------------
  423. * @param string $string 要处理的字符串
  424. * @param mixed $br 对换行的处理,
  425. * false:去除换行;true:保留原样;string:替换成string
  426. +----------------------------------------------------------
  427. * @return string
  428. +----------------------------------------------------------
  429. */
  430. static public function nl2($string, $br = '<br />') {
  431. if ($br == false) {
  432. $string = preg_replace("/(\015\012)|(\015)|(\012)/", '', $string);
  433. } elseif ($br != true){
  434. $string = preg_replace("/(\015\012)|(\015)|(\012)/", $br, $string);
  435. }
  436. return $string;
  437. }
  438. }