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.
		
		
		
		
		
			
		
			
				
					
					
						
							1432 lines
						
					
					
						
							47 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							1432 lines
						
					
					
						
							47 KiB
						
					
					
				| <?php | |
| 
 | |
| class mBase extends publicBase { | |
|     public $mcflag = 'mymc'; | |
|     private $gmp = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | |
|     private $base62_string = "A0aB1bC2cD3dE4eF5fG6gH7hI8iJ9jKLMNOPQRSTUVWXYZklmnopqrstuvwxyz"; | |
| 
 | |
|     /** | |
|      * 连接MC | |
|      * 初始化MC/MCQ连接 | |
|      * @param string $mcflag 配置文件中MC标识 | |
|      */ | |
|     protected function initMC() { | |
|         $cnf = $this->parseMcCnf($this->mcflag); | |
| 
 | |
|         if(MEMCACHE_NAME=='memcached') { | |
|             $mc = new Memcached; | |
|             $mc->setOption(Memcached::OPT_COMPRESSION, false); // 设置默认关闭压缩 | |
|             $mc->setOption(Memcached::OPT_CONNECT_TIMEOUT, 500); // 设置连接超时 | |
|         } else { | |
|             $mc = new Memcache; | |
|         } | |
|         $res = $mc->addServer($cnf['host'], $cnf['port']); | |
|         if(!$res) return false; | |
|         return $mc; | |
|     } | |
| 
 | |
|     /** | |
|      * 根据缓存Key获取数据 | |
|      * @param string $key | |
|      */ | |
|     public function get($key) { | |
|         $obj = $this->initMC($this->mcflag); | |
|         if(!$obj) return false; | |
| 
 | |
|         return $obj->get($key); | |
|     } | |
| 
 | |
| 
 | |
|     /** | |
|      * 根据缓存Key存储数据 | |
|      * @param string $key | |
|      */ | |
|     public function set($key, $value, $expire=600) { | |
|         $obj = $this->initMC($this->mcflag); | |
|         if(!$obj) return false; | |
| 
 | |
|         if(MEMCACHE_NAME=='memcache') { | |
|             return $obj->set($key, $value, MEMCACHE_COMPRESSED, $expire); | |
|         } else { | |
|             return $obj->set($key, $value, $expire); | |
|         } | |
|     } | |
| 
 | |
| 
 | |
|     /** | |
|      * 根据缓存Key删除存储 | |
|      * @param string $key | |
|      */ | |
|     public function delete($key) { | |
|         $obj = $this->initMC($this->mcflag); | |
|         if(!$obj) return false; | |
| 
 | |
|         return $obj->delete($key); | |
|     } | |
| 
 | |
| 
 | |
|     /** | |
|      * 缓存Key计数+1 | |
|      * @param string $key | |
|      * @param int $offset 累加值 | |
|      */ | |
|     public function increment($key, $offset=1) { | |
|         $obj = $this->initMC($this->mcflag); | |
|         if(!$obj) return false; | |
| 
 | |
|         return $obj->increment($key, $offset); | |
|     } | |
| 
 | |
| 
 | |
|     /** | |
|      * 缓存Key计数-1 | |
|      * @param string $key | |
|      * @param int $offset 减值 | |
|      */ | |
|     public function decrement($key, $offset=1) { | |
|         $obj = $this->initMC($this->mcflag); | |
|         if(!$obj) return false; | |
| 
 | |
|         return $obj->decrement($key, $offset); | |
|     } | |
| 
 | |
| 
 | |
|     /** | |
|      * 解析MC配置信息 | |
|      * 获得MC的相关连接信息 | |
|      * @param sting $mcflag MC标识 | |
|      */ | |
|     private function parseMcCnf($mcflag='') { | |
|         if(!empty($mcflag)) $this->mcflag = $mcflag; | |
|         $configs = parse_ini_file(_Storage_CNF_PATH, true); | |
|         $config = $configs[strtolower($this->mcflag)]; | |
| 
 | |
|         $cnf['host'] = trim($config['host']); | |
|         $cnf['port'] = trim($config['port']); | |
|         $cnf['db'] = trim($config['db']); | |
|         return $cnf; | |
|     } | |
| 
 | |
|     /** | |
|      * 发送邮件 | |
|      * 通过PHPMAILER发送邮件 | |
|      * @param array $emails 邮件组 | |
|      * @param string $title 邮件标题 | |
|      * @param string $content 邮件内容 | |
|      */ | |
|     public static function sendMail($emails, $title, $content,$attr='') { | |
|         include_once SERVER_ROOT . '/library/mail/class.phpmailer.php'; | |
| 
 | |
|         $mail_name = array_rand($GLOBALS['notice_mail_list']); | |
| 
 | |
|         $mail = new PHPMailer(); | |
|         $mail->IsSMTP(); | |
|         $mail->Host = $GLOBALS['notice_mail_list'][$mail_name]['host']; | |
|         $mail->Port = 465;               // TCP 端口 | |
|         $mail->SMTPSecure = 'ssl';      // 启用 TLS 加密 | |
|         //$mail->SMTPDebug        = 2;  // 是否开启调试 | |
|         $mail->Username = $mail_name; | |
|         $mail->Password = $GLOBALS['notice_mail_list'][$mail_name]['password']; | |
|         $mail->From = $mail_name; | |
|         $mail->CharSet = "utf-8"; | |
|         $mail->IsHTML(true); | |
|         $mail->SMTPAuth = true; | |
|         $mail->ClearAddresses(); | |
|         $mail->SetLanguage('en', SERVER_ROOT . '/library/mail/language/'); | |
| 
 | |
|         if($attr){ | |
|             $mail->addAttachment($attr); | |
|         } | |
| 
 | |
|         $mail->FromName = "医者仁心·医案小助手"; | |
|         foreach($emails as $email) { | |
|         	$mail->AddAddress($email); | |
|         } | |
|         $mail->Subject = $title; | |
|         $mail->Body = $content; | |
| 
 | |
|         return $mail->Send(); | |
|     } | |
| 
 | |
|     /** | |
|      * sendCloud发邮件 | |
|      * http://sendcloud.sohu.com | |
|      * kuailebangshou  Hellow0rld123 | |
|      */ | |
|     public function sendMailBySohu($emails, $title, $content, $attachments=array()) { | |
|         return $this->sendMail($emails, $title, $content); | |
| 
 | |
|         $mailstr = implode(';', $emails); | |
|         $maildata = array ( | |
|             'api_user' => SENDCLOUD_USER, | |
|             'api_key' => SENDCLOUD_PASS, | |
|             'from' => '58996091@qq.com', | |
|             'fromname' => '-快乐论文-', | |
|             'to' => $mailstr, | |
|             'subject' => $title, | |
|             'html' => $content | |
|         ); | |
|         $attachs = array(); | |
|         $i = 0; | |
|         if(!empty($attachments)) { | |
|             foreach ($attachments as $v) { | |
|                 $i++; | |
|                 $filename = basename($v); | |
|                 $attachs['file'.$i] = '@'.$v.';filename='.$filename; | |
|             } | |
|         } | |
| 
 | |
|         $ch = curl_init(); | |
|         curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); | |
|         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
|         curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); | |
|         curl_setopt($ch, CURLOPT_URL, 'https://sendcloud.sohu.com/webapi/mail.send.json'); | |
|         //不同于登录SendCloud站点的帐号,您需要登录后台创建发信子帐号,使用子帐号和密码才可以进行邮件的发送。 | |
|         curl_setopt($ch, CURLOPT_POSTFIELDS, array_merge($maildata, $attachs)); | |
|         $result = curl_exec($ch); | |
|         if($result === false) { //请求失败 | |
|             //echo 'last error : ' . curl_error($ch); | |
|             return false; | |
|         } | |
|         curl_close($ch); | |
|         return $result; | |
|     } | |
| 
 | |
| 
 | |
|     protected function initSnoopy($host='') { | |
|         include_once SERVER_ROOT.'/library/snoopy/Snoopy.class.php'; | |
| 
 | |
|         $snoopy = new Snoopy; | |
|         $snoopy->host = $host; | |
|         $snoopy->agent = "Mozilla/5.0 (Windows NT 6.1; rv:18.0) Gecko/20100101 Firefox/18.0"; | |
|         $snoopy->rawheaders['Connection'] = "keep-alive"; | |
|         $snoopy->accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; | |
|         $snoopy->maxredirs = 5; | |
|         $snoopy->rawheaders["Pragma"] = "no-cache"; | |
|         $snoopy->rawheaders["X_FORWARDED_FOR"] = "210.136.193.130"; | |
|         $snoopy->rawheaders['Accept-Language'] = "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3"; | |
| 
 | |
|         return $snoopy; | |
|     } | |
| 
 | |
| 
 | |
|     /** | |
|      * 获取错误返回信息 | |
|      */ | |
|     public function getError() { | |
|         if(empty($this->error)) return '系统繁忙!'; | |
| 
 | |
|         return $this->error; | |
|     } | |
| 
 | |
|     /** | |
|      * 设置错误信息 | |
|      * @param unknown_type $errorInfo | |
|      */ | |
|     protected function setError($errorInfo) { | |
|         return $this->error = $errorInfo; | |
|     } | |
| 
 | |
|     /** | |
|      * CUrl封装的get方式请求API的方法 | |
|      * @param string $url URL | |
|      * @param int $timeout 超时时间 | |
|      */ | |
|     public function getCUrl($url, $timeout=3) { | |
|         $ch = curl_init(); | |
|         curl_setopt($ch, CURLOPT_URL, $url); | |
|         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
|         curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | |
| 
 | |
|         //分析是否开启SSL加密 | |
|         $ssl = substr($url, 0, 8) == 'https://' ? true : false; | |
|         if ($ssl) { | |
|             curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查 | |
|             curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 从证书中检查SSL加密算法是否存在 | |
|         } | |
| 
 | |
|         $res = curl_exec($ch); | |
|         if(curl_error($ch)=='') { | |
|             curl_close($ch); | |
|             return $res; | |
|         } | |
|         curl_close($ch); | |
|         return false; | |
|     } | |
| 
 | |
|     /** | |
|      * CUrl封装的post方式请求API的方法 | |
|      * @param string $url | |
|      * @param array $data post数据 | |
|      * @param int $timeout 超时时间 | |
|      */ | |
|     public function postCUrl($url, $data, $timeout=3, $is_xml_data = false, $is_json_data = false) { | |
|         $ch = curl_init(); | |
| 
 | |
|         $urlinfo = parse_url($url); | |
|         $domain = $urlinfo['host']; | |
|         $headers = array("Host: $domain"); | |
|         curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | |
| 
 | |
|         //分析是否开启SSL加密 | |
|         $ssl = substr($url, 0, 8) == 'https://' ? true : false; | |
|         if ($ssl) { | |
|             curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查 | |
|             curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 从证书中检查SSL加密算法是否存在 | |
|         } | |
| 
 | |
|         curl_setopt($ch, CURLOPT_URL, $url); | |
|         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
|         curl_setopt($ch, CURLOPT_POST, true); | |
|         curl_setopt($ch, CURLOPT_POSTFIELDS, $data); | |
|         curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); | |
|         curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | |
|         if($is_xml_data) curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/xml')); | |
|         if($is_json_data) curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); | |
| 
 | |
|         $res = curl_exec($ch); | |
|         if(curl_error($ch)=='') { | |
|             curl_close($ch); | |
|             return $res; | |
|         } | |
|         curl_close($ch); | |
|         return false; | |
|     } | |
| 
 | |
|     public function postCurlContainFile($url, $data, $timeout=3, $file_param_key_name='') { | |
|         $ch = curl_init(); | |
| 
 | |
|         $urlinfo = parse_url($url); | |
|         $domain = $urlinfo['host']; | |
|         $headers = array("Host: $domain"); | |
|         curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | |
| 
 | |
|         //分析是否开启SSL加密 | |
|         $ssl = substr($url, 0, 8) == 'https://' ? true : false; | |
|         if ($ssl) { | |
|             curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查 | |
|             curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 从证书中检查SSL加密算法是否存在 | |
|         } | |
| 
 | |
|         curl_setopt($ch, CURLOPT_URL, $url); | |
|         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
|         curl_setopt($ch, CURLOPT_POST, true); | |
| 
 | |
|         if($file_param_key_name) $data[$file_param_key_name] = new CURLFile($data[$file_param_key_name]); | |
| 
 | |
|         curl_setopt($ch, CURLOPT_POSTFIELDS, $data); | |
|         curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); | |
|         curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | |
| 
 | |
|         $res = curl_exec($ch); | |
|         if(curl_error($ch)=='') { | |
|             curl_close($ch); | |
|             return $res; | |
|         } else { | |
|             $this->curl_error = curl_error($ch); | |
|         } | |
|         curl_close($ch); | |
|         return false; | |
|     } | |
| 
 | |
|     /** | |
|      * SSLCert CURL | |
|      * @param unknown $url | |
|      * @param unknown $data | |
|      * @param unknown $cert['sslcert'] = 'cert.pem';$cert['sslkey'] = 'key.pem'; | |
|      * @param number $timeout | |
|      * @return mixed|boolean | |
|      */ | |
|     public function postCUrlBySSLCert($url, $data, $cert, $timeout=3) { | |
|         $ch = curl_init(); | |
| 
 | |
|         $urlinfo = parse_url($url); | |
|         $domain = $urlinfo['host']; | |
|         $headers = array("Host: $domain"); | |
|         curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | |
| 
 | |
|         // SSL设置 | |
|         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查 | |
|         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在 | |
|  | |
|         curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $cert['password']); | |
|         curl_setopt($ch,CURLOPT_SSLCERT, $cert['sslcert']); | |
|         curl_setopt($ch,CURLOPT_KEYPASSWD, $cert['password']); | |
|         curl_setopt($ch,CURLOPT_SSLKEY, $cert['sslkey']); | |
|         curl_setopt($ch,CURLOPT_CAPATH, dirname($cert['rootca']).'/'); | |
|         curl_setopt($ch,CURLOPT_CAINFO, basename($cert['rootca'])); | |
| 
 | |
|         curl_setopt($ch, CURLOPT_URL, $url); | |
|         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
|         curl_setopt($ch, CURLOPT_POST, true); | |
|         curl_setopt($ch, CURLOPT_POSTFIELDS, $data); | |
|         curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); | |
|         curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | |
| 
 | |
|         $res = curl_exec($ch); | |
|         if(curl_error($ch)=='') { | |
|             curl_close($ch); | |
|             return $res; | |
|         } | |
|         curl_close($ch); | |
|         return false; | |
|     } | |
| 
 | |
| 
 | |
| 
 | |
|     /** | |
|      * 递归删除文件夹 | |
|      * @param  string $dir 文件夹路径 | |
|      * @param  array  $undel 该文件不删除 | |
|      */ | |
|     public function rm_muti_dir($dir, $undel=array()) { | |
|         if(!is_dir($dir)) return true; | |
|         $d = dir($dir); | |
|         while (false !== ($child = $d->read())) { | |
|             if($child == '.' || $child == '..') continue; | |
|             if(is_dir($dir.'/'.$child)) { | |
|                 $this->rm_muti_dir($dir.'/'.$child); | |
|             } else { | |
|                 if (empty($undel)) { | |
|                     unlink($dir.'/'.$child); | |
|                 } else { | |
|                     if(!in_array($dir.'/'.$child, $undel)) unlink($dir.'/'.$child); | |
|                 } | |
|             } | |
|         } | |
|         $d->close(); | |
|         rmdir($dir); | |
|     } | |
| 
 | |
|     /** | |
|      * 递归获取目录下的文件 | |
|      * @param unknown $dir | |
|      * @return string | |
|      */ | |
|     public function scan_dir($dir) { | |
|         if ($handle = opendir($dir)) { | |
|             while (false !== ($file = readdir($handle))) { | |
|                 if($file=='..' || $file=='.') continue; | |
| 
 | |
|                 if(is_file($dir.'/'.$file)) { | |
|                     $file_list[] = $dir.'/'.$file; | |
|                     continue; | |
|                 } | |
| 
 | |
|                 $file_list[$file] = $this->scan_dir($dir.'/'.$file); | |
|                 foreach($file_list[$file] as $infile) { | |
|                     $file_list[] = $infile; | |
|                 } | |
|                 unset($file_list[$file]); | |
|             } | |
|             closedir($handle); | |
| 
 | |
|             return $file_list; | |
|         } | |
|     } | |
| 
 | |
|     public function genPasswd($length = 8) { | |
|         // 密码字符集,可任意添加你需要的字符 | |
|         $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; | |
| 
 | |
|         $password = ''; | |
|         for ( $i = 0; $i < $length; $i++ ) { | |
|             $password .= $chars[ mt_rand(0, strlen($chars) - 1) ]; | |
|         } | |
| 
 | |
|         return $password; | |
|     } | |
| 
 | |
|     function array2xml($array) { | |
|         $xml = "<xml>"; | |
|         foreach($array as $k => $v) { | |
|             $xml .= '<'.$k.'>'.$v.'</'.$k.'>'; | |
|         } | |
|         $xml .= "</xml>"; | |
|         return $xml; | |
|     } | |
| 
 | |
|     /** | |
|      * URL编码(UTF-8) | |
|      */ | |
|     public function urlCoding($str) { | |
|         $res = urlencode($str); | |
|         $res = preg_replace('/\+/', '%20', $res); | |
|         $res = preg_replace('/\*/', '%2A', $res); | |
|         $res = preg_replace('/%7E/', '~', $res); | |
|         return $res; | |
|     } | |
| 
 | |
|     /** | |
|      * 检测手机号是否有效 | |
|      */ | |
|     public function isValidPhone($phone) { | |
|         if(!preg_match("/^1[3456789]\d{9}$/", $phone)) { | |
|             return false; | |
|         } | |
|         return true; | |
|     } | |
| 
 | |
|     /** | |
|      * 获取用户IP | |
|      */ | |
|     public function getClientIp() { | |
|         if(!empty($_SERVER["HTTP_CLIENT_IP"]))  { | |
|             $ip = $_SERVER["HTTP_CLIENT_IP"]; | |
|         } elseif(!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))  { | |
|             $ip = $_SERVER["HTTP_X_FORWARDED_FOR"]; | |
|         } elseif(!empty($_SERVER["REMOTE_ADDR"])) { | |
|             $ip = $_SERVER["REMOTE_ADDR"]; | |
|         } | |
|         if(strpos($ip, ',')!==false) { | |
|             $iparr = explode(',', $ip); | |
|             return trim($iparr[0]); | |
|         } | |
|         return $ip; | |
|     } | |
| 
 | |
|     /* | |
|      *function:检测字符串是否由纯英文,纯中文,中英文混合组成 | |
|      *param string | |
|      *return 1:纯英文;2:纯中文;3:中英文混合 | |
|      */ | |
|     function checkStr($str=''){ | |
|         if(trim($str)==''){ | |
|             return ''; | |
|         } | |
|         $m=mb_strlen($str,'utf-8'); | |
| 
 | |
|         $s=strlen($str); | |
| 
 | |
|         if($s==$m){ | |
|             return 1; | |
|         } | |
|         if($s%$m==0&&$s%3==0){ | |
|             return 2; | |
|         } | |
|         return 3; | |
|     } | |
| 
 | |
|     public function toCopycheck($sale_id, $inf, $ratio) { | |
|         return false; | |
| 
 | |
|         $serobj = new mService(); | |
|         $dirs = array_flip($GLOBALS['dirFlag']); | |
|         $paper_path = sprintf(PAPER_SAVE_PATH, $dirs[$inf['type']], substr($inf['add_date'],0,10), $sale_id.$GLOBALS['file_type'][FILE_TYPE_TXT]); | |
|         $copycheckdata = array( | |
|             'title'     => $inf['title'], | |
|             'author'    => $inf['author'], | |
|             'content'   => file_get_contents($paper_path), | |
|             'ratio'     => $ratio, | |
|             'url'       => $serobj->getServiceReport($inf['uid'], $inf['type']).'/tid/'.$inf['tids'][0].'/sid/'.$inf['sale_id'].'/lastday/15', | |
|             'type'      => $inf['type'], | |
|             'unique_id' => $sale_id, | |
|             'version'   => $inf['version'] ? $inf['version'] : 3, | |
|         ); | |
|         $this->postCUrl('http://api.copycheck.yunpaper.com/doc/detect', $copycheckdata); | |
|     } | |
| 
 | |
|     /** | |
|      * 判断是否是闰年 | |
|      * @param unknown $year | |
|      */ | |
|     public function isLeapYear($year) { | |
|         if ($year%4==0&&($year%100!=0 || $year%400==0)) return true; | |
|         return false; | |
|     } | |
| 
 | |
|     public function downloadFile($file_path, $file_name) { | |
|         $file = realpath($file_path); | |
|         Header( "Content-type:  application/octet-stream "); | |
|         Header( "Accept-Ranges:  bytes "); | |
|         Header( "Accept-Length: " .filesize($file)); | |
|         Header( "Content-Disposition:  attachment;  filename= {$file_name}"); | |
|         readfile($file); | |
|         exit(); | |
|     } | |
| 
 | |
|     public function requestUrlByPost($url, $data, $cookie_jar='', $ip='', $timeout=100) { | |
|         $ch = curl_init(); | |
|         $urlinfo = parse_url($url); | |
|         $domain = $urlinfo['host']; | |
|         $headers = array("Host: $domain"); | |
|         curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | |
| 
 | |
|         if(!empty($ip)) { | |
|             $url = str_replace($domain, $ip, $url); | |
|         } | |
|         curl_setopt($ch, CURLOPT_URL, $url); | |
|         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
|         curl_setopt($ch, CURLOPT_REFERER, $url); | |
|         curl_setopt($ch, CURLOPT_HEADER, false); | |
|         curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0 FirePHP/0.7.0'); | |
|         curl_setopt($ch, CURLOPT_POST, true); | |
|         // 若给定url自动跳转到新的url,有了下面参数可自动获取新url内容:302跳转(paperyy下载报告会用到) | |
|         curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); | |
| 
 | |
|         if(!empty($data)) { | |
|             foreach($data as $k => $v) { | |
|                 if (is_array($v) || is_object($v)) continue; | |
| 
 | |
|                 $poststr .= "&$k=".urlencode($v); | |
|             } | |
|             unset($data); | |
|             curl_setopt($ch, CURLOPT_POSTFIELDS, substr($poststr, 1)); | |
|         } | |
| 
 | |
|         if(!empty($cookie_jar)) { | |
|             curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_jar); | |
|         } | |
|         curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); | |
|         curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | |
|         $result = curl_exec($ch); | |
|         curl_close($ch); | |
| 
 | |
|         if ($result !== false) { | |
|             return $result; | |
|         } else { | |
|             return false; | |
|         } | |
|     } | |
| 
 | |
|     public function requestUrlByGet($url, $data, $cookie_jar='', $ip='', $timeout=100) { | |
|         $ch = curl_init(); | |
|         $urlinfo = parse_url($url); | |
|         $domain = $urlinfo['host']; | |
|         $headers = array("Host: $domain"); | |
|         curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | |
| 
 | |
|         if(!empty($ip)) { | |
|             $url = str_replace($domain, $ip, $url); | |
|         } | |
| 
 | |
|         if(!empty($data)) { | |
|             foreach($data as $k => $v) { | |
|                 $getstr .= "&$k=".urlencode($v); | |
|             } | |
|             unset($data); | |
|             $url = $url.'?'.$getstr; | |
|         } | |
| 
 | |
|         curl_setopt($ch, CURLOPT_URL, $url); | |
|         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
|         curl_setopt($ch, CURLOPT_REFERER, $url); | |
|         curl_setopt($ch, CURLOPT_HEADER, false); | |
|         curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0 FirePHP/0.7.0'); | |
|         curl_setopt($ch, CURLOPT_POST, false); | |
| 
 | |
|         if(!empty($cookie_jar)) { | |
|             curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_jar); | |
|         } | |
|         curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); | |
|         curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | |
| 
 | |
|         // 若给定url自动跳转到新的url,有了下面参数可自动获取新url内容:302跳转(paperpass下载报告会用到) | |
|         curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); | |
| 
 | |
|         $result = curl_exec($ch); | |
|         curl_close($ch); | |
| 
 | |
|         if ($result !== false) { | |
|             return $result; | |
|         } else { | |
|             return false; | |
|         } | |
|     } | |
| 
 | |
|     /** | |
|      * AES加密算法 | |
|      * @param unknown $msg        需要加密的数据字符串 | |
|      * @param string $secret_key  加密密钥 | |
|      * @return string | |
|      */ | |
|     public function encryptData($msg, $secret_key=JD_DATA_CRYPTO_KEY) { | |
|         foreach ($GLOBALS["encrypt_methods"] as $met) { | |
|             $msg = openssl_encrypt($msg, $met, $secret_key); | |
|         } | |
|         return $msg; | |
|     } | |
| 
 | |
|     /** | |
|      * AES解密算法 | |
|      * @param unknown $msg         需要解密的数据字符串 | |
|      * @param string $secret_key   加密时的秘钥 | |
|      * @return string | |
|      */ | |
|     public function decryptData($msg, $secret_key=JD_DATA_CRYPTO_KEY) { | |
|         foreach(array_reverse($GLOBALS["encrypt_methods"]) as $met) { | |
|             $msg = openssl_decrypt($msg, $met, $secret_key); | |
|         } | |
|         return $msg; | |
|     } | |
| 
 | |
|     /** | |
|      * 上传文件,判断文件MIME类型是否符合 | |
|      * @param unknown $upfile     上传的文件 | |
|      * @param unknown $save_path  保存的路径 | |
|      * @param array $mime_type_limit   mime限制 | |
|      * @return boolean | |
|      */ | |
|     public function uploadFile($upfile, $save_path, $mime_type_limit=array()) { | |
| 
 | |
|         if($upfile['error'] == 4) { | |
|             $this->setError("请先上传文件"); | |
|             return false; | |
|         } | |
| 
 | |
|         if($upfile['error'] == 3) { | |
|             $this->setError("上传文件不完整,请重新上传"); | |
|             return false; | |
|         } | |
| 
 | |
|         if($upfile['error'] == 1 || $upfile['error'] == 2) { | |
|             $this->setError("上传文件过大"); | |
|             return false; | |
|         } | |
| 
 | |
|         if($upfile['size'] < 0) { | |
|             $this->setError("上传文件大小错误"); | |
|             return false; | |
|         } | |
| 
 | |
|         if(!in_array($upfile['type'], $mime_type_limit)) { | |
|             $this->setError("上传文件格式不正确".$upfile['type']); | |
|             return false; | |
|         } | |
| 
 | |
|         $log_dir = dirname($save_path); | |
|         if(!is_dir($log_dir)) { | |
|             mkdir($log_dir, 0755, true); | |
|             chown($log_dir, 'nobody'); | |
|             chgrp($log_dir, 'nobody'); | |
|         } | |
| 
 | |
|         $res = move_uploaded_file($upfile['tmp_name'], $save_path); | |
|         if(!$res) { | |
|             $this->setError("上传文件失败"); | |
|             return false; | |
|         } | |
|         return $res; | |
|     } | |
| 
 | |
|     /** | |
|      * 上传文件,判断文件后缀是否符合 | |
|      * @param unknown $upfile | |
|      * @param unknown $save_path | |
|      * @param array $file_ext_limit  array('zip', 'rar', 'jpg', 'jpeg', 'png'); | |
|      * @return boolean | |
|      */ | |
|     public function uploadFile2($upfile, $save_path, $file_ext_limit=array()) { | |
|         if($upfile['error'] == UPLOAD_ERR_NO_FILE) { | |
|             $this->setError("请先上传文件"); | |
|             return false; | |
|         } | |
| 
 | |
|         if($upfile['error'] == UPLOAD_ERR_PARTIAL) { | |
|             $this->setError("上传文件不完整,请重新上传"); | |
|             return false; | |
|         } | |
| 
 | |
|         if($upfile['error'] == UPLOAD_ERR_INI_SIZE || $upfile['error'] == UPLOAD_ERR_FORM_SIZE) { | |
|             $this->setError("上传文件过大"); | |
|             return false; | |
|         } | |
| 
 | |
|         if($upfile['error'] == UPLOAD_ERR_NO_TMP_DIR) { | |
|             $this->setError("文件写入到临时文件夹出错"); | |
|             return false; | |
|         } | |
| 
 | |
|         if($upfile['error'] == UPLOAD_ERR_CANT_WRITE) { | |
|             $this->setError("文件写入失败"); | |
|             return false; | |
|         } | |
| 
 | |
|         if($upfile['error'] == UPLOAD_ERR_EXTENSION) { | |
|             $this->setError("文件写入失败"); | |
|             return false; | |
|         } | |
| 
 | |
|         if ($upfile['error'] != UPLOAD_ERR_OK) { | |
|             $this->setError("上传文件失败".$upfile['error']); | |
|             return false; | |
|         } | |
| 
 | |
|         if($upfile['size'] <= 0) { | |
|             $this->setError("上传文件大小错误"); | |
|             return false; | |
|         } | |
| 
 | |
|         if(is_array($file_ext_limit) && count($file_ext_limit) > 0) { | |
|             setlocale(LC_ALL, 'zh_CN.UTF-8'); | |
|             $ext = pathinfo($upfile['name'], PATHINFO_EXTENSION); | |
|             if (!in_array($ext, $file_ext_limit)) { | |
|                 $this->setError("上传文件格式不正确"); | |
|                 return false; | |
|             } | |
|         } | |
| 
 | |
|         $log_dir = dirname($save_path); | |
|         if(!is_dir($log_dir)) { | |
|             mkdir($log_dir, 0755, true); | |
|             chown($log_dir, 'nobody'); | |
|             chgrp($log_dir, 'nobody'); | |
|         } | |
| 
 | |
|         $res = move_uploaded_file($upfile['tmp_name'], $save_path); | |
|         if(!$res) { | |
|             $this->setError("上传文件失败"); | |
|             return false; | |
|         } | |
|         return $res; | |
|     } | |
| 
 | |
|     /** | |
|      * 写日志  /datacenter/logs/$catalog_name/2018-10-30/$logname | |
|      * @param unknown $catalog_name  目录名称 | |
|      * @param unknown $logname       日志名称 | |
|      * @param unknown $log           需要记录的日志 | |
|      * @return boolean | |
|      */ | |
|     public function writeLog($catalog_name, $logname, $log) { | |
|         $log_path = LOG_PATH_BASE."/".$catalog_name."/".date('Y-m-d')."/".$logname; | |
|         $log_dir = dirname($log_path); | |
|         if(!is_dir($log_dir)) { | |
|             mkdir($log_dir, 0775, true); | |
|             chown($log_dir, 'nobody'); | |
|             chgrp($log_dir, 'nobody'); | |
|         } | |
| 
 | |
|         error_log(date("Y-m-d H:i:s")."-|".$log."\n", 3, $log_path); | |
| 
 | |
|         chown($log_path, 'nobody'); | |
|         chgrp($log_path, 'nobody'); | |
| 
 | |
|         return true; | |
|     } | |
| 
 | |
| 
 | |
|     /** | |
|      * 初始化Redis | |
|      * @param unknown $db           redis使用的数据库(正常database.ini中有,当多个项目指向同一库时,传此参数兼容) | |
|      * @return boolean|RedisOperate | |
|      */ | |
|     public function initRedis($db=null) { | |
|         $cnf = $this->parseMcCnf('redis'); | |
| 
 | |
|         $obj = new mRedis(); | |
|         $rdobj = $obj->getInstance($cnf); | |
| 
 | |
|         // 数据库分配 | |
|         $redis_db = $cnf['db']; | |
|         if($db !== null) $redis_db = $db; | |
| 
 | |
|         $res = $rdobj->select($redis_db); | |
|         if(!$res) return false; | |
| 
 | |
|         return $rdobj; | |
|     } | |
| 
 | |
|     public function setRedisCache($key, $expire_time, $value) { | |
|         $rdobj = $this->initRedis(); | |
| 
 | |
|         $res = $rdobj->setex($key, $expire_time, serialize($value)); | |
|         if(!$res) return false; | |
|         return true; | |
|     } | |
| 
 | |
|     public function getRedisCache($key) { | |
|         $rdobj = $this->initRedis(); | |
|         $res = unserialize($rdobj->get($key)); | |
|         if(!$res) return false; | |
|         return $res; | |
|     } | |
| 
 | |
|     public function delRedisCache($key) { | |
|         $rdobj = $this->initRedis(); | |
|         $res = $rdobj->del($key); | |
|         if(!$res) return false; | |
|         return true; | |
|     } | |
| 
 | |
|     /** | |
|      * | |
|      * @param unknown $width | |
|      * @param unknown $height | |
|      * @param string  $content | |
|      * @param string  $font_name | |
|      */ | |
|     public function verifyCode($width, $height, $content=VERIFY_CODE_STRING_CODE, $font_name="Context_Black_SSi_Black_Italic.ttf") { | |
|         /** | |
|          * 字母+数字的验证码生成 | |
|          */ | |
|         //1.创建黑色画布 | |
|         $image = imagecreatetruecolor($width, $height); | |
| 
 | |
|         //2.为画布定义(背景)颜色 | |
|         $bgcolor = imagecolorallocate($image, 255, 255, 255); | |
| 
 | |
|         //3.填充颜色 | |
|         imagefill($image, 0, 0, $bgcolor); | |
| 
 | |
|         //4.1 创建一个变量存储产生的验证码数据,便于用户提交核对 | |
|         $verify_code = ""; | |
|         $fontcolor_arr = [ | |
|             0 => [77,72,249], | |
|             1 => [149, 19, 200], | |
|             2 => [152, 95, 131], | |
|             3 => [146, 8, 108], | |
|             4 => [163, 80, 249], | |
|             5 => [151, 252, 127], | |
|         ]; | |
| 
 | |
|         // 字体颜色 | |
|  | |
| 
 | |
|         for ($i=0;$i<4;$i++) { | |
|             $fontcolor_rand = $fontcolor_arr[rand(0, count($fontcolor_arr)-1)]; | |
|             $fontcolor = imagecolorallocate($image, $fontcolor_rand[0], $fontcolor_rand[1], $fontcolor_rand[2]); | |
|             $y = mt_rand(40, 45); | |
|             // 字体大小 | |
|             $fontsize = 22; | |
|             $rand_str_len = strlen($content)-1; | |
|             // 设置字体内容 | |
|             $fontcontent = substr($content, mt_rand(0, $rand_str_len), 1); | |
|             $verify_code .= $fontcontent; | |
|             //设置字体样式 | |
|             $font_style = sprintf(FONT_STYLE_FILE_PATH, $font_name); | |
|             //显示的角度 | |
|             $rand_angle = rand(-15, 15); | |
|             // 显示的坐标 | |
|             $x = (($i)*$width/4)+5; | |
|             if($i==0) $x += 5; | |
|             // 填充内容到画布中 | |
|             imagettftext($image, $fontsize, $rand_angle, $x, $y, $fontcolor, $font_style, $fontcontent); | |
|         } | |
|         session_start(); | |
|         $_SESSION["verify_code"] = strtolower($verify_code); | |
|         session_write_close(); | |
| 
 | |
|         //5.向浏览器输出图片头信息 | |
|         header('content-type:image/png'); | |
| 
 | |
|         //6.输出图片到浏览器 | |
|         imagepng($image); | |
| 
 | |
|         //7.销毁图片 | |
|         imagedestroy($image); | |
|     } | |
| 
 | |
|     public function requestWeipuUrlByPost($url, $data, $cookie_jar='', $ip='', $timeout=100) { | |
|         $ch = curl_init(); | |
|         $urlinfo = parse_url($url); | |
|         $domain = $urlinfo['host']; | |
|         $headers = array("Host: $domain"); | |
|         curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | |
| 
 | |
|         if(!empty($ip)) { | |
|             $url = str_replace($domain, $ip, $url); | |
|         } | |
|         curl_setopt($ch, CURLOPT_URL, $url); | |
|         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
|         curl_setopt($ch, CURLOPT_REFERER, $url); | |
|         curl_setopt($ch, CURLOPT_HEADER, false); | |
|         curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0 FirePHP/0.7.0'); | |
|         curl_setopt($ch, CURLOPT_POST, true); | |
|         curl_setopt($ch, CURLOPT_POSTFIELDS, $data); | |
|         if(!empty($cookie_jar)) { | |
|             curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_jar); | |
|         } | |
|         curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); | |
|         curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | |
|         $result = curl_exec($ch); | |
|         curl_close($ch); | |
| 
 | |
|         if ($result !== false) { | |
|             return $result; | |
|         } else { | |
|             return false; | |
|         } | |
|     } | |
| 
 | |
|     public function getCurlRequest($url, $data, $headers=array(), $timeout=15, $cookie_path='', $port='') { | |
|         $ch = curl_init(); | |
|         foreach($data as $k => $v) { | |
|             $getstr .= "&$k=".urlencode($v); | |
|         } | |
|         unset($data); | |
| 
 | |
|         curl_setopt($ch, CURLOPT_URL, $url.'?'.$getstr); | |
|         curl_setopt($ch, CURLOPT_POST, false); | |
| 
 | |
| 
 | |
|         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
|         curl_setopt($ch, CURLOPT_REFERER, $url); | |
| 
 | |
|         curl_setopt($ch, CURLOPT_HEADER, false); | |
|         if(!empty($headers)) curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | |
| 
 | |
|         if(!empty($cookie_path)) { | |
|             curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_path); | |
|             curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_path); | |
|         } | |
| 
 | |
|         curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); | |
|         curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | |
| 
 | |
|         if(!empty($port)) { | |
|             curl_setopt($ch,CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);//使用了SOCKS5代理 | |
|             curl_setopt($ch, CURLOPT_PROXY, "127.0.0.1:".$port); | |
|         } | |
| 
 | |
|         $result = curl_exec($ch); | |
|         curl_close($ch); | |
| 
 | |
|         if ($result !== false) return $result; | |
| 
 | |
|         return false; | |
|     } | |
| 
 | |
|     public function isHttps($server_port='80') { | |
|         if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') { | |
|             return true; | |
|         } elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { | |
|             return true; | |
|         } elseif ( ! empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off') { | |
|             return true; | |
|         } | |
|         if ($server_port == '443') return true; | |
|         return false; | |
|     } | |
| 
 | |
|     /** | |
|      * 判断vpn是否启动(shadowsocks) | |
|      */ | |
|     private function getProxyProcess($cmd) { | |
|         $is_exist = shell_exec("ps aux|grep '".$cmd."' |grep -v grep"); | |
|         if($is_exist) return true; | |
|         return false; | |
|     } | |
| 
 | |
|     /** | |
|      * 启动vpn(shadowsocks) | |
|      * @param unknown $server_ip        服务器ip | |
|      * @param unknown $server_port      服务器端口 | |
|      * @param unknown $proxy_port       代理端口 | |
|      * @param unknown $server_passwd    服务密码 | |
|      * @return boolean | |
|      */ | |
|     public function startProxyProcess($server_ip, $server_port, $proxy_port, $server_passwd) { | |
|         if(empty($server_ip)) { | |
|             $this->setError('服务器地址为空'); | |
|             return false; | |
|         } | |
| 
 | |
|         if(empty($server_port)) { | |
|             $this->setError('服务器端口为空'); | |
|             return false; | |
|         } | |
| 
 | |
|         if(empty($proxy_port)) { | |
|             $this->setError('代理端口为空'); | |
|             return false; | |
|         } | |
| 
 | |
|         if(empty($server_passwd)) { | |
|             $this->setError('服务密码为空'); | |
|             return false; | |
|         } | |
| 
 | |
|         $cmd = "sslocal -s ".$server_ip." -p ".$server_port." -l ".$proxy_port." -k ".$server_passwd." -m aes-256-cfb"; | |
|         $is_exist = $this->getProxyProcess($cmd); | |
|         if($is_exist) return true; | |
| 
 | |
|         // 启动vpn | |
|         $res = shell_exec("nohup /usr/bin/python2 /bin/".$cmd." >sslocal.log 2>&1 &"); | |
| 
 | |
|         // 判断是否启动成功 | |
|         $is_start = $this->getProxyProcess($cmd); | |
|         if(!$is_start) return false; | |
|         return true; | |
|     } | |
| 
 | |
|     /** | |
|      * 文件分片上传 | |
|      * @author Gavin Lau | |
|      * @param unknown $savepath         文件最终保存路径 | |
|      * @param unknown $filemd5          文件md5 | |
|      * @param unknown $filesize         文件大小 | |
|      * @param unknown $part_upfile      分片上传文件 | |
|      * @param number $chunks            总分片数 | |
|      * @param number $chunk             第几分片数(从0开始) | |
|      * @param array $allow_file_exts    允许上传的类型array('zip','rar'); | |
|      * @param string $chunksize         分片切割大小(默认5M) | |
|      */ | |
|     public function uploadFileParts($savepath, $filemd5, $filesize, $part_upfile, $chunks=0, $chunk=0, $allow_file_exts=array(), $chunksize=UPFILE_CHUNK_SIZE) { | |
|         // 校验上传分片文件是否正确 | |
|         if($part_upfile['error'] == 4) return $this->jsonResult(false, '请先上传文件'); | |
|         if($part_upfile['error'] == 3) return $this->jsonResult(false, '上传文件不完整,请重新上传'); | |
|         if($part_upfile['error'] == 1 || $part_upfile['error'] == 2) return $this->jsonResult(false, '上传文件过大'); | |
|         if($part_upfile['size'] < 0) return $this->jsonResult(false, '上传文件大小错误'); | |
|         // 判断允许上传文件类型 | |
|         if(is_array($allow_file_exts) && count($allow_file_exts)>0) { | |
|             setlocale(LC_ALL, 'zh_CN.UTF-8'); | |
|             $ext = pathinfo($part_upfile['name'], PATHINFO_EXTENSION); | |
|             if(!in_array($ext, $allow_file_exts)) return $this->jsonResult(false, '上传文件格式不正确'); | |
|         } | |
| 
 | |
|         $save_dir = dirname($savepath); | |
|         if(!is_dir($save_dir)) { | |
|             mkdir($save_dir, 0755, true); | |
|             chown($save_dir, 'nobody'); | |
|             chgrp($save_dir, 'nobody'); | |
|         } | |
| 
 | |
|         // 如果未达到分片大小,直接保存文件 | |
|         if($chunks==0 && $chunk==0) { | |
|             $res = move_uploaded_file($part_upfile['tmp_name'], $savepath); | |
|             if(!$res) return $this->jsonResult(false, '文件保存失败,请重新上传'); | |
|             return $this->jsonResult(true, '文件保存成功', array('is_merged'=>true)); | |
|         } | |
| 
 | |
|         // 分片保存路径 | |
|         $part_savepath = sprintf(UPLOAD_FILE_PARTS_TEMPPATH, date("Y-m-d"), $filemd5, $chunk); | |
|         $dir = dirname($part_savepath); | |
|         if(!is_dir($dir)) { | |
|             mkdir($dir, 0755, true); | |
|             chown($dir, 'nobody'); | |
|             chgrp($dir, 'nobody'); | |
|         } | |
| 
 | |
|         $res = move_uploaded_file($part_upfile['tmp_name'], $part_savepath); | |
|         if(!$res) return $this->jsonResult(false, '文件保存失败,请重新上传'); | |
| 
 | |
|         // redis hash | |
|         $rhkey = sprintf(_RH_UPLOAD_FILE_PARTS, $filemd5); | |
|         $rdobj = $this->initRedis(); | |
| 
 | |
|         // 实际每一片大小 | |
|         $up_partsize = $chunksize; | |
|         // 最后一片大小 | |
|         if($chunks>0 && $chunks-1 == $chunk) $up_partsize = $filesize - $chunk*$chunksize; | |
|         $rdobj->hset($rhkey, $chunk, $up_partsize); | |
|         if($chunk==0) $rdobj->expire($rhkey, 60*60); | |
| 
 | |
|         $parts_count = $rdobj->hlen($rhkey); | |
|         // 合并分片 | |
|         if($parts_count == $chunks) { | |
|             $handle = fopen($savepath, 'wb'); | |
|             for($i=0; $i<$parts_count; $i++) { | |
|                 $part_path = sprintf(UPLOAD_FILE_PARTS_TEMPPATH, date("Y-m-d"), $filemd5, $i); | |
|                 if(!file_exists($part_path)) return $this->jsonResult(false, '分块文件缺失|'.$i); | |
| 
 | |
|                 $part_size = $rdobj->hget($rhkey, $i); | |
|                 if(!$part_size) return $this->jsonResult(false, '分块文件大小缺失|'.$i); | |
| 
 | |
|                 $part_handle  = fopen($part_path, 'rb'); | |
|                 $content = fread($part_handle, $part_size); | |
|                 fwrite($handle, $content); | |
|                 unset($content); | |
|                 fclose($part_handle);      // 销毁分片文件资源 | |
|  | |
|                 unlink($part_path);        // 删除已经合并的分片文件 | |
|             } | |
|             fclose($handle); | |
|             $rdobj->del($rhkey); | |
|             return $this->jsonResult(true, '文件保存成功', array('is_merged'=>true)); | |
|         } | |
|         return $this->jsonResult(true, '文件保存成功', array('is_merged'=>false)); | |
|     } | |
| 
 | |
|     private function jsonResult($status = 1, $info = null, $data = array()) { | |
|         $result = array(); | |
|         $result['status'] = $status; | |
|         $result['info'] = !is_null($info) ? $info : ''; | |
|         $result['data'] = $data; | |
|         return json_encode($result); | |
|     } | |
| 
 | |
|     /** | |
|      * 一段时间内请求次数限制 | |
|      * @param unknown $key              缓存key | |
|      * @param number $limit_times       限制次数 | |
|      * @param number $time_interval     时间间隔(秒) | |
|      * @return boolean | |
|      */ | |
|     public function requestLimit($key, $limit_times=10, $time_interval=60) { | |
|         $rdobj = $this->initRedis(); | |
|         $request_times = $rdobj->get($key); | |
|         if($request_times >= $limit_times){ | |
|             $this->setError('请勿频繁操作'); | |
|             return false; | |
|         } | |
|         $rdobj->setex($key, $time_interval, $request_times+1); | |
|         return true; | |
|     } | |
| 
 | |
| 
 | |
| 
 | |
|     /** | |
|      * base62整形加密 | |
|      * @param unknown $num | |
|      * @return string | |
|      */ | |
|     public function base62EncodeInteger($num) { | |
|         $base62 = gmp_strval(gmp_init($num, 10), 62); | |
|         if ($this->gmp === $this->base62_string) { | |
|             return $base62; | |
|         } | |
| 
 | |
|         return strtr($base62, $this->gmp, $this->base62_string); | |
|     } | |
| 
 | |
|     /** | |
|      * base解密 加密的整形 | |
|      * @param unknown $encode_str | |
|      * @return number | |
|      */ | |
|     public function base62DecodeInteger($encode_str) { | |
|         $this->validateInput($encode_str); | |
| 
 | |
|         if ($this->gmp !== $this->base62_string) { | |
|             $encode_str = strtr($encode_str, $this->base62_string, $this->gmp); | |
|         } | |
| 
 | |
|         $hex = gmp_strval(gmp_init($encode_str, 62), 16); | |
|         if (strlen($hex) % 2) { | |
|             $hex = "0" . $hex; | |
|         } | |
| 
 | |
|         return (int) hexdec($hex); | |
|     } | |
| 
 | |
|     private function validateInput($data) { | |
|         /* If the data contains characters that aren't in the character set. */ | |
|         if (strlen($data) !== strspn($data, $this->base62_string)) { | |
|             $valid = str_split($this->base62_string); | |
|             $invalid = str_replace($valid, "", $data); | |
|             $invalid = count_chars($invalid, 3); | |
| 
 | |
|             throw new InvalidArgumentException( | |
|                 "Data contains invalid characters \"{$invalid}\"" | |
|             ); | |
|         } | |
|     } | |
| 
 | |
|     public function unRarUsePhp($zippath, $unzippath, $password=NULL) { | |
|         $zipdir = dirname($zippath); | |
|         if (!is_dir($zipdir)) mkdir($zipdir, 0775, true); | |
|         chown($zipdir, 'nobody'); | |
|         chgrp($zipdir, 'nobody'); | |
| 
 | |
|         if (!is_dir($unzippath)) mkdir($unzippath, 0775, true); | |
|         chown($unzippath, 'nobody'); | |
|         chgrp($unzippath, 'nobody'); | |
| 
 | |
|         if ($password === null) { | |
|             $rar_file = rar_open($zippath) OR die('failed to open ' . $zippath); | |
|         } else { | |
|             $rar_file = rar_open($zippath, $password) OR die('failed to open ' . $zippath); | |
|         } | |
| 
 | |
|         $entries = rar_list($rar_file); | |
|         foreach ($entries as $entry) { | |
|             $res = $entry->extract(false, $unzippath."/".$entry->getName(), $password); | |
|             if (!$res) return false; | |
|         } | |
|         rar_close($rar_file); | |
|         return true; | |
|     } | |
| 
 | |
|     /** | |
|      * downloadFileChunk | |
|      * @param unknown $filepath | |
|      * @param unknown $outfile_name | |
|      * @return boolean | |
|      */ | |
|     public function downFileChunk($filepath, $outfile_name, $is_del_file=false) { | |
|         if(!file_exists($filepath)) { | |
|             $this->setError('下载文件不存在'); | |
|             return false; | |
|         } | |
| 
 | |
|         // 如果标题中存在空格,需要替换掉 | |
|         $outfile_name = str_replace(',', '_', str_replace(' ', '', $outfile_name)); | |
|         $outfile_name = urlencode($outfile_name); | |
|         $outfile_name = str_replace("+", "%20", $outfile_name); | |
| 
 | |
|         //根据扩展名 指出输出浏览器格式 | |
|         $outfile_ext = pathinfo($outfile_name, PATHINFO_EXTENSION); | |
|         switch ($outfile_ext) { | |
|             case "exe" : | |
|                 $ctype = "application/octet-stream"; | |
|                 break; | |
|             case "zip" : | |
|                 $ctype = "application/zip"; | |
|                 break; | |
|             case "mp3" : | |
|                 $ctype = "audio/mpeg"; | |
|                 break; | |
|             case "mpg" : | |
|                 $ctype = "video/mpeg"; | |
|                 break; | |
|             case "avi" : | |
|                 $ctype = "video/x-msvideo"; | |
|                 break; | |
|             default : | |
|                 $ctype = "application/force-download"; | |
|         } | |
|         // Begin writing headers | |
|         header("Cache-Control:"); | |
|         header("Cache-Control: public"); | |
|         // 设置输出浏览器格式 | |
|         header("Content-Type: $ctype"); | |
|         header("Content-Disposition: attachment; filename=" . $outfile_name); | |
|         header("Accept-Ranges: bytes"); | |
| 
 | |
|         $filesize = filesize($filepath); | |
|         $filesize2 = $filesize -1; //文件总字节数 | |
|         //如果有$_SERVER['HTTP_RANGE']参数 | |
|         if (isset ($_SERVER['HTTP_RANGE'])) { | |
|             /* | |
|              * Range头域 Range头域可以请求实体的一个或者多个子范围。 | |
|              *  例如, 表示头500个字节:bytes=0-499 | |
|              *  表示第二个500字节:bytes=500-999 | |
|              *  表示最后500个字节:bytes=-500 | |
|              *   表示500字节以后的范围:bytes=500- | |
|              *   第一个和最后一个字节:bytes=0-0,-1 | |
|              *   同时指定几个范围:bytes=500-600,601-999 | |
|              *   但是服务器可以忽略此请求头,如果无条件GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是以200 (OK)。 | |
|              */ | |
|             // 断点后再次连接 $_SERVER['HTTP_RANGE'] 的值 bytes=4390912- | |
|             list ($a, $range) = explode("=", $_SERVER['HTTP_RANGE']); | |
| 
 | |
|             //if yes, download missing part | |
|             str_replace($range, "-", $range); | |
|             $new_length = $filesize2 - $range; //获取下次下载的长度 | |
|             header("HTTP/1.1 206 Partial Content"); | |
|             header("Content-Length: $new_length"); //输入总长 | |
|             header("Content-Range: bytes $range$filesize2/$filesize"); //Content-Range: bytes 4908618-4988927/4988928 95%的时候 | |
|         } else { | |
|             header("Content-Range: bytes 0-$filesize2/$filesize"); //Content-Range: bytes 0-4988927/4988928 | |
|             header("Content-Length: " . $filesize); //输出总长 | |
|         } | |
| 
 | |
|         header("Expires: 0"); | |
| 
 | |
|         $ua = $_SERVER["HTTP_USER_AGENT"]; | |
|         if(preg_match("/safari/", strtolower($ua))) $outfile_name = urldecode($outfile_name); | |
|         if (preg_match("/Firefox/", $ua)) { | |
|             header('Content-Disposition: attachment; filename*="utf8\'\'' . $outfile_name . '"'); | |
|         } else { | |
|             Header("Content-Disposition: attachment; filename=".$outfile_name); | |
|         } | |
| 
 | |
|         if (file_exists($filepath)) { | |
|             $fp = fopen("$filepath", "rb"); | |
|             $buffercount = 0; | |
|             $buffer = 1*1024*1024; | |
|             ob_end_clean();//缓冲区结束 | |
|             ob_implicit_flush();//强制每当有输出的时候,即刻把输出发送到浏览器 | |
|             header('X-Accel-Buffering: no'); // 不缓冲数据 | |
|             while(!feof($fp)&&$filesize-$buffercount>0){//循环读取文件数据 | |
|                 $data=fread($fp,$buffer); | |
|                 $buffercount+=$buffer; | |
|                 echo $data;//输出文件 | |
|             } | |
|             fclose($fp); | |
| 
 | |
|             if ($is_del_file) unlink($filepath); | |
|         } | |
| 
 | |
|         exit(); | |
|     } | |
| 
 | |
|     public function getIpAddress($ip) { | |
|         $res = $this->getCUrl("http://ip.geo.iqiyi.com/cityjson?format=json&ip={$ip}"); | |
|         if (!$res) return array(); | |
| 
 | |
|         $data = json_decode($res, true); | |
| 
 | |
|         return array( | |
|             'country'  => $data['data']['country'], | |
|             'province' => $data['data']['province'], | |
|             'city'     => $data['data']['city'], | |
|             'isp'      => $data['data']['isp'], | |
|         ); | |
|     } | |
| 
 | |
|     /** | |
|      * 域名后缀是否正确 | |
|      * @param unknown $domain | |
|      * @return boolean | |
|      */ | |
|     public function isDomainSuffix($domain) { | |
|         $data = explode('.', $domain); | |
|         $suffix = end($data); | |
|         $suffixs = array( | |
|             '.com','.cn','.top','.ltd','.net','.tech','.shop','.vip','.xyz','.wang','.cloud','.online','.icu','.site','.love','.art','.xin','.store','.fun','.cc','.website','.press','.space','.beer','.luxe', | |
|             '.video','.ren','.group','.fit','.yoga','.pro','.ink','.biz','.info','.design','.link','.work','.mobi','.kim','.pub','.club','.tv','.asia','.red','.live', | |
|             '.wiki','.life','.world','.run','.show','.city','.gold','.today','.plus','.cool','.company','.chat','.zone','.fans','.law','.host','.center','.email','.fund','.social','.team','.guru','.co', | |
|             '.org' | |
|         ); | |
| 
 | |
|         if (!in_array('.'.$suffix, $suffixs)) return false; | |
| 
 | |
|         return true; | |
|     } | |
| 
 | |
|     /** | |
|      * 过滤关键词 | |
|      * | |
|      * @param string $content | |
|      * @return string | |
|      */ | |
|     public function filterKeys($content) { | |
|         return str_replace($GLOBALS['forbidden_keywords'], '', $content); | |
|     } | |
| 
 | |
|     public function readFileContent($file_path) { | |
|         $file_type = pathinfo($file_path, PATHINFO_EXTENSION); | |
| 
 | |
|         switch ($file_type) { | |
|             case 'doc': | |
|             case 'docx': | |
|                 return $this->readWordContent($file_path); | |
|             case 'pdf': | |
|                 return $this->readPDF($file_path); | |
|             default: | |
|                 return file_get_contents($file_path); | |
|         } | |
|         return false; | |
|     } | |
| 
 | |
|     /** | |
|      * 读PDF文件 | |
|      * @param  string $paperpath  论文路径 | |
|      * @return string 论文内容 | |
|      */ | |
|     public function readPDF($paperpath) { | |
|         return $this->readSecretPdf($paperpath); | |
|     } | |
| 
 | |
|     /** | |
|      * 读取加密的pdf  使用的是java第三方扩展pdfbox库 | |
|      * @param string $paperpath pdf路径 | |
|      */ | |
|     public function readSecretPdf($paperpath) { | |
|         $cmd = 'java -Dfile.encoding=UTF-8 -jar ' . DATACENTER_ROOT .'/java/readSecretPdf.jar ' . "'".$paperpath."'"; | |
|         return shell_exec($cmd); | |
|     } | |
| 
 | |
|     /** | |
|      * 读docx文件 | |
|      * @param  string $paperpath  论文路径 | |
|      * @return string 论文内容 | |
|      */ | |
|     public function readWordContent($paperpath, $is_reduce_read = false) { | |
|         $cmd = 'java -Dfile.encoding=UTF-8 -jar ' . DATACENTER_ROOT .'/java/readWordContent.jar ' . "'".$paperpath."'"; | |
|         return shell_exec($cmd); | |
|     } | |
| 
 | |
| }
 | |
| 
 |