1. 經常使用公共方法javascript
1 <?php 2 // +---------------------------------------------------------------------- 3 // | OneThink [ WE CAN DO IT JUST THINK IT ] 4 // +---------------------------------------------------------------------- 5 // | Copyright (c) 2013 http://www.onethink.cn All rights reserved. 6 // +---------------------------------------------------------------------- 7 // | Author: 麥當苗兒 <zuojiazi@vip.qq.com> <http://www.zjzit.cn> 8 // +---------------------------------------------------------------------- 9 10 // OneThink常量定義 11 const ONETHINK_VERSION = '1.1.141101'; 12 const ONETHINK_ADDON_PATH = './Addons/'; 13 14 /** 15 * 系統公共庫文件 16 * 主要定義系統公共函數庫 17 */ 18 19 /** 20 * 檢測用戶是否登陸 21 * @return integer 0-未登陸,大於0-當前登陸用戶ID 22 * @author 麥當苗兒 <zuojiazi@vip.qq.com> 23 */ 24 function is_login(){ 25 $user = session('user_auth'); 26 if (empty($user)) { 27 return 0; 28 } else { 29 return session('user_auth_sign') == data_auth_sign($user) ? $user['uid'] : 0; 30 } 31 } 32 33 /** 34 * 檢測當前用戶是否爲管理員 35 * @return boolean true-管理員,false-非管理員 36 * @author 麥當苗兒 <zuojiazi@vip.qq.com> 37 */ 38 function is_administrator($uid = null){ 39 $uid = is_null($uid) ? is_login() : $uid; 40 return $uid && (intval($uid) === C('USER_ADMINISTRATOR')); 41 } 42 43 /** 44 * 字符串轉換爲數組,主要用於把分隔符調整到第二個參數 45 * @param string $str 要分割的字符串 46 * @param string $glue 分割符 47 * @return array 48 * @author 麥當苗兒 <zuojiazi@vip.qq.com> 49 */ 50 function str2arr($str, $glue = ','){ 51 return explode($glue, $str); 52 } 53 54 /** 55 * 數組轉換爲字符串,主要用於把分隔符調整到第二個參數 56 * @param array $arr 要鏈接的數組 57 * @param string $glue 分割符 58 * @return string 59 * @author 麥當苗兒 <zuojiazi@vip.qq.com> 60 */ 61 function arr2str($arr, $glue = ','){ 62 return implode($glue, $arr); 63 } 64 65 /** 66 * 字符串截取,支持中文和其餘編碼 67 * @static 68 * @access public 69 * @param string $str 須要轉換的字符串 70 * @param string $start 開始位置 71 * @param string $length 截取長度 72 * @param string $charset 編碼格式 73 * @param string $suffix 截斷顯示字符 74 * @return string 75 */ 76 function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=true) { 77 if(function_exists("mb_substr")) 78 $slice = mb_substr($str, $start, $length, $charset); 79 elseif(function_exists('iconv_substr')) { 80 $slice = iconv_substr($str,$start,$length,$charset); 81 if(false === $slice) { 82 $slice = ''; 83 } 84 }else{ 85 $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/"; 86 $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/"; 87 $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/"; 88 $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/"; 89 preg_match_all($re[$charset], $str, $match); 90 $slice = join("",array_slice($match[0], $start, $length)); 91 } 92 return $suffix ? $slice.'...' : $slice; 93 } 94 95 /** 96 * 系統加密方法 97 * @param string $data 要加密的字符串 98 * @param string $key 加密密鑰 99 * @param int $expire 過時時間 單位 秒 100 * @return string 101 * @author 麥當苗兒 <zuojiazi@vip.qq.com> 102 */ 103 function think_encrypt($data, $key = '', $expire = 0) { 104 $key = md5(empty($key) ? C('DATA_AUTH_KEY') : $key); 105 $data = base64_encode($data); 106 $x = 0; 107 $len = strlen($data); 108 $l = strlen($key); 109 $char = ''; 110 111 for ($i = 0; $i < $len; $i++) { 112 if ($x == $l) $x = 0; 113 $char .= substr($key, $x, 1); 114 $x++; 115 } 116 117 $str = sprintf('%010d', $expire ? $expire + time():0); 118 119 for ($i = 0; $i < $len; $i++) { 120 $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1)))%256); 121 } 122 return str_replace(array('+','/','='),array('-','_',''),base64_encode($str)); 123 } 124 125 /** 126 * 系統解密方法 127 * @param string $data 要解密的字符串 (必須是think_encrypt方法加密的字符串) 128 * @param string $key 加密密鑰 129 * @return string 130 * @author 麥當苗兒 <zuojiazi@vip.qq.com> 131 */ 132 function think_decrypt($data, $key = ''){ 133 $key = md5(empty($key) ? C('DATA_AUTH_KEY') : $key); 134 $data = str_replace(array('-','_'),array('+','/'),$data); 135 $mod4 = strlen($data) % 4; 136 if ($mod4) { 137 $data .= substr('====', $mod4); 138 } 139 $data = base64_decode($data); 140 $expire = substr($data,0,10); 141 $data = substr($data,10); 142 143 if($expire > 0 && $expire < time()) { 144 return ''; 145 } 146 $x = 0; 147 $len = strlen($data); 148 $l = strlen($key); 149 $char = $str = ''; 150 151 for ($i = 0; $i < $len; $i++) { 152 if ($x == $l) $x = 0; 153 $char .= substr($key, $x, 1); 154 $x++; 155 } 156 157 for ($i = 0; $i < $len; $i++) { 158 if (ord(substr($data, $i, 1))<ord(substr($char, $i, 1))) { 159 $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1))); 160 }else{ 161 $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1))); 162 } 163 } 164 return base64_decode($str); 165 } 166 167 /** 168 * 數據簽名認證 169 * @param array $data 被認證的數據 170 * @return string 簽名 171 * @author 麥當苗兒 <zuojiazi@vip.qq.com> 172 */ 173 function data_auth_sign($data) { 174 //數據類型檢測 175 if(!is_array($data)){ 176 $data = (array)$data; 177 } 178 ksort($data); //排序 179 $code = http_build_query($data); //url編碼並生成query字符串 180 $sign = sha1($code); //生成簽名 181 return $sign; 182 } 183 184 /** 185 * 對查詢結果集進行排序 186 * @access public 187 * @param array $list 查詢結果 188 * @param string $field 排序的字段名 189 * @param array $sortby 排序類型 190 * asc正向排序 desc逆向排序 nat天然排序 191 * @return array 192 */ 193 function list_sort_by($list,$field, $sortby='asc') { 194 if(is_array($list)){ 195 $refer = $resultSet = array(); 196 foreach ($list as $i => $data) 197 $refer[$i] = &$data[$field]; 198 switch ($sortby) { 199 case 'asc': // 正向排序 200 asort($refer); 201 break; 202 case 'desc':// 逆向排序 203 arsort($refer); 204 break; 205 case 'nat': // 天然排序 206 natcasesort($refer); 207 break; 208 } 209 foreach ( $refer as $key=> $val) 210 $resultSet[] = &$list[$key]; 211 return $resultSet; 212 } 213 return false; 214 } 215 216 /** 217 * 把返回的數據集轉換成Tree 218 * @param array $list 要轉換的數據集 219 * @param string $pid parent標記字段 220 * @param string $level level標記字段 221 * @return array 222 * @author 麥當苗兒 <zuojiazi@vip.qq.com> 223 */ 224 function list_to_tree($list, $pk='id', $pid = 'pid', $child = '_child', $root = 0) { 225 // 建立Tree 226 $tree = array(); 227 if(is_array($list)) { 228 // 建立基於主鍵的數組引用 229 $refer = array(); 230 foreach ($list as $key => $data) { 231 $refer[$data[$pk]] =& $list[$key]; 232 } 233 foreach ($list as $key => $data) { 234 // 判斷是否存在parent 235 $parentId = $data[$pid]; 236 if ($root == $parentId) { 237 $tree[] =& $list[$key]; 238 }else{ 239 if (isset($refer[$parentId])) { 240 $parent =& $refer[$parentId]; 241 $parent[$child][] =& $list[$key]; 242 } 243 } 244 } 245 } 246 return $tree; 247 } 248 249 /** 250 * 將list_to_tree的樹還原成列表 251 * @param array $tree 原來的樹 252 * @param string $child 孩子節點的鍵 253 * @param string $order 排序顯示的鍵,通常是主鍵 升序排列 254 * @param array $list 過渡用的中間數組, 255 * @return array 返回排過序的列表數組 256 * @author yangweijie <yangweijiester@gmail.com> 257 */ 258 function tree_to_list($tree, $child = '_child', $order='id', &$list = array()){ 259 if(is_array($tree)) { 260 foreach ($tree as $key => $value) { 261 $reffer = $value; 262 if(isset($reffer[$child])){ 263 unset($reffer[$child]); 264 tree_to_list($value[$child], $child, $order, $list); 265 } 266 $list[] = $reffer; 267 } 268 $list = list_sort_by($list, $order, $sortby='asc'); 269 } 270 return $list; 271 } 272 273 /** 274 * 格式化字節大小 275 * @param number $size 字節數 276 * @param string $delimiter 數字和單位分隔符 277 * @return string 格式化後的帶單位的大小 278 * @author 麥當苗兒 <zuojiazi@vip.qq.com> 279 */ 280 function format_bytes($size, $delimiter = '') { 281 $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB'); 282 for ($i = 0; $size >= 1024 && $i < 5; $i++) $size /= 1024; 283 return round($size, 2) . $delimiter . $units[$i]; 284 } 285 286 /** 287 * 設置跳轉頁面URL 288 * 使用函數再次封裝,方便之後選擇不一樣的存儲方式(目前使用cookie存儲) 289 * @author 麥當苗兒 <zuojiazi@vip.qq.com> 290 */ 291 function set_redirect_url($url){ 292 cookie('redirect_url', $url); 293 } 294 295 /** 296 * 獲取跳轉頁面URL 297 * @return string 跳轉頁URL 298 * @author 麥當苗兒 <zuojiazi@vip.qq.com> 299 */ 300 function get_redirect_url(){ 301 $url = cookie('redirect_url'); 302 return empty($url) ? __APP__ : $url; 303 } 304 305 /** 306 * 處理插件鉤子 307 * @param string $hook 鉤子名稱 308 * @param mixed $params 傳入參數 309 * @return void 310 */ 311 function hook($hook,$params=array()){ 312 \Think\Hook::listen($hook,$params); 313 } 314 315 /** 316 * 獲取插件類的類名 317 * @param strng $name 插件名 318 */ 319 function get_addon_class($name){ 320 $class = "Addons\\{$name}\\{$name}Addon"; 321 return $class; 322 } 323 324 /** 325 * 獲取插件類的配置文件數組 326 * @param string $name 插件名 327 */ 328 function get_addon_config($name){ 329 $class = get_addon_class($name); 330 if(class_exists($class)) { 331 $addon = new $class(); 332 return $addon->getConfig(); 333 }else { 334 return array(); 335 } 336 } 337 338 /** 339 * 插件顯示內容裏生成訪問插件的url 340 * @param string $url url 341 * @param array $param 參數 342 * @author 麥當苗兒 <zuojiazi@vip.qq.com> 343 */ 344 function addons_url($url, $param = array()){ 345 $url = parse_url($url); 346 $case = C('URL_CASE_INSENSITIVE'); 347 $addons = $case ? parse_name($url['scheme']) : $url['scheme']; 348 $controller = $case ? parse_name($url['host']) : $url['host']; 349 $action = trim($case ? strtolower($url['path']) : $url['path'], '/'); 350 351 /* 解析URL帶的參數 */ 352 if(isset($url['query'])){ 353 parse_str($url['query'], $query); 354 $param = array_merge($query, $param); 355 } 356 357 /* 基礎參數 */ 358 $params = array( 359 '_addons' => $addons, 360 '_controller' => $controller, 361 '_action' => $action, 362 ); 363 $params = array_merge($params, $param); //添加額外參數 364 365 return U('Addons/execute', $params); 366 } 367 368 /** 369 * 時間戳格式化 370 * @param int $time 371 * @return string 完整的時間顯示 372 * @author huajie <banhuajie@163.com> 373 */ 374 function time_format($time = NULL,$format='Y-m-d H:i'){ 375 $time = $time === NULL ? NOW_TIME : intval($time); 376 return date($format, $time); 377 } 378 379 /** 380 * 根據用戶ID獲取用戶名 381 * @param integer $uid 用戶ID 382 * @return string 用戶名 383 */ 384 function get_username($uid = 0){ 385 static $list; 386 if(!($uid && is_numeric($uid))){ //獲取當前登陸用戶名 387 return session('user_auth.username'); 388 } 389 390 /* 獲取緩存數據 */ 391 if(empty($list)){ 392 $list = S('sys_active_user_list'); 393 } 394 395 /* 查找用戶信息 */ 396 $key = "u{$uid}"; 397 if(isset($list[$key])){ //已緩存,直接使用 398 $name = $list[$key]; 399 } else { //調用接口獲取用戶信息 400 $User = new User\Api\UserApi(); 401 $info = $User->info($uid); 402 if($info && isset($info[1])){ 403 $name = $list[$key] = $info[1]; 404 /* 緩存用戶 */ 405 $count = count($list); 406 $max = C('USER_MAX_CACHE'); 407 while ($count-- > $max) { 408 array_shift($list); 409 } 410 S('sys_active_user_list', $list); 411 } else { 412 $name = ''; 413 } 414 } 415 return $name; 416 } 417 418 /** 419 * 根據用戶ID獲取用戶暱稱 420 * @param integer $uid 用戶ID 421 * @return string 用戶暱稱 422 */ 423 function get_nickname($uid = 0){ 424 static $list; 425 if(!($uid && is_numeric($uid))){ //獲取當前登陸用戶名 426 return session('user_auth.username'); 427 } 428 429 /* 獲取緩存數據 */ 430 if(empty($list)){ 431 $list = S('sys_user_nickname_list'); 432 } 433 434 /* 查找用戶信息 */ 435 $key = "u{$uid}"; 436 if(isset($list[$key])){ //已緩存,直接使用 437 $name = $list[$key]; 438 } else { //調用接口獲取用戶信息 439 $info = M('Member')->field('nickname')->find($uid); 440 if($info !== false && $info['nickname'] ){ 441 $nickname = $info['nickname']; 442 $name = $list[$key] = $nickname; 443 /* 緩存用戶 */ 444 $count = count($list); 445 $max = C('USER_MAX_CACHE'); 446 while ($count-- > $max) { 447 array_shift($list); 448 } 449 S('sys_user_nickname_list', $list); 450 } else { 451 $name = ''; 452 } 453 } 454 return $name; 455 } 456 457 /** 458 * 獲取分類信息並緩存分類 459 * @param integer $id 分類ID 460 * @param string $field 要獲取的字段名 461 * @return string 分類信息 462 */ 463 function get_category($id, $field = null){ 464 static $list; 465 466 /* 非法分類ID */ 467 if(empty($id) || !is_numeric($id)){ 468 return ''; 469 } 470 471 /* 讀取緩存數據 */ 472 if(empty($list)){ 473 $list = S('sys_category_list'); 474 } 475 476 /* 獲取分類名稱 */ 477 if(!isset($list[$id])){ 478 $cate = M('Category')->find($id); 479 if(!$cate || 1 != $cate['status']){ //不存在分類,或分類被禁用 480 return ''; 481 } 482 $list[$id] = $cate; 483 S('sys_category_list', $list); //更新緩存 484 } 485 return is_null($field) ? $list[$id] : $list[$id][$field]; 486 } 487 488 /* 根據ID獲取分類標識 */ 489 function get_category_name($id){ 490 return get_category($id, 'name'); 491 } 492 493 /* 根據ID獲取分類名稱 */ 494 function get_category_title($id){ 495 return get_category($id, 'title'); 496 } 497 498 /** 499 * 獲取頂級模型信息 500 */ 501 function get_top_model($model_id=null){ 502 $map = array('status' => 1, 'extend' => 0); 503 if(!is_null($model_id)){ 504 $map['id'] = array('neq',$model_id); 505 } 506 $model = M('Model')->where($map)->field(true)->select(); 507 foreach ($model as $value) { 508 $list[$value['id']] = $value; 509 } 510 return $list; 511 } 512 513 /** 514 * 獲取文檔模型信息 515 * @param integer $id 模型ID 516 * @param string $field 模型字段 517 * @return array 518 */ 519 function get_document_model($id = null, $field = null){ 520 static $list; 521 522 /* 非法分類ID */ 523 if(!(is_numeric($id) || is_null($id))){ 524 return ''; 525 } 526 527 /* 讀取緩存數據 */ 528 if(empty($list)){ 529 $list = S('DOCUMENT_MODEL_LIST'); 530 } 531 532 /* 獲取模型名稱 */ 533 if(empty($list)){ 534 $map = array('status' => 1, 'extend' => 1); 535 $model = M('Model')->where($map)->field(true)->select(); 536 foreach ($model as $value) { 537 $list[$value['id']] = $value; 538 } 539 S('DOCUMENT_MODEL_LIST', $list); //更新緩存 540 } 541 542 /* 根據條件返回數據 */ 543 if(is_null($id)){ 544 return $list; 545 } elseif(is_null($field)){ 546 return $list[$id]; 547 } else { 548 return $list[$id][$field]; 549 } 550 } 551 552 /** 553 * 解析UBB數據 554 * @param string $data UBB字符串 555 * @return string 解析爲HTML的數據 556 * @author 麥當苗兒 <zuojiazi@vip.qq.com> 557 */ 558 function ubb($data){ 559 //TODO: 待完善,目前返回原始數據 560 return $data; 561 } 562 563 /** 564 * 記錄行爲日誌,並執行該行爲的規則 565 * @param string $action 行爲標識 566 * @param string $model 觸發行爲的模型名 567 * @param int $record_id 觸發行爲的記錄id 568 * @param int $user_id 執行行爲的用戶id 569 * @return boolean 570 * @author huajie <banhuajie@163.com> 571 */ 572 function action_log($action = null, $model = null, $record_id = null, $user_id = null){ 573 574 //參數檢查 575 if(empty($action) || empty($model) || empty($record_id)){ 576 return '參數不能爲空'; 577 } 578 if(empty($user_id)){ 579 $user_id = is_login(); 580 } 581 582 //查詢行爲,判斷是否執行 583 $action_info = M('Action')->getByName($action); 584 if($action_info['status'] != 1){ 585 return '該行爲被禁用或刪除'; 586 } 587 588 //插入行爲日誌 589 $data['action_id'] = $action_info['id']; 590 $data['user_id'] = $user_id; 591 $data['action_ip'] = ip2long(get_client_ip()); 592 $data['model'] = $model; 593 $data['record_id'] = $record_id; 594 $data['create_time'] = NOW_TIME; 595 596 //解析日誌規則,生成日誌備註 597 if(!empty($action_info['log'])){ 598 if(preg_match_all('/\[(\S+?)\]/', $action_info['log'], $match)){ 599 $log['user'] = $user_id; 600 $log['record'] = $record_id; 601 $log['model'] = $model; 602 $log['time'] = NOW_TIME; 603 $log['data'] = array('user'=>$user_id,'model'=>$model,'record'=>$record_id,'time'=>NOW_TIME); 604 foreach ($match[1] as $value){ 605 $param = explode('|', $value); 606 if(isset($param[1])){ 607 $replace[] = call_user_func($param[1],$log[$param[0]]); 608 }else{ 609 $replace[] = $log[$param[0]]; 610 } 611 } 612 $data['remark'] = str_replace($match[0], $replace, $action_info['log']); 613 }else{ 614 $data['remark'] = $action_info['log']; 615 } 616 }else{ 617 //未定義日誌規則,記錄操做url 618 $data['remark'] = '操做url:'.$_SERVER['REQUEST_URI']; 619 } 620 621 M('ActionLog')->add($data); 622 623 if(!empty($action_info['rule'])){ 624 //解析行爲 625 $rules = parse_action($action, $user_id); 626 627 //執行行爲 628 $res = execute_action($rules, $action_info['id'], $user_id); 629 } 630 } 631 632 /** 633 * 解析行爲規則 634 * 規則定義 table:$table|field:$field|condition:$condition|rule:$rule[|cycle:$cycle|max:$max][;......] 635 * 規則字段解釋:table->要操做的數據表,不須要加表前綴; 636 * field->要操做的字段; 637 * condition->操做的條件,目前支持字符串,默認變量{$self}爲執行行爲的用戶 638 * rule->對字段進行的具體操做,目前支持四則混合運算,如:1+score*2/2-3 639 * cycle->執行週期,單位(小時),表示$cycle小時內最多執行$max次 640 * max->單個週期內的最大執行次數($cycle和$max必須同時定義,不然無效) 641 * 單個行爲後可加 ; 鏈接其餘規則 642 * @param string $action 行爲id或者name 643 * @param int $self 替換規則裏的變量爲執行用戶的id 644 * @return boolean|array: false解析出錯 , 成功返回規則數組 645 * @author huajie <banhuajie@163.com> 646 */ 647 function parse_action($action = null, $self){ 648 if(empty($action)){ 649 return false; 650 } 651 652 //參數支持id或者name 653 if(is_numeric($action)){ 654 $map = array('id'=>$action); 655 }else{ 656 $map = array('name'=>$action); 657 } 658 659 //查詢行爲信息 660 $info = M('Action')->where($map)->find(); 661 if(!$info || $info['status'] != 1){ 662 return false; 663 } 664 665 //解析規則:table:$table|field:$field|condition:$condition|rule:$rule[|cycle:$cycle|max:$max][;......] 666 $rules = $info['rule']; 667 $rules = str_replace('{$self}', $self, $rules); 668 $rules = explode(';', $rules); 669 $return = array(); 670 foreach ($rules as $key=>&$rule){ 671 $rule = explode('|', $rule); 672 foreach ($rule as $k=>$fields){ 673 $field = empty($fields) ? array() : explode(':', $fields); 674 if(!empty($field)){ 675 $return[$key][$field[0]] = $field[1]; 676 } 677 } 678 //cycle(檢查週期)和max(週期內最大執行次數)必須同時存在,不然去掉這兩個條件 679 if(!array_key_exists('cycle', $return[$key]) || !array_key_exists('max', $return[$key])){ 680 unset($return[$key]['cycle'],$return[$key]['max']); 681 } 682 } 683 684 return $return; 685 } 686 687 /** 688 * 執行行爲 689 * @param array $rules 解析後的規則數組 690 * @param int $action_id 行爲id 691 * @param array $user_id 執行的用戶id 692 * @return boolean false 失敗 , true 成功 693 * @author huajie <banhuajie@163.com> 694 */ 695 function execute_action($rules = false, $action_id = null, $user_id = null){ 696 if(!$rules || empty($action_id) || empty($user_id)){ 697 return false; 698 } 699 700 $return = true; 701 foreach ($rules as $rule){ 702 703 //檢查執行週期 704 $map = array('action_id'=>$action_id, 'user_id'=>$user_id); 705 $map['create_time'] = array('gt', NOW_TIME - intval($rule['cycle']) * 3600); 706 $exec_count = M('ActionLog')->where($map)->count(); 707 if($exec_count > $rule['max']){ 708 continue; 709 } 710 711 //執行數據庫操做 712 $Model = M(ucfirst($rule['table'])); 713 $field = $rule['field']; 714 $res = $Model->where($rule['condition'])->setField($field, array('exp', $rule['rule'])); 715 716 if(!$res){ 717 $return = false; 718 } 719 } 720 return $return; 721 } 722 723 //基於數組建立目錄和文件 724 function create_dir_or_files($files){ 725 foreach ($files as $key => $value) { 726 if(substr($value, -1) == '/'){ 727 mkdir($value); 728 }else{ 729 @file_put_contents($value, ''); 730 } 731 } 732 } 733 734 if(!function_exists('array_column')){ 735 function array_column(array $input, $columnKey, $indexKey = null) { 736 $result = array(); 737 if (null === $indexKey) { 738 if (null === $columnKey) { 739 $result = array_values($input); 740 } else { 741 foreach ($input as $row) { 742 $result[] = $row[$columnKey]; 743 } 744 } 745 } else { 746 if (null === $columnKey) { 747 foreach ($input as $row) { 748 $result[$row[$indexKey]] = $row; 749 } 750 } else { 751 foreach ($input as $row) { 752 $result[$row[$indexKey]] = $row[$columnKey]; 753 } 754 } 755 } 756 return $result; 757 } 758 } 759 760 /** 761 * 獲取表名(不含表前綴) 762 * @param string $model_id 763 * @return string 表名 764 * @author huajie <banhuajie@163.com> 765 */ 766 function get_table_name($model_id = null){ 767 if(empty($model_id)){ 768 return false; 769 } 770 $Model = M('Model'); 771 $name = ''; 772 $info = $Model->getById($model_id); 773 if($info['extend'] != 0){ 774 $name = $Model->getFieldById($info['extend'], 'name').'_'; 775 } 776 $name .= $info['name']; 777 return $name; 778 } 779 780 /** 781 * 獲取屬性信息並緩存 782 * @param integer $id 屬性ID 783 * @param string $field 要獲取的字段名 784 * @return string 屬性信息 785 */ 786 function get_model_attribute($model_id, $group = true,$fields=true){ 787 static $list; 788 789 /* 非法ID */ 790 if(empty($model_id) || !is_numeric($model_id)){ 791 return ''; 792 } 793 794 /* 獲取屬性 */ 795 if(!isset($list[$model_id])){ 796 $map = array('model_id'=>$model_id); 797 $extend = M('Model')->getFieldById($model_id,'extend'); 798 799 if($extend){ 800 $map = array('model_id'=> array("in", array($model_id, $extend))); 801 } 802 $info = M('Attribute')->where($map)->field($fields)->select(); 803 $list[$model_id] = $info; 804 } 805 806 $attr = array(); 807 if($group){ 808 foreach ($list[$model_id] as $value) { 809 $attr[$value['id']] = $value; 810 } 811 $model = M("Model")->field("field_sort,attribute_list,attribute_alias")->find($model_id); 812 $attribute = explode(",", $model['attribute_list']); 813 if (empty($model['field_sort'])) { //未排序 814 $group = array(1 => array_merge($attr)); 815 } else { 816 $group = json_decode($model['field_sort'], true); 817 818 $keys = array_keys($group); 819 foreach ($group as &$value) { 820 foreach ($value as $key => $val) { 821 $value[$key] = $attr[$val]; 822 unset($attr[$val]); 823 } 824 } 825 826 if (!empty($attr)) { 827 foreach ($attr as $key => $val) { 828 if (!in_array($val['id'], $attribute)) { 829 unset($attr[$key]); 830 } 831 } 832 $group[$keys[0]] = array_merge($group[$keys[0]], $attr); 833 } 834 } 835 if (!empty($model['attribute_alias'])) { 836 $alias = preg_split('/[;\r\n]+/s', $model['attribute_alias']); 837 $fields = array(); 838 foreach ($alias as &$value) { 839 $val = explode(':', $value); 840 $fields[$val[0]] = $val[1]; 841 } 842 foreach ($group as &$value) { 843 foreach ($value as $key => $val) { 844 if (!empty($fields[$val['name']])) { 845 $value[$key]['title'] = $fields[$val['name']]; 846 } 847 } 848 } 849 } 850 $attr = $group; 851 }else{ 852 foreach ($list[$model_id] as $value) { 853 $attr[$value['name']] = $value; 854 } 855 } 856 return $attr; 857 } 858 859 /** 860 * 調用系統的API接口方法(靜態方法) 861 * api('User/getName','id=5'); 調用公共模塊的User接口的getName方法 862 * api('Admin/User/getName','id=5'); 調用Admin模塊的User接口 863 * @param string $name 格式 [模塊名]/接口名/方法名 864 * @param array|string $vars 參數 865 */ 866 function api($name,$vars=array()){ 867 $array = explode('/',$name); 868 $method = array_pop($array); 869 $classname = array_pop($array); 870 $module = $array? array_pop($array) : 'Common'; 871 $callback = $module.'\\Api\\'.$classname.'Api::'.$method; 872 if(is_string($vars)) { 873 parse_str($vars,$vars); 874 } 875 return call_user_func_array($callback,$vars); 876 } 877 878 /** 879 * 根據條件字段獲取指定表的數據 880 * @param mixed $value 條件,可用常量或者數組 881 * @param string $condition 條件字段 882 * @param string $field 須要返回的字段,不傳則返回整個數據 883 * @param string $table 須要查詢的表 884 * @author huajie <banhuajie@163.com> 885 */ 886 function get_table_field($value = null, $condition = 'id', $field = null, $table = null){ 887 if(empty($value) || empty($table)){ 888 return false; 889 } 890 891 //拼接參數 892 $map[$condition] = $value; 893 $info = M(ucfirst($table))->where($map); 894 if(empty($field)){ 895 $info = $info->field(true)->find(); 896 }else{ 897 $info = $info->getField($field); 898 } 899 return $info; 900 } 901 902 /** 903 * 獲取連接信息 904 * @param int $link_id 905 * @param string $field 906 * @return 完整的連接信息或者某一字段 907 * @author huajie <banhuajie@163.com> 908 */ 909 function get_link($link_id = null, $field = 'url'){ 910 $link = ''; 911 if(empty($link_id)){ 912 return $link; 913 } 914 $link = M('Url')->getById($link_id); 915 if(empty($field)){ 916 return $link; 917 }else{ 918 return $link[$field]; 919 } 920 } 921 922 /** 923 * 獲取文檔封面圖片 924 * @param int $cover_id 925 * @param string $field 926 * @return 完整的數據 或者 指定的$field字段值 927 * @author huajie <banhuajie@163.com> 928 */ 929 function get_cover($cover_id, $field = null){ 930 if(empty($cover_id)){ 931 return false; 932 } 933 $picture = M('Picture')->where(array('status'=>1))->getById($cover_id); 934 if($field == 'path'){ 935 if(!empty($picture['url'])){ 936 $picture['path'] = $picture['url']; 937 }else{ 938 $picture['path'] = __ROOT__.$picture['path']; 939 } 940 } 941 return empty($field) ? $picture : $picture[$field]; 942 } 943 944 /** 945 * 檢查$pos(推薦位的值)是否包含指定推薦位$contain 946 * @param number $pos 推薦位的值 947 * @param number $contain 指定推薦位 948 * @return boolean true 包含 , false 不包含 949 * @author huajie <banhuajie@163.com> 950 */ 951 function check_document_position($pos = 0, $contain = 0){ 952 if(empty($pos) || empty($contain)){ 953 return false; 954 } 955 956 //將兩個參數進行按位與運算,不爲0則表示$contain屬於$pos 957 $res = $pos & $contain; 958 if($res !== 0){ 959 return true; 960 }else{ 961 return false; 962 } 963 } 964 965 /** 966 * 獲取數據的全部子孫數據的id值 967 * @author 朱亞傑 <xcoolcc@gmail.com> 968 */ 969 970 function get_stemma($pids,Model &$model, $field='id'){ 971 $collection = array(); 972 973 //非空判斷 974 if(empty($pids)){ 975 return $collection; 976 } 977 978 if( is_array($pids) ){ 979 $pids = trim(implode(',',$pids),','); 980 } 981 $result = $model->field($field)->where(array('pid'=>array('IN',(string)$pids)))->select(); 982 $child_ids = array_column ((array)$result,'id'); 983 984 while( !empty($child_ids) ){ 985 $collection = array_merge($collection,$result); 986 $result = $model->field($field)->where( array( 'pid'=>array( 'IN', $child_ids ) ) )->select(); 987 $child_ids = array_column((array)$result,'id'); 988 } 989 return $collection; 990 } 991 992 /** 993 * 驗證分類是否容許發佈內容 994 * @param integer $id 分類ID 995 * @return boolean true-容許發佈內容,false-不容許發佈內容 996 */ 997 function check_category($id){ 998 if (is_array($id)) { 999 $id['type'] = !empty($id['type'])?$id['type']:2; 1000 $type = get_category($id['category_id'], 'type'); 1001 $type = explode(",", $type); 1002 return in_array($id['type'], $type); 1003 } else { 1004 $publish = get_category($id, 'allow_publish'); 1005 return $publish ? true : false; 1006 } 1007 } 1008 1009 /** 1010 * 檢測分類是否綁定了指定模型 1011 * @param array $info 模型ID和分類ID數組 1012 * @return boolean true-綁定了模型,false-未綁定模型 1013 */ 1014 function check_category_model($info){ 1015 $cate = get_category($info['category_id']); 1016 $array = explode(',', $info['pid'] ? $cate['model_sub'] : $cate['model']); 1017 return in_array($info['model_id'], $array); 1018 }
2. 安裝公共方法php
1 <?php 2 // +---------------------------------------------------------------------- 3 // | OneThink [ WE CAN DO IT JUST THINK IT ] 4 // +---------------------------------------------------------------------- 5 // | Copyright (c) 2013 http://www.onethink.cn All rights reserved. 6 // +---------------------------------------------------------------------- 7 // | Author: 麥當苗兒 <zuojiazi@vip.qq.com> <http://www.zjzit.cn> 8 // +---------------------------------------------------------------------- 9 10 // 檢測環境是否支持可寫 11 define('IS_WRITE',APP_MODE !== 'sae'); 12 13 /** 14 * 系統環境檢測 15 * @return array 系統環境數據 16 */ 17 function check_env(){ 18 $items = array( 19 'os' => array('操做系統', '不限制', '類Unix', PHP_OS, 'success'), 20 'php' => array('PHP版本', '5.3', '5.3+', PHP_VERSION, 'success'), 21 'upload' => array('附件上傳', '不限制', '2M+', '未知', 'success'), 22 'gd' => array('GD庫', '2.0', '2.0+', '未知', 'success'), 23 'disk' => array('磁盤空間', '5M', '不限制', '未知', 'success'), 24 ); 25 26 //PHP環境檢測 27 if($items['php'][3] < $items['php'][1]){ 28 $items['php'][4] = 'error'; 29 session('error', true); 30 } 31 32 //附件上傳檢測 33 if(@ini_get('file_uploads')) 34 $items['upload'][3] = ini_get('upload_max_filesize'); 35 36 //GD庫檢測 37 $tmp = function_exists('gd_info') ? gd_info() : array(); 38 if(empty($tmp['GD Version'])){ 39 $items['gd'][3] = '未安裝'; 40 $items['gd'][4] = 'error'; 41 session('error', true); 42 } else { 43 $items['gd'][3] = $tmp['GD Version']; 44 } 45 unset($tmp); 46 47 //磁盤空間檢測 48 if(function_exists('disk_free_space')) { 49 $items['disk'][3] = floor(disk_free_space(INSTALL_APP_PATH) / (1024*1024)).'M'; 50 } 51 52 return $items; 53 } 54 55 /** 56 * 目錄,文件讀寫檢測 57 * @return array 檢測數據 58 */ 59 function check_dirfile(){ 60 $items = array( 61 array('dir', '可寫', 'success', './Uploads/Download'), 62 array('dir', '可寫', 'success', './Uploads/Picture'), 63 array('dir', '可寫', 'success', './Uploads/Editor'), 64 array('dir', '可寫', 'success', './Runtime'), 65 array('dir', '可寫', 'success', './Data'), 66 array('dir', '可寫', 'success', './Application/User/Conf'), 67 array('file', '可寫', 'success', './Application/Common/Conf'), 68 69 ); 70 71 foreach ($items as &$val) { 72 $item = INSTALL_APP_PATH . $val[3]; 73 if('dir' == $val[0]){ 74 if(!is_writable($item)) { 75 if(is_dir($items)) { 76 $val[1] = '可讀'; 77 $val[2] = 'error'; 78 session('error', true); 79 } else { 80 $val[1] = '不存在'; 81 $val[2] = 'error'; 82 session('error', true); 83 } 84 } 85 } else { 86 if(file_exists($item)) { 87 if(!is_writable($item)) { 88 $val[1] = '不可寫'; 89 $val[2] = 'error'; 90 session('error', true); 91 } 92 } else { 93 if(!is_writable(dirname($item))) { 94 $val[1] = '不存在'; 95 $val[2] = 'error'; 96 session('error', true); 97 } 98 } 99 } 100 } 101 102 return $items; 103 } 104 105 /** 106 * 函數檢測 107 * @return array 檢測數據 108 */ 109 function check_func(){ 110 $items = array( 111 array('pdo','支持','success','類'), 112 array('pdo_mysql','支持','success','模塊'), 113 array('file_get_contents', '支持', 'success','函數'), 114 array('mb_strlen', '支持', 'success','函數'), 115 ); 116 117 foreach ($items as &$val) { 118 if(('類'==$val[3] && !class_exists($val[0])) 119 || ('模塊'==$val[3] && !extension_loaded($val[0])) 120 || ('函數'==$val[3] && !function_exists($val[0])) 121 ){ 122 $val[1] = '不支持'; 123 $val[2] = 'error'; 124 session('error', true); 125 } 126 } 127 128 return $items; 129 } 130 131 /** 132 * 寫入配置文件 133 * @param array $config 配置信息 134 */ 135 function write_config($config, $auth){ 136 if(is_array($config)){ 137 //讀取配置內容 138 $conf = file_get_contents(MODULE_PATH . 'Data/conf.tpl'); 139 $user = file_get_contents(MODULE_PATH . 'Data/user.tpl'); 140 //替換配置項 141 foreach ($config as $name => $value) { 142 $conf = str_replace("[{$name}]", $value, $conf); 143 $user = str_replace("[{$name}]", $value, $user); 144 } 145 146 $conf = str_replace('[AUTH_KEY]', $auth, $conf); 147 $user = str_replace('[AUTH_KEY]', $auth, $user); 148 149 //寫入應用配置文件 150 if(!IS_WRITE){ 151 return '因爲您的環境不可寫,請複製下面的配置文件內容覆蓋到相關的配置文件,而後再登陸後臺。<p>'.realpath(APP_PATH).'/Common/Conf/config.php</p> 152 <textarea name="" style="width:650px;height:185px">'.$conf.'</textarea> 153 <p>'.realpath(APP_PATH).'/User/Conf/config.php</p> 154 <textarea name="" style="width:650px;height:125px">'.$user.'</textarea>'; 155 }else{ 156 if(file_put_contents(APP_PATH . 'Common/Conf/config.php', $conf) && 157 file_put_contents(APP_PATH . 'User/Conf/config.php', $user)){ 158 show_msg('配置文件寫入成功'); 159 } else { 160 show_msg('配置文件寫入失敗!', 'error'); 161 session('error', true); 162 } 163 return ''; 164 } 165 166 } 167 } 168 169 /** 170 * 建立數據表 171 * @param resource $db 數據庫鏈接資源 172 */ 173 function create_tables($db, $prefix = ''){ 174 //讀取SQL文件 175 $sql = file_get_contents(MODULE_PATH . 'Data/install.sql'); 176 $sql = str_replace("\r", "\n", $sql); 177 $sql = explode(";\n", $sql); 178 179 //替換表前綴 180 $orginal = C('ORIGINAL_TABLE_PREFIX'); 181 $sql = str_replace(" `{$orginal}", " `{$prefix}", $sql); 182 183 //開始安裝 184 show_msg('開始安裝數據庫...'); 185 foreach ($sql as $value) { 186 $value = trim($value); 187 if(empty($value)) continue; 188 if(substr($value, 0, 12) == 'CREATE TABLE') { 189 $name = preg_replace("/^CREATE TABLE `(\w+)` .*/s", "\\1", $value); 190 $msg = "建立數據表{$name}"; 191 if(false !== $db->execute($value)){ 192 show_msg($msg . '...成功'); 193 } else { 194 show_msg($msg . '...失敗!', 'error'); 195 session('error', true); 196 } 197 } else { 198 $db->execute($value); 199 } 200 201 } 202 } 203 204 function register_administrator($db, $prefix, $admin, $auth){ 205 show_msg('開始註冊創始人賬號...'); 206 $sql = "INSERT INTO `[PREFIX]ucenter_member` VALUES " . 207 "('1', '[NAME]', '[PASS]', '[EMAIL]', '', '[TIME]', '[IP]', 0, 0, '[TIME]', '1')"; 208 209 $password = user_md5($admin['password'], $auth); 210 $sql = str_replace( 211 array('[PREFIX]', '[NAME]', '[PASS]', '[EMAIL]', '[TIME]', '[IP]'), 212 array($prefix, $admin['username'], $password, $admin['email'], NOW_TIME, get_client_ip(1)), 213 $sql); 214 //執行sql 215 $db->execute($sql); 216 217 $sql = "INSERT INTO `[PREFIX]member` VALUES ". 218 "('1', '[NAME]', '0', '0000-00-00', '', '0', '1', '0', '[TIME]', '0', '[TIME]', '1');"; 219 $sql = str_replace( 220 array('[PREFIX]', '[NAME]', '[TIME]'), 221 array($prefix, $admin['username'], NOW_TIME), 222 $sql); 223 $db->execute($sql); 224 show_msg('創始人賬號註冊完成!'); 225 } 226 227 /** 228 * 更新數據表 229 * @param resource $db 數據庫鏈接資源 230 * @author lyq <605415184@qq.com> 231 */ 232 function update_tables($db, $prefix = ''){ 233 //讀取SQL文件 234 $sql = file_get_contents(MODULE_PATH . 'Data/update.sql'); 235 $sql = str_replace("\r", "\n", $sql); 236 $sql = explode(";\n", $sql); 237 238 //替換表前綴 239 $sql = str_replace(" `onethink_", " `{$prefix}", $sql); 240 241 //開始安裝 242 show_msg('開始升級數據庫...'); 243 foreach ($sql as $value) { 244 $value = trim($value); 245 if(empty($value)) continue; 246 if(substr($value, 0, 12) == 'CREATE TABLE') { 247 $name = preg_replace("/^CREATE TABLE `(\w+)` .*/s", "\\1", $value); 248 $msg = "建立數據表{$name}"; 249 if(false !== $db->execute($value)){ 250 show_msg($msg . '...成功'); 251 } else { 252 show_msg($msg . '...失敗!', 'error'); 253 session('error', true); 254 } 255 } else { 256 if(substr($value, 0, 8) == 'UPDATE `') { 257 $name = preg_replace("/^UPDATE `(\w+)` .*/s", "\\1", $value); 258 $msg = "更新數據表{$name}"; 259 } else if(substr($value, 0, 11) == 'ALTER TABLE'){ 260 $name = preg_replace("/^ALTER TABLE `(\w+)` .*/s", "\\1", $value); 261 $msg = "修改數據表{$name}"; 262 } else if(substr($value, 0, 11) == 'INSERT INTO'){ 263 $name = preg_replace("/^INSERT INTO `(\w+)` .*/s", "\\1", $value); 264 $msg = "寫入數據表{$name}"; 265 } 266 if(($db->execute($value)) !== false){ 267 show_msg($msg . '...成功'); 268 } else{ 269 show_msg($msg . '...失敗!', 'error'); 270 session('error', true); 271 } 272 } 273 } 274 } 275 276 /** 277 * 及時顯示提示信息 278 * @param string $msg 提示信息 279 */ 280 function show_msg($msg, $class = ''){ 281 echo "<script type=\"text/javascript\">showmsg(\"{$msg}\", \"{$class}\")</script>"; 282 flush(); 283 ob_flush(); 284 } 285 286 /** 287 * 生成系統AUTH_KEY 288 * @author 麥當苗兒 <zuojiazi@vip.qq.com> 289 */ 290 function build_auth_key(){ 291 $chars = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 292 $chars .= '`~!@#$%^&*()_+-=[]{};:"|,.<>/?'; 293 $chars = str_shuffle($chars); 294 return substr($chars, 0, 40); 295 } 296 297 /** 298 * 系統很是規MD5加密方法 299 * @param string $str 要加密的字符串 300 * @return string 301 */ 302 function user_md5($str, $key = ''){ 303 return '' === $str ? '' : md5(sha1($str) . $key); 304 }
3. 加密公共方法java
1 <?php 2 // +---------------------------------------------------------------------- 3 // | OneThink [ WE CAN DO IT JUST THINK IT ] 4 // +---------------------------------------------------------------------- 5 // | Copyright (c) 2013 http://www.onethink.cn All rights reserved. 6 // +---------------------------------------------------------------------- 7 // | Author: 麥當苗兒 <zuojiazi@vip.qq.com> <http://www.zjzit.cn> 8 // +---------------------------------------------------------------------- 9 10 /** 11 * 系統很是規MD5加密方法 12 * @param string $str 要加密的字符串 13 * @return string 14 */ 15 function think_ucenter_md5($str, $key = 'ThinkUCenter'){ 16 return '' === $str ? '' : md5(sha1($str) . $key); 17 } 18 19 /** 20 * 系統加密方法 21 * @param string $data 要加密的字符串 22 * @param string $key 加密密鑰 23 * @param int $expire 過時時間 (單位:秒) 24 * @return string 25 */ 26 function think_ucenter_encrypt($data, $key, $expire = 0) { 27 $key = md5($key); 28 $data = base64_encode($data); 29 $x = 0; 30 $len = strlen($data); 31 $l = strlen($key); 32 $char = ''; 33 for ($i = 0; $i < $len; $i++) { 34 if ($x == $l) $x=0; 35 $char .= substr($key, $x, 1); 36 $x++; 37 } 38 $str = sprintf('%010d', $expire ? $expire + time() : 0); 39 for ($i = 0; $i < $len; $i++) { 40 $str .= chr(ord(substr($data,$i,1)) + (ord(substr($char,$i,1)))%256); 41 } 42 return str_replace('=', '', base64_encode($str)); 43 } 44 45 /** 46 * 系統解密方法 47 * @param string $data 要解密的字符串 (必須是think_encrypt方法加密的字符串) 48 * @param string $key 加密密鑰 49 * @return string 50 */ 51 function think_ucenter_decrypt($data, $key){ 52 $key = md5($key); 53 $x = 0; 54 $data = base64_decode($data); 55 $expire = substr($data, 0, 10); 56 $data = substr($data, 10); 57 if($expire > 0 && $expire < time()) { 58 return ''; 59 } 60 $len = strlen($data); 61 $l = strlen($key); 62 $char = $str = ''; 63 for ($i = 0; $i < $len; $i++) { 64 if ($x == $l) $x = 0; 65 $char .= substr($key, $x, 1); 66 $x++; 67 } 68 for ($i = 0; $i < $len; $i++) { 69 if (ord(substr($data, $i, 1)) < ord(substr($char, $i, 1))) { 70 $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1))); 71 }else{ 72 $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1))); 73 } 74 } 75 return base64_decode($str); 76 }