diff --git a/.gitignore b/.gitignore index 5d947ca8879f8a9072fe485c566204e3c2929e80..80c94226455b07ae2d755393faaed7c4b97945a4 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ bin-release/ # Other files and folders .settings/ +.idea/ +.git/ # Executables *.swf diff --git a/application/.htaccess b/application/.htaccess new file mode 100644 index 0000000000000000000000000000000000000000..3418e55a68383c1cbc687c52a2994d1e8ed83800 --- /dev/null +++ b/application/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/application/api/common/AliSms.php b/application/api/common/AliSms.php new file mode 100644 index 0000000000000000000000000000000000000000..d3c9156861051fdf4eef56d3fb91083c4abba452 --- /dev/null +++ b/application/api/common/AliSms.php @@ -0,0 +1,140 @@ + "cn-hangzhou", + "Action" => "SendSms", + "Version" => "2017-05-25", + )) + // fixme 选填: 启用https + // ,true + ); + + return $content; + } + + /** + * 生成签名并发起请求 + * + * @param $accessKeyId string AccessKeyId (https://ak-console.aliyun.com/) + * @param $accessKeySecret string AccessKeySecret + * @param $domain string API接口所在域名 + * @param $params array API具体参数 + * @param $security boolean 使用https + * @return bool|\stdClass 返回API接口调用结果,当发生错误时返回false + */ + public static function request($accessKeyId, $accessKeySecret, $domain, $params, $security=false) { + $apiParams = array_merge(array ( + "SignatureMethod" => "HMAC-SHA1", + "SignatureNonce" => uniqid(mt_rand(0,0xffff), true), + "SignatureVersion" => "1.0", + "AccessKeyId" => $accessKeyId, + "Timestamp" => gmdate("Y-m-d\TH:i:s\Z"), + "Format" => "JSON", + ), $params); + ksort($apiParams); + + $sortedQueryStringTmp = ""; + foreach ($apiParams as $key => $value) { + $sortedQueryStringTmp .= "&" . self::encode($key) . "=" . self::encode($value); + } + + $stringToSign = "GET&%2F&" . self::encode(substr($sortedQueryStringTmp, 1)); + + $sign = base64_encode(hash_hmac("sha1", $stringToSign, $accessKeySecret . "&",true)); + + $signature = self::encode($sign); + + $url = ($security ? 'https' : 'http')."://{$domain}/?Signature={$signature}{$sortedQueryStringTmp}"; + + try { + $content = self::fetchContent($url); + return json_decode($content); + } catch( \Exception $e) { + return false; + } + } + + static function encode($str) + { + $res = urlencode($str); + $res = preg_replace("/\+/", "%20", $res); + $res = preg_replace("/\*/", "%2A", $res); + $res = preg_replace("/%7E/", "~", $res); + return $res; + } + + static function fetchContent($url) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_TIMEOUT, 5); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_HTTPHEADER, array( + "x-sdk-client" => "php/2.0.0" + )); + + if(substr($url, 0,5) == 'https') { + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + } + + $rtn = curl_exec($ch); + + if($rtn === false) { + trigger_error("[CURL_" . curl_errno($ch) . "]: " . curl_error($ch), E_USER_ERROR); + } + curl_close($ch); + + return $rtn; + } +} \ No newline at end of file diff --git a/application/api/common/Page.php b/application/api/common/Page.php new file mode 100644 index 0000000000000000000000000000000000000000..cf3c5c1fb8311e87f32a2857ce441b3a5ca65eb0 --- /dev/null +++ b/application/api/common/Page.php @@ -0,0 +1,27 @@ +request = $request; + $this->init(); + } + + /** + * 初始化 + * 检查请求类型,数据格式等 + */ + public function init() + { + //所有ajax请求的options预请求都会直接返回200,如果需要单独针对某个类中的方法,可以在路由规则中进行配置 + if($this->request->isOptions()){ + + return self::returnMsg(200,'success'); + } + if(!Oauth::match($this->noAuth)){ //请求方法白名单 + //$oauth = app('app\api\controller\Oauth'); //tp5.1容器,直接绑定类到容器进行实例化 + //return $this->clientInfo = $oauth->authenticate();; + } + } + + /** + * 空方法 + */ + public function _empty() + { + return self::returnMsg(404, 'empty method!'); + } +} diff --git a/application/api/controller/Oauth.php b/application/api/controller/Oauth.php new file mode 100644 index 0000000000000000000000000000000000000000..65f562a898af0a501d8c6e0bb3a37e1b4fb0fc7b --- /dev/null +++ b/application/api/controller/Oauth.php @@ -0,0 +1,122 @@ +action()), $arr) || in_array('*', $arr)) + { + return true; + } + + // 没找到匹配 + return false; + } + + /** + * 生成签名 + * _字符开头的变量不参与签名 + */ + public static function makeSign ($data = [],$app_secret = '') + { + unset($data['version']); + unset($data['sign']); + return self::_getOrderMd5($data); + } + + /** + * 计算ORDER的MD5签名 + */ + private static function _getOrderMd5($params = []) { + ksort($params); + return strtolower(md5(urldecode(http_build_query($params)))); + } + +} diff --git a/application/api/controller/Send.php b/application/api/controller/Send.php new file mode 100644 index 0000000000000000000000000000000000000000..6656acc6ff189363b4025d2f92b01b1717ce1789 --- /dev/null +++ b/application/api/controller/Send.php @@ -0,0 +1,31 @@ +$data]; + // 发送头部信息 + foreach ($header as $name => $val) { + if (is_null($val)) { + header($name); + } else { + header($name . ':' . $val); + } + } + return json($return,200); + //exit(json_encode($return,JSON_UNESCAPED_UNICODE)); + } +} + diff --git a/application/api/controller/v1/Facefusion.php b/application/api/controller/v1/Facefusion.php new file mode 100644 index 0000000000000000000000000000000000000000..52255f2ca72ec63e20f364e0f6bb103d2250ec5e --- /dev/null +++ b/application/api/controller/v1/Facefusion.php @@ -0,0 +1,184 @@ +isPost()){ + $base64 = $request->post("base64",""); + $typeID = $request->post("typeID",""); + $rsp = $request->post("rsp","url"); + if($base64 == ""){ + return self::returnMsg(-1,'请上传您的人脸照片',[]); + } + if($typeID == ""){ + return self::returnMsg(-1,'请选择需要融合的职业',[]); + } + + $dataCK = [ + 'api_key' => config('ks_api_key'), + 'api_secret' => config('ks_api_secret'), + 'image_base64' => $base64 + ]; + $urlCK = "https://api-cn.faceplusplus.com/facepp/v3/detect"; + $resCK = json_to_array(https_post($urlCK,$dataCK)); + if(isset($resCK['faces']) && empty($resCK['faces']) ){ + return self::returnMsg(-1,'人脸检测失败,请上传含有人脸的照片',[]); + } + //获取模版图的url + $templateUrls = config('ks_project'); + p($templateUrls,1); + + + + + } + } + /** + * + * @return \think\Response + */ + public function index2(Request $request) { + if($request->isPost()){ + $base64 = $request->post("base64",""); + $typeID = $request->post("typeID",""); + $rsp = $request->post("rsp","url"); + + if($base64 == ""){ + return self::returnMsg(-1,'请上传您的人脸照片',[]); + } + if($typeID == ""){ + return self::returnMsg(-1,'请选择需要融合的职业',[]); + } + $typeIDs = config($typeID); + + + $type = $typeIDs[rand(0,count($typeIDs)-1)]; + try{ + // 实例化一个证书对象,入参需要传入腾讯云账户secretId,secretKey + $cred = new Credential(config('tx_secretId'),config('tx_secretKey')); + + $httpProfile = new HttpProfile(); + $httpProfile->setEndpoint("facefusion.tencentcloudapi.com"); + $clientProfile = new ClientProfile(); + $clientProfile->setHttpProfile($httpProfile); + $client = new FacefusionClient($cred, "", $clientProfile); + $req = new FaceFusionRequest(); + $params = array( + "ProjectId" => config('tx_projectId'), + "ModelId" => $type['modelId'], + "Image" => $base64, + "RspImgType" => $rsp, + 'CelebrityIdentify' => 1, + ); + $req->fromJsonString(json_encode($params)); + $resp = $client->FaceFusion($req); + $respArr = json_decode($resp->toJsonString(),1); + + if(isset($respArr['Image'])){ + if($respArr['ReviewResultSet'][0]['Suggestion'] == 'BLOCK'){ + return self::returnMsg(200,'图片审核不通过,请重新上传', + ['typeID'=> $typeID,'su'=>1,'url'=>'https://tencent.wepromo.cn/3rd/sgd/public/assets/images/error.png']); + } + } + if($rsp == 'base64'){ + $imgUrl = 'data:image/jpeg;base64,'.$respArr['Image']; + } else { + $imgUrl = $respArr['Image']; + } + $countModel = new CountModel(); + $countModel->where(['id'=>1])->setInc('count',5); + + + + return self::returnMsg(200,'success',['url' => $imgUrl,'su'=>0,'typeID'=> $typeID]); + }catch (\TencentCloudSDKException $e) { + return self::returnMsg(-1,'error',[]); + } + } + return self::returnMsg(200,'success'); + } + + + public function check(Request $request){ + if($request->isPost()){ + $base64 = $request->post("base64",""); + if($base64 == ""){ + return self::returnMsg(-1,'请上传您的人脸照片',[]); + } + try { + $cred = new Credential(config('tx_secretId'),config('tx_secretKey')); + $httpProfile = new HttpProfile(); + $httpProfile->setEndpoint("iai.tencentcloudapi.com"); + + $clientProfile = new ClientProfile(); + $clientProfile->setHttpProfile($httpProfile); + $client = new IaiClient($cred, "", $clientProfile); + + $req = new DetectFaceRequest(); + $params = array( + "MinFaceSize" => 1, + "Image" => $base64, + "NeedFaceAttributes" => 0, + "NeedQualityDetection" => 0 + ); + $req->fromJsonString(json_encode($params)); + + $resp = $client->DetectFace($req); + + p($resp,1); + + + + + } catch (\TencentCloudSDKException $e) { + echo $e; + } + } + + } + + + public function savecount(Request $request){ + if($request->isPost()){ + //增加当前使用人数 + $countModel = new CountModel(); + $countModel->where(['id'=>1])->setInc('count'); + return self::returnMsg(200,'success'); + } + } + + + public function getcount(Request $request){ + if($request->isPost()){ + //查询当前使用人数 + $countModel = new CountModel(); + $countInfo = $countModel->field('count')->where(['id'=>1]) ->find(); + return self::returnMsg(200,'success',['count'=>$countInfo['count']]); + } + } +} diff --git a/application/api/controller/v1/Token.php b/application/api/controller/v1/Token.php new file mode 100644 index 0000000000000000000000000000000000000000..fde52366b1892aab0bd15c0f09a5566bc37640ad --- /dev/null +++ b/application/api/controller/v1/Token.php @@ -0,0 +1,171 @@ +supplierModel = new SupplierModel(); + } + + /** + * 生成token + */ + public function token(Request $request) + { + $data = [ + 'appid' => $request->post('appid',''), + 'nonce' => $request->post('nonce',''), + 'timestamp' => $request->post('timestamp',''), + 'sercet' => $request->post('sercet',''), + 'key' => $request->post('key',''), + 'sign' => $request->post('sign','') + ]; + //参数验证 + $validate = new \app\api\validate\Token; + if(!$validate->check($data)){ + return self::returnMsg(401,$validate->getError()); + } + $this->checkParams($data); //参数校验 + + try { + $accessToken = self::setAccessToken($data); //传入参数应该是根据手机号查询改用户的数据 + return $accessToken['access_token']; + //return self::returnMsg(200,'success',$accessToken); + } catch (Exception $e) { + return self::returnMsg(500,'fail',$e); + } + } + + /** + * 刷新token + */ + public function refresh($refresh_token='',$appid = '') + { + $cache_refresh_token = Cache::get(self::$refreshAccessTokenPrefix.$appid); //查看刷新token是否存在 + if(!$cache_refresh_token){ + return self::returnMsg(401,'fail','refresh_token is null'); + }else{ + if($cache_refresh_token !== $refresh_token){ + return self::returnMsg(401,'fail','refresh_token is error'); + }else{ //重新给用户生成调用token + $data['appid'] = $appid; + $accessToken = self::setAccessToken($data); + return self::returnMsg(200,'success',$accessToken); + } + } + } + + /** + * 参数检测 + */ + public function checkParams($params = []) + { + //时间戳校验 + if(abs($params['timestamp'] - time()) > self::$timeDif){ + + return self::returnMsg(401,'请求时间戳与服务器时间戳异常','timestamp:'.time()); + } + //查询是否存在appid + $info = $this->supplierModel->getOneByAppID($params['appid'],'appid,appsercet'); + if(empty($info)){ + return self::returnMsg(401,'无效的appid'); + } + + //appid检测,这里是在本地进行测试,正式的应该是查找数据库或者redis进行验证 + if($params['sercet'] !== $info['appsercet']){ + return self::returnMsg(401,'无效的sercet'); + } + + //签名检测 + $sign = Oauth::makeSign($params,$info['appsercet']); + if($sign !== $params['sign']){ + return self::returnMsg(401,'无效的sign'); + } + } + + /** + * 设置AccessToken + * @param $clientInfo + * @return int + */ + protected function setAccessToken($clientInfo) + { + //生成令牌 + $accessToken = self::buildAccessToken(); + $refresh_token = self::getRefreshToken($clientInfo['appid']); + + $accessTokenInfo = [ + 'appid' => $clientInfo['appid'], + 'access_token' => $accessToken,//访问令牌 + 'expires_time' => time() + self::$expires, //过期时间时间戳 + 'refresh_token' => $refresh_token,//刷新的token + 'refresh_expires_time' => time() + self::$refreshExpires, //过期时间时间戳 + ]; + self::saveAccessToken($accessToken, $accessTokenInfo); //保存本次token + self::saveRefreshToken($refresh_token,$clientInfo['appid']); + return $accessTokenInfo; + } + + /** + * 刷新用的token检测是否还有效 + */ + public static function getRefreshToken($appid = '') + { + return Cache::get(self::$refreshAccessTokenPrefix.$appid) ? Cache::get(self::$refreshAccessTokenPrefix.$appid) : self::buildAccessToken(); + } + + /** + * 生成AccessToken + * @return string + */ + protected static function buildAccessToken($lenght = 32) + { + //生成AccessToken + $str_pol = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789abcdefghijklmnopqrstuvwxyz"; + return substr(str_shuffle($str_pol), 0, $lenght); + + } + + /** + * 存储token + * @param $accessToken + * @param $accessTokenInfo + */ + protected static function saveAccessToken($accessToken, $accessTokenInfo) + { + //存储accessToken + cache(self::$accessTokenPrefix . $accessToken, $accessTokenInfo, self::$expires); + } + + /** + * 刷新token存储 + * @param $accessToken + * @param $accessTokenInfo + */ + protected static function saveRefreshToken($refresh_token,$appid) + { + //存储RefreshToken + cache(self::$refreshAccessTokenPrefix.$appid,$refresh_token,self::$refreshExpires); + } +} \ No newline at end of file diff --git a/application/api/exception/BaseException.php b/application/api/exception/BaseException.php new file mode 100644 index 0000000000000000000000000000000000000000..ee04c651caf0ad506f4334be1c949b1899d52b99 --- /dev/null +++ b/application/api/exception/BaseException.php @@ -0,0 +1,33 @@ +code = $params['code']; + } + if (array_key_exists('msg', $params)) { + $this->message = $params['msg']; + } + } +} + diff --git a/application/api/exception/ExceptionHandler.php b/application/api/exception/ExceptionHandler.php new file mode 100644 index 0000000000000000000000000000000000000000..2df5ee604c663567a380ee211122a81e0b7dc7da --- /dev/null +++ b/application/api/exception/ExceptionHandler.php @@ -0,0 +1,57 @@ +statuscode = $this->code = 500; + + if ($e instanceof BaseException) { //是否异常实例 + $this->code = $e->code; + $this->message = $e->message; + } else { + if (config('app_debug')) { //是否开启debug模式,异常交给父类异常处理,否则输出json格式错误 + return parent::render($e); + } + $this->code = 500; + $this->message = $e->getMessage() ?: '很抱歉,服务器内部错误'; + //$this->recordErrorLog($e); + } + // Http异常 + if ($e instanceof \think\exception\HttpException) + { + $this->statuscode = $this->code = $e->getStatusCode(); + } + return json(['msg' => $this->message, 'code' => $this->code,'data' => null],$this->statuscode); + } + + /** + * 将异常写入日志 + * @param Exception $e + */ + private function recordErrorLog(Exception $e) + { + Log::record($e->getMessage(), 'error'); + Log::record($e->getTraceAsString(), 'error'); + } +} diff --git a/application/api/utils/ArrayUtil.php b/application/api/utils/ArrayUtil.php new file mode 100644 index 0000000000000000000000000000000000000000..c5a3451331535766abad129d8b0dc4ffe23a5553 --- /dev/null +++ b/application/api/utils/ArrayUtil.php @@ -0,0 +1,114 @@ +"; + foreach ($values as $key => $val) { + if (is_numeric($val)) { + $xml.="<".$key.">".$val."".$key.">"; + } else { + $xml.="<".$key.">".$key.">"; + } + } + $xml.=""; + return $xml; + } + + /** + * 将xml转为array + * @param string $xml + * @return array|false + */ + public static function toArray($xml) + { + if (!$xml) { + return false; + } + + // 检查xml是否合法 + $xml_parser = xml_parser_create(); + if (!xml_parse($xml_parser, $xml, true)) { + xml_parser_free($xml_parser); + return false; + } + + //将XML转为array + //禁止引用外部xml实体 + libxml_disable_entity_loader(true); + + $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); + + return $data; + } + + /** + * google api 二维码生成【QRcode可以存储最多4296个字母数字类型的任意文本,具体可以查看二维码数据格式】 + * @param string $text 二维码包含的信息,可以是数字、字符、二进制信息、汉字。不能混合数据类型,数据必须经过UTF-8 URL-encoded + * @param string $widthHeight 生成二维码的尺寸设置 + * @param string $ecLevel 可选纠错级别,QR码支持四个等级纠错,用来恢复丢失的、读错的、模糊的、数据。 + * L-默认:可以识别已损失的7%的数据 + * M-可以识别已损失15%的数据 + * Q-可以识别已损失25%的数据 + * H-可以识别已损失30%的数据 + * + * @param string $margin 生成的二维码离图片边框的距离 + * + * @return string + */ + public static function toQRimg($text, $widthHeight = '150', $ecLevel = 'L', $margin = '0') + { + $chl = urlencode($text); + + return "http://chart.apis.google.com/chart?chs={$widthHeight}x{$widthHeight}&cht=qr&chld={$ecLevel}|{$margin}&chl={$chl}"; + } +} diff --git a/application/api/utils/wxBizDataCrypt.php b/application/api/utils/wxBizDataCrypt.php new file mode 100644 index 0000000000000000000000000000000000000000..533dfb317059d4fc08df16852ad2c8d7e0a61cc5 --- /dev/null +++ b/application/api/utils/wxBizDataCrypt.php @@ -0,0 +1,68 @@ +sessionKey = $sessionKey; + $this->appid = $appid; + } + + + /** + * 检验数据的真实性,并且获取解密后的明文. + * @param $encryptedData string 加密的用户数据 + * @param $iv string 与用户数据一同返回的初始向量 + * @param $data string 解密后的原文 + * + * @return int 成功0,失败返回对应的错误码 + */ + public function decryptData( $encryptedData, $iv ) + { + if (strlen($this->sessionKey) != 24) { + return self::$IllegalAesKey; + } + $aesKey=base64_decode($this->sessionKey); + + + if (strlen($iv) != 24) { + return self::$IllegalIv; + } + $aesIV=base64_decode($iv); + + $aesCipher=base64_decode($encryptedData); + + $result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV); + + $dataObj=json_decode( $result ); + if( $dataObj == NULL ) + { + return self::$IllegalBuffer; + } + if( $dataObj->watermark->appid != $this->appid ) + { + return self::$IllegalBuffer; + } + $data = $result; + return $data; + } +} \ No newline at end of file diff --git a/application/api/validate/Token.php b/application/api/validate/Token.php new file mode 100644 index 0000000000000000000000000000000000000000..7526eddb31a25991f71f70a2e8b73b83051a864a --- /dev/null +++ b/application/api/validate/Token.php @@ -0,0 +1,28 @@ + 'require', + 'sercet' => 'require', + 'nonce' => 'require', + 'key' => 'require', + 'timestamp' => 'number|require', + 'sign' => 'require' + ]; + + protected $message = [ + 'appid.require' => 'appid不能为空', + 'sercet.require' => 'sercet不能为空', + 'key.require' => '设备信息不能为空', + 'nonce.require' => '随机数不能为空', + 'timestamp.number' => '时间戳格式错误', + 'sign.require' => '签名不能为空', + ]; +} \ No newline at end of file diff --git a/application/api/validate/ValidataCommon.php b/application/api/validate/ValidataCommon.php new file mode 100644 index 0000000000000000000000000000000000000000..0f59b9a6a6acb25afc1f57fddfc8ccc93426f4b4 --- /dev/null +++ b/application/api/validate/ValidataCommon.php @@ -0,0 +1,51 @@ + $v){ + if(!in_array($v,self::$dataRule)){ + return self::returnMsg(401,'fail','验证规则只支持require,int'); + } + if(!isset($data[$k]) || empty($data[$k])){ + return self::returnMsg(401,'fail',$k.'不能为空'); + }else{ + if($v == 'int'){ + if(!is_numeric($data[$k])){ + return self::returnMsg(401,'fail',$k.'类型必须为'.$v); + } + }elseif ($v == 'mobile'){ + if(!preg_match('/^1[3-9][0-9]\d{8}$/',$data[$k])){ + return self::returnMsg(401,'fail',$k.'手机号格式错误'); + } + } + } + } + }else{ + return self::returnMsg(401,'fail','验证数据格式为数组'); + } + + } +} \ No newline at end of file diff --git a/application/command.php b/application/command.php new file mode 100644 index 0000000000000000000000000000000000000000..826bb2b231d4f7863167c23aee1ab668e51e872f --- /dev/null +++ b/application/command.php @@ -0,0 +1,12 @@ + +// +---------------------------------------------------------------------- + +return []; diff --git a/application/common.php b/application/common.php new file mode 100644 index 0000000000000000000000000000000000000000..a8f87857a31aec0c79618185699c5061c3b803fe --- /dev/null +++ b/application/common.php @@ -0,0 +1,97 @@ + +// +---------------------------------------------------------------------- + +// 应用公共文件 +/** + * 打印输出 + * @param array $obj + * @param int $exit + */ +function p($obj = array(),$exit = 0,$format=1){ + if($format){ + echo "
"; + print_r($obj); + echo ""; + } else { + print_r($obj); + } + $exit && exit; +} +//获取远程内容 +function geturl($url) { + $headers1 = array( + //'referer' => $_POST['referer'], + 'Client-IP' => (empty($_SERVER['HTTP_CLIENT_IP'])? $_SERVER['REMOTE_ADDR'] : $_SERVER['HTTP_CLIENT_IP']), + 'X-Forwarded-For' => (empty($_SERVER['HTTP_X_FORWARDED_FOR'])? $_SERVER['REMOTE_ADDR'] : $_SERVER['HTTP_X_FORWARDED_FOR']), + ); + // 判断是否支持CURL + if (!function_exists('curl_init') || !function_exists('curl_exec')) { + exit('您的主机不支持Curl,请开启~'); + } + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_USERAGENT, 'Cloud Parse'); + //curl_setopt($curl, CURLOPT_REFERER, "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); + curl_setopt($curl, CURLOPT_AUTOREFERER, 1); + curl_setopt($curl, CURLOPT_TIMEOUT, 10); + curl_setopt($curl, CURLOPT_HEADER, 0); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + $data = curl_exec($curl); + curl_close($curl); + return $data; +} + +function https_post($url,$data=array()){ + $curl = curl_init(); // 启动一个CURL会话 + curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址 + //curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查 + //curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1); // 从证书中检查SSL加密算法是否存在 + curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器 + curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转 + curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer + curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求 + curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包 + curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环 + curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容 + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回 + $tmpInfo = curl_exec($curl); // 执行操作 + if (curl_errno($curl)) { + echo 'Errno'.curl_error($curl);//捕抓异常 + } + curl_close($curl); // 关闭CURL会话 + return $tmpInfo; // 返回数据,json格式 +} +/** + * json字符窜转换成数组 + * + * @param string $str json字符窜 + * @return array + */ +function json_to_array($str) { + if (is_string($str)) + $str = json_decode($str); + $arr=array(); + foreach($str as $k=>$v) { + if(is_object($v) || is_array($v)) + $arr[$k]=json_to_array($v); + else + $arr[$k]=$v; + } + return $arr; +} +//生成订单号 +function _getRandOrderID(){ + list($t1, $t2) = explode(' ', microtime()); + $order_id = $t2.rand(10,99).rand(10,99).rand(10,99).rand(0,9); + return $order_id; +} \ No newline at end of file diff --git a/application/provider.php b/application/provider.php new file mode 100644 index 0000000000000000000000000000000000000000..d0fcd2454482b0aa3af3e839ba7836faac6fdda4 --- /dev/null +++ b/application/provider.php @@ -0,0 +1,14 @@ + +// +---------------------------------------------------------------------- + +// 应用容器绑定定义 +return [ +]; diff --git a/application/tags.php b/application/tags.php new file mode 100644 index 0000000000000000000000000000000000000000..4b18d1050b7c1263ff327ba6a149123df323f869 --- /dev/null +++ b/application/tags.php @@ -0,0 +1,28 @@ + +// +---------------------------------------------------------------------- + +// 应用行为扩展定义文件 +return [ + // 应用初始化 + 'app_init' => [], + // 应用开始 + 'app_begin' => [], + // 模块初始化 + 'module_init' => [], + // 操作开始执行 + 'action_begin' => [], + // 视图内容过滤 + 'view_filter' => [], + // 日志写入 + 'log_write' => [], + // 应用结束 + 'app_end' => [], +]; diff --git a/composer.json b/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..28d0f37c2f5c520e4c90f4b4e5652f54209fcb2d --- /dev/null +++ b/composer.json @@ -0,0 +1,14 @@ +{ + "name": "smalls/video-tools", + "description": "", + "type": "library", + "require": { + "php": ">= 7.0", + "ext-json": "*", + "ext-openssl": "*", + "ext-SimpleXML": "*", + "ext-mbstring": "*", + "guzzlehttp/guzzle": "^6.3.0", + "tencentcloud/tencentcloud-sdk-php": "3.0.235" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000000000000000000000000000000000000..304bab33cb186462abf1bce7261ede126d07d9f4 --- /dev/null +++ b/composer.lock @@ -0,0 +1,775 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "c4cab94fed51556824ce7e7d0371edb5", + "packages": [ + { + "name": "guzzlehttp/guzzle", + "version": "6.5.5", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", + "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.cloud.tencent.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.6.1", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.17.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.1" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2020-06-16T21:01:06+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.cloud.tencent.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2016-12-20T10:07:11+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.cloud.tencent.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + }, + "suggest": { + "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2019-07-01T23:21:34+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.99", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.cloud.tencent.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "time": "2018-07-02T15:55:56+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.cloud.tencent.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.cloud.tencent.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.18.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "5dcab1bc7146cf8c1beaa4502a3d9be344334251" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/5dcab1bc7146cf8c1beaa4502a3d9be344334251", + "reference": "5dcab1bc7146cf8c1beaa4502a3d9be344334251", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.cloud.tencent.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-intl-normalizer": "^1.10", + "symfony/polyfill-php70": "^1.10", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.18-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-08-04T06:02:08+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.18.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e", + "reference": "37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.cloud.tencent.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.18-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-07-14T12:35:20+00:00" + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.18.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "0dd93f2c578bdc9c72697eaa5f1dd25644e618d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/0dd93f2c578bdc9c72697eaa5f1dd25644e618d3", + "reference": "0dd93f2c578bdc9c72697eaa5f1dd25644e618d3", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.cloud.tencent.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0|~9.99", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.18-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-07-14T12:35:20+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.18.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "639447d008615574653fb3bc60d1986d7172eaae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/639447d008615574653fb3bc60d1986d7172eaae", + "reference": "639447d008615574653fb3bc60d1986d7172eaae", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.cloud.tencent.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.18-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-07-14T12:35:20+00:00" + }, + { + "name": "tencentcloud/tencentcloud-sdk-php", + "version": "3.0.235", + "source": { + "type": "git", + "url": "https://github.com/TencentCloud/tencentcloud-sdk-php.git", + "reference": "bed9a47f545ea6b6dc1d25688b9ac53c6fbe7999" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/TencentCloud/tencentcloud-sdk-php/zipball/bed9a47f545ea6b6dc1d25688b9ac53c6fbe7999", + "reference": "bed9a47f545ea6b6dc1d25688b9ac53c6fbe7999", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.cloud.tencent.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "guzzlehttp/guzzle": "^6.3", + "guzzlehttp/psr7": "^1.4", + "php": ">=5.6.33" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/QcloudApi/QcloudApi.php" + ], + "psr-4": { + "TencentCloud\\": "./src/TencentCloud" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "coolli", + "email": "tencentcloudapi@tencent.com", + "homepage": "https://cloud.tencent.com/document/sdk/PHP", + "role": "Developer" + } + ], + "description": "TencentCloudApi php sdk", + "homepage": "https://github.com/TencentCloud/tencentcloud-sdk-php", + "time": "2020-08-18T01:26:16+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">= 7.0", + "ext-json": "*", + "ext-openssl": "*", + "ext-simplexml": "*", + "ext-mbstring": "*" + }, + "platform-dev": [], + "plugin-api-version": "1.1.0" +} diff --git a/config/app.php b/config/app.php new file mode 100644 index 0000000000000000000000000000000000000000..8c6e6166fd024d44b3b4760439735e5048cb8be3 --- /dev/null +++ b/config/app.php @@ -0,0 +1,271 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 应用设置 +// +---------------------------------------------------------------------- + +return [ + // 应用名称 + 'app_name' => '', + // 应用地址 + 'app_host' => '', + // 应用调试模式 + 'app_debug' => false, + // 应用Trace + 'app_trace' => false, + // 是否支持多模块 + 'app_multi_module' => true, + // 入口自动绑定模块 + 'auto_bind_module' => false, + // 注册的根命名空间 + 'root_namespace' => ['data'=>'../data/'], + // 默认输出类型 + 'default_return_type' => 'json', + // 默认AJAX 数据返回格式,可选json xml ... + 'default_ajax_return' => 'json', + // 默认JSONP格式返回的处理方法 + 'default_jsonp_handler' => 'jsonpReturn', + // 默认JSONP处理方法 + 'var_jsonp_handler' => 'callback', + // 默认时区 + 'default_timezone' => 'Asia/Shanghai', + // 是否开启多语言 + 'lang_switch_on' => false, + // 默认全局过滤方法 用逗号分隔多个 + 'default_filter' => '', + // 默认语言 + 'default_lang' => 'zh-cn', + // 应用类库后缀 + 'class_suffix' => false, + // 控制器类后缀 + 'controller_suffix' => false, + // +---------------------------------------------------------------------- + // | 模块设置 + // +---------------------------------------------------------------------- + + // 默认模块名 + 'default_module' => 'index', + // 禁止访问模块 + 'deny_module_list' => ['common'], + // 默认控制器名 + 'default_controller' => 'Index', + // 默认操作名 + 'default_action' => 'index', + // 默认验证器 + 'default_validate' => '', + // 默认的空模块名 + 'empty_module' => '', + // 默认的空控制器名 + 'empty_controller' => 'Error', + // 操作方法前缀 + 'use_action_prefix' => false, + // 操作方法后缀 + 'action_suffix' => '', + // 自动搜索控制器 + 'controller_auto_search' => false, + + // +---------------------------------------------------------------------- + // | URL设置 + // +---------------------------------------------------------------------- + // PATHINFO变量名 用于兼容模式 + 'var_pathinfo' => 's', + // 兼容PATH_INFO获取 + 'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'], + // pathinfo分隔符 + 'pathinfo_depr' => '/', + // HTTPS代理标识 + 'https_agent_name' => '', + // IP代理获取标识 + 'http_agent_ip' => 'X-REAL-IP', + // URL伪静态后缀 + 'url_html_suffix' => 'html', + // URL普通方式参数 用于自动生成 + 'url_common_param' => false, + // URL参数方式 0 按名称成对解析 1 按顺序解析 + 'url_param_type' => 0, + // 是否开启路由延迟解析 + 'url_lazy_route' => false, + // 是否强制使用路由 + 'url_route_must' => false, + // 合并路由规则 + 'route_rule_merge' => false, + // 路由是否完全匹配 + 'route_complete_match' => false, + // 使用注解路由 + 'route_annotation' => false, + // 域名根,如thinkphp.cn + 'url_domain_root' => '', + // 是否自动转换URL中的控制器和操作名 + 'url_convert' => true, + // 默认的访问控制器层 + 'url_controller_layer' => 'controller', + // 表单请求类型伪装变量 + 'var_method' => '_method', + // 表单ajax伪装变量 + 'var_ajax' => '_ajax', + // 表单pjax伪装变量 + 'var_pjax' => '_pjax', + // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则 + 'request_cache' => false, + // 请求缓存有效期 + 'request_cache_expire' => null, + // 全局请求缓存排除规则 + 'request_cache_except' => [], + // 是否开启路由缓存 + 'route_check_cache' => false, + // 路由缓存的Key自定义设置(闭包),默认为当前URL和请求类型的md5 + 'route_check_cache_key' => '', + // 路由缓存类型及参数 + 'route_cache_option' => [], + + // 默认跳转页面对应的模板文件 + 'dispatch_success_tmpl' => Env::get('think_path') . 'tpl/dispatch_jump.tpl', + 'dispatch_error_tmpl' => Env::get('think_path') . 'tpl/dispatch_jump.tpl', + + // 异常页面的模板文件 + 'exception_tmpl' => Env::get('think_path') . 'tpl/think_exception.tpl', + + // 错误显示信息,非调试模式有效 + 'error_message' => '页面错误!请稍后再试~', + // 显示错误信息 + 'show_error_msg' => false, + // 异常处理handle类 留空使用 \think\exception\Handle + //'exception_handle' => '\\app\\api\\exception\\ExceptionHandler', + 'exception_handle' => function($e) { + // 参数验证错误 + return json([ + 'msg'=>$e->getMessage(), + 'code'=>500, + 'data'=>'', + ]); + }, + //旷世人脸融合 + 'ks_api_key' => "8TK-03JRTc6p26mzHLUYga0D1DMBJ-_v", + 'ks_api_secret' => "CX7lwCyuxVNWblAUfJXkVf__dG1W-KW2", + 'ks_project' => [ + 'nurse_nan' => 'https://static.scms.sztv.com.cn/ysz/upload/Image/mrtp/2020/09/23/0ca7639ef73b4df5a968a0f67a47acc7.jpg', + 'nurse_nv' => 'https://static.scms.sztv.com.cn/ysz/upload/Image/mrtp/2020/09/23/2308f069375c4707a626dc6f95ea8747.jpg', + 'police_nan' => 'http://static.scms.sztv.com.cn/ysz/upload/Image/mrtp/2020/09/23/8c2d3cb6566045349ff3c4acc2ead6fa.jpg', + 'police_nv' => 'https://static.scms.sztv.com.cn/ysz/upload/Image/mrtp/2020/09/23/617044ccb2a94e98ab52a55acc7872e6.jpg', + 'stew_nan' => 'https://static.scms.sztv.com.cn/ysz/upload/Image/mrtp/2020/09/23/e7b35d363be34066a4815fcbf0a07ea1.jpg', + 'stew_nv' => 'https://static.scms.sztv.com.cn/ysz/upload/Image/mrtp/2020/09/23/e866f9a21de746809ea11fdda2d09b33.jpg', + 'school_nan' => 'https://static.scms.sztv.com.cn/ysz/upload/Image/mrtp/2020/09/23/00d3312ed3384a6aacef75a0a447ca20.jpg', + 'school_nv' => 'https://static.scms.sztv.com.cn/ysz/upload/Image/mrtp/2020/09/23/3b65896999d845e287c14444674dda1b.jpg', + 'volunteer_nan' => 'https://static.scms.sztv.com.cn/ysz/upload/Image/mrtp/2020/09/23/4a42c14a30ba4171951c40a298b94d74.jpg', + 'volunteer_nv' => 'https://static.scms.sztv.com.cn/ysz/upload/Image/mrtp/2020/09/23/7c94deee07e24d9886f16d623ad90082.jpg', + ], + //腾讯云人脸融合相关 + 'tx_projectId' => '304220', + 'tx_secretId' => 'AKIDkOsXFsQYcV6WpxBvCMLo9TdzHNbkGUC2', + 'tx_secretKey' => 'scFhw5DE3f4PZaTJ7jHsKn8HMFl9Mn7J', + 'nurse_nan' => [ + [ + 'modelId' => 'qc_304220_845778_134', + 'url' => 'nurse_1.jpg' + ] + ], + 'nurse_nv' => [ + [ + 'modelId' => 'qc_304220_898813_117', + 'url' => 'nurse_1.jpg' + ], + [ + 'modelId' => 'qc_304220_928425_118', + 'url' => 'nurse_2.jpg' + ] + ], + 'police_nan' => [ + [ + 'modelId' => 'qc_304220_881614_137', + 'url' => 'police_1.jpg' + ] + ], + 'police_nv' =>[ + [ + 'modelId' => 'qc_304220_463635_119', + 'url' => 'police_2.jpg' + ] + ], + 'stew_nan' =>[ + [ + 'modelId' => 'qc_304220_889670_129', + 'url' => 'police_2.jpg' + ], + [ + 'modelId' => 'qc_304220_598880_128', + 'url' => 'police_2.jpg' + ] + ], + 'stew_nv' => [ + [ + 'modelId' => 'qc_304220_910900_120', + 'url' => 'stew_1.jpg' + ], + [ + 'modelId' => 'qc_304220_825650_121', + 'url' => 'stew_2.jpg' + ], + [ + 'modelId' => 'qc_304220_553892_122', + 'url' => 'stew_3.jpg' + ], + [ + 'modelId' => 'qc_304220_477452_123', + 'url' => 'stew_4.jpg' + ], + [ + 'modelId' => 'qc_304220_160733_124', + 'url' => 'stew_5.jpg' + ], + [ + 'modelId' => 'qc_304220_279572_125', + 'url' => 'stew_6.jpg' + ], + [ + 'modelId' => 'qc_304220_589565_126', + 'url' => 'stew_7.jpg' + ], + [ + 'modelId' => 'qc_304220_959193_127', + 'url' => 'stew_8.jpg' + ] + ], + 'school_nv' => [ + [ + 'modelId' => 'qc_304220_226920_130', + 'url' => 'school_1.jpg' + ], + [ + 'modelId' => 'qc_304220_809183_133', + 'url' => 'school_1.jpg' + ], + ], + 'school_nan' => [ + [ + 'modelId' => 'qc_304220_276690_140', + 'url' => 'school_1.jpg' + ] + ], + 'volunteer_nan' => [ + [ + 'modelId' => 'qc_304220_637956_135', + 'url' => 'volunteer_1.jpg' + ] + ], + 'volunteer_nv' => [ + [ + 'modelId' => 'qc_304220_246292_136', + 'url' => 'volunteer_2.jpg' + ] + ], + // +]; diff --git a/config/cache.php b/config/cache.php new file mode 100644 index 0000000000000000000000000000000000000000..985dbb1c480bd612d18bb6945151396f7216616a --- /dev/null +++ b/config/cache.php @@ -0,0 +1,25 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 缓存设置 +// +---------------------------------------------------------------------- + +return [ + // 驱动方式 + 'type' => 'File', + // 缓存保存目录 + 'path' => '', + // 缓存前缀 + 'prefix' => '', + // 缓存有效期 0表示永久缓存 + 'expire' => 0, +]; diff --git a/config/console.php b/config/console.php new file mode 100644 index 0000000000000000000000000000000000000000..b0f9165ac2dcb7ce5d68e32e113f6b53084c0c3b --- /dev/null +++ b/config/console.php @@ -0,0 +1,19 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 控制台配置 +// +---------------------------------------------------------------------- +return [ + 'name' => 'Think Console', + 'version' => '0.1', + 'user' => null, +]; diff --git a/config/cookie.php b/config/cookie.php new file mode 100644 index 0000000000000000000000000000000000000000..1de07082a6c0a48f5b8cad6b798eef1f3310bfbc --- /dev/null +++ b/config/cookie.php @@ -0,0 +1,30 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | Cookie设置 +// +---------------------------------------------------------------------- +return [ + // cookie 名称前缀 + 'prefix' => '', + // cookie 保存时间 + 'expire' => 0, + // cookie 保存路径 + 'path' => '/', + // cookie 有效域名 + 'domain' => '', + // cookie 启用安全传输 + 'secure' => false, + // httponly设置 + 'httponly' => '', + // 是否使用 setcookie + 'setcookie' => true, +]; diff --git a/config/database.php b/config/database.php new file mode 100644 index 0000000000000000000000000000000000000000..3c6225786bbb0184832613e93db5fad634977d77 --- /dev/null +++ b/config/database.php @@ -0,0 +1,63 @@ + +// +---------------------------------------------------------------------- + +return [ + // 数据库类型 + 'type' => 'mysql', + // 服务器地址 + 'hostname' => '172.21.16.5', + // 数据库名 + 'database' => 'sgd', + // 用户名 + 'username' => 'sgd', + // 密码 + 'password' => 'Sgd_2020', + // 端口 + 'hostport' => '3306', + // 连接dsn + 'dsn' => '', + // 数据库连接参数 + 'params' => [], + // 数据库编码默认采用utf8 + 'charset' => 'utf8', + // 数据库表前缀 + 'prefix' => '', + // 数据库调试模式 + 'debug' => true, + // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) + 'deploy' => 0, + // 数据库读写是否分离 主从式有效 + 'rw_separate' => false, + // 读写分离后 主服务器数量 + 'master_num' => 1, + // 指定从服务器序号 + 'slave_no' => '', + // 自动读取主库数据 + 'read_master' => false, + // 是否严格检查字段是否存在 + 'fields_strict' => true, + // 数据集返回类型 + 'resultset_type' => 'array', + // 自动写入时间戳字段 + 'auto_timestamp' => false, + // 时间字段取出后的默认时间格式 + 'datetime_format' => 'Y-m-d H:i:s', + // 是否需要进行SQL性能分析 + 'sql_explain' => false, + // Builder类 + 'builder' => '', + // Query类 + 'query' => '\\think\\db\\Query', + // 是否需要断线重连 + 'break_reconnect' => false, + // 断线标识字符串 + 'break_match_str' => [], +]; diff --git a/config/face.php b/config/face.php new file mode 100644 index 0000000000000000000000000000000000000000..43f1ef1f1582db9be4f89754dd2b0ef5fee6c513 --- /dev/null +++ b/config/face.php @@ -0,0 +1,90 @@ + [ + [ + 'modelId' => 'qc_304220_450453_60', + 'url' => 'nurse_1.jpg' + ], + [ + 'modelId' => 'qc_304220_973822_59', + 'url' => 'nurse_2.jpg' + ], + [ + 'modelId' => 'qc_304220_343160_58', + 'url' => 'nurse_3.jpg' + ], + ], + 'police' => [ + [ + 'modelId' => 'qc_304220_631053_61', + 'url' => 'police_1.jpg' + ], + [ + 'modelId' => 'qc_304220_497090_62', + 'url' => 'police_2.jpg' + ], + [ + 'modelId' => 'qc_304220_921215_63', + 'url' => 'police_3.jpg' + ], + [ + 'modelId' => 'qc_304220_881107_64', + 'url' => 'police_4.jpg' + ], + ], + 'stew' => [ + [ + 'modelId' => 'qc_304220_235055_65', + 'url' => 'stew_1.jpg' + ], + [ + 'modelId' => 'qc_304220_399447_66', + 'url' => 'stew_2.jpg' + ], + [ + 'modelId' => 'qc_304220_829050_67', + 'url' => 'stew_3.jpg' + ], + [ + 'modelId' => 'qc_304220_654517_68', + 'url' => 'stew_4.jpg' + ], + [ + 'modelId' => 'qc_304220_169438_69', + 'url' => 'stew_5.jpg' + ], + [ + 'modelId' => 'qc_304220_786777_70', + 'url' => 'stew_6.jpg' + ], + [ + 'modelId' => 'qc_304220_882831_71', + 'url' => 'stew_7.jpg' + ], + [ + 'modelId' => 'qc_304220_630049_72', + 'url' => 'stew_8.jpg' + ] + ], + 'school' => [ + [ + 'modelId' => 'qc_304220_891187_73', + 'url' => 'school_1.jpg' + ] + ], + 'volunteer' => [ + [ + 'modelId' => 'qc_304220_309641_74', + 'url' => 'volunteer_1.jpg' + ], + [ + 'modelId' => 'qc_304220_718161_75', + 'url' => 'volunteer_2.jpg' + ] + ] + +]; diff --git a/config/log.php b/config/log.php new file mode 100644 index 0000000000000000000000000000000000000000..b3d87b4a9481401cb8724f313c170954e5de2ec9 --- /dev/null +++ b/config/log.php @@ -0,0 +1,30 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 日志设置 +// +---------------------------------------------------------------------- +return [ + // 日志记录方式,内置 file socket 支持扩展 + 'type' => 'File', + // 日志保存目录 + 'path' => '', + // 日志记录级别 + 'level' => [], + // 单文件日志写入 + 'single' => false, + // 独立日志级别 + 'apart_level' => [], + // 最大日志文件数量 + 'max_files' => 0, + // 是否关闭日志写入 + 'close' => false, +]; diff --git a/config/middleware.php b/config/middleware.php new file mode 100644 index 0000000000000000000000000000000000000000..fe15ec3d9400f6e00e919d3b2171c4a1c3aaa032 --- /dev/null +++ b/config/middleware.php @@ -0,0 +1,18 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 中间件配置 +// +---------------------------------------------------------------------- +return [ + // 默认中间件命名空间 + 'default_namespace' => 'app\\http\\middleware\\', +]; diff --git a/config/session.php b/config/session.php new file mode 100644 index 0000000000000000000000000000000000000000..1d7b6c60f5f47756901ddfd6cbbc272e27e690a0 --- /dev/null +++ b/config/session.php @@ -0,0 +1,26 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 会话设置 +// +---------------------------------------------------------------------- + +return [ + 'id' => '', + // SESSION_ID的提交变量,解决flash上传跨域 + 'var_session_id' => '', + // SESSION 前缀 + 'prefix' => 'think', + // 驱动方式 支持redis memcache memcached + 'type' => '', + // 是否自动开启 SESSION + 'auto_start' => true, +]; diff --git a/config/template.php b/config/template.php new file mode 100644 index 0000000000000000000000000000000000000000..299bd6f43e990055f30a4c2e0e6203edf2ceffe6 --- /dev/null +++ b/config/template.php @@ -0,0 +1,35 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 模板设置 +// +---------------------------------------------------------------------- + +return [ + // 模板引擎类型 支持 php think 支持扩展 + 'type' => 'Think', + // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法 + 'auto_rule' => 1, + // 模板路径 + 'view_path' => '', + // 模板后缀 + 'view_suffix' => 'html', + // 模板文件名分隔符 + 'view_depr' => DIRECTORY_SEPARATOR, + // 模板引擎普通标签开始标记 + 'tpl_begin' => '{', + // 模板引擎普通标签结束标记 + 'tpl_end' => '}', + // 标签库标签开始标记 + 'taglib_begin' => '{', + // 标签库标签结束标记 + 'taglib_end' => '}', +]; diff --git a/config/trace.php b/config/trace.php new file mode 100644 index 0000000000000000000000000000000000000000..425d30148dcdd4cf62c4ff78132637966ccacaea --- /dev/null +++ b/config/trace.php @@ -0,0 +1,18 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | Trace设置 开启 app_trace 后 有效 +// +---------------------------------------------------------------------- +return [ + // 内置Html Console 支持扩展 + 'type' => 'Html', +]; diff --git a/data/model/BaseModel.php b/data/model/BaseModel.php new file mode 100644 index 0000000000000000000000000000000000000000..e8d6198d3731485a81a42ea2737c513aa4728202 --- /dev/null +++ b/data/model/BaseModel.php @@ -0,0 +1,519 @@ +Validate = new Validate($this->rule, $this->msg); + $this->Validate->extend('no_html_parse', function ($value, $rule) { + return true; + }); + } + /** + * 获取空模型 + */ + public function getEModel($tables) + { + $rs = Db::query('show columns FROM `' . config('database.prefix') . $tables . "`"); + $obj = []; + if ($rs) { + foreach ($rs as $key => $v) { + $obj[$v['Field']] = $v['Default']; + if ($v['Key'] == 'PRI') { + $obj[$v['Field']] = 0; + } + + } + } + return $obj; + } + + /** + * 自动验证数据 + * @access protected + * @param array $data 验证数据 + * @param mixed $rule 验证规则 + * @param bool $batch 批量验证 + * @return bool + */ +// protected function validateData($data, $rule = null, $batch = null) + // { + // $info = is_null($rule) ? $this->Validate : $rule; + +// if (!empty($info)) { + // if (is_array($info)) { + // $validate = $this->Validate;// Loader::validate(); + // $validate->rule($info['rule']); + // $validate->message($info['msg']); + +// } else { + // $name = is_string($info) ? $info : $this->name; + // if (strpos($name, '.')) { + // list($name, $scene) = explode('.', $name); + // } + // $validate = $this->Validate;// Loader::validate($name); + // if (!empty($scene)) { + // $validate->scene($scene); + // } + // } + // $batch = is_null($batch) ? $this->batchValidate : $batch; + +// if (!$validate->batch($batch)->check($data)) { + // $this->error = $validate->getError(); + // if ($this->failException) { + // throw new ValidateException($this->error); + // } else { + // return false; + // } + // } + // $this->validate = null; + // } + // return true; + // } + + public function save($data = [], $where = [], $sequence = null) + { + $data = $this->htmlClear($data); + $retval = parent::save($data, $where, $sequence); + if (!empty($where)) { + //表示更新数据 + if ($retval == 0) { + if ($retval !== false) { + $retval = 1; + } + } + } +// $retval = ['code' => $code, 'message' => $this->getError()]; + return $retval; + } + + public function ihtmlspecialchars($string) + { + if (is_array($string)) { + foreach ($string as $key => $val) { + $string[$key] = $this->ihtmlspecialchars($val); + } + } else { + $string = preg_replace('/&((#(d{3,5}|x[a-fa-f0-9]{4})|[a-za-z][a-z0-9]{2,5});)/', '&\1', + str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string)); + } + return $string; + } + + protected function htmlClear($data) + { + $rule = $this->rule; + $info = empty($rule) ? $this->Validate : $rule; + foreach ($data as $k => $v) { + if (!empty($info)) { + if (is_array($info)) { + $is_Specialchars = $this->is_Specialchars($info, $k); + // 数据对象赋值 + if ($is_Specialchars) { + $data[$k] = $this->ihtmlspecialchars($v); + } else { + $data[$k] = $v; + } +// foreach ($rule as $key => $value) { + // if(strcasecmp($value,"no_html_parse")!= 0){ + // $data[$k] = $this->ihtmlspecialchars($v); + // }else{ + // $data[$k] = $v; + // } + // } + } else { + ; + } + } + } + return $data; + } + + /** + * 判断当前k 是否在数组的k值中 + * @param unknown $rule + * @param unknown $k + */ + protected function is_Specialchars($rule, $k) + { + $is_have = true; + foreach ($rule as $key => $value) { + if ($key == $k) { + if (strcasecmp($value, "no_html_parse") != 0) { + $is_have = true; + } else { + $is_have = false; + } + } + } + return $is_have; + } + + /** + * 数据库开启事务 + */ + public function startTrans() + { + Db::startTrans(); + } + + /** + * 数据库事务提交 + */ + public function commit() + { + Db::commit(); + } + + /** + * 数据库事务回滚 + */ + public function rollback() + { + Db::rollback(); + } + + /** + * 列表查询 + * + * @param unknown $page_index + * @param number $page_size + * @param string $order + * @param string $where + * @param string $field + */ + public function pageQuery($page_index, $page_size, $condition, $order, $field) + { + if (isset($condition['whereOr']) && is_array($condition['whereOr'])) { + $whereOr = $condition['whereOr']; + unset($condition['whereOr']); + } else { + $whereOr = false; + } + if ($whereOr) { + $count = $this->where($condition) + ->whereOr(function ($query) use ($whereOr) { + foreach ($whereOr as $whereKey => $whereValue) { + $query = $query->where($whereKey, $whereValue); + } + })->count(); + } else { + $count = $this->where($condition)->count(); + } + if ($page_size == 0) { + + if ($whereOr) { + $list = $this->field($field) + ->where($condition) + ->whereOr(function ($query) use ($whereOr) { + foreach ($whereOr as $whereKey => $whereValue) { + $query = $query->where($whereKey, $whereValue); + } + }) + ->order($order) + ->select(); + } else { + $list = $this->field($field) + ->where($condition) + ->order($order) + ->select(); + } + $page_count = 1; + } else { + $start_row = $page_size * ($page_index - 1); + if ($whereOr) { + $list = $this->field($field) + ->where($condition) + ->whereOr(function ($query) use ($whereOr) { + foreach ($whereOr as $whereKey => $whereValue) { + $query = $query->where($whereKey, $whereValue); + } + }) + ->order($order) + ->limit($start_row . "," . $page_size) + ->select(); + } else { + $list = $this->field($field) + ->where($condition) + ->order($order) + ->limit($start_row . "," . $page_size) + ->select(); + } + + if ($count % $page_size == 0) { + $page_count = $count / $page_size; + } else { + $page_count = (int) ($count / $page_size) + 1; + } + } + return array( + 'data' => $list, + 'total_count' => $count, + 'page_count' => $page_count, + ); + } + /** + * 获取一定条件下的列表 + * @param unknown $condition + * @param unknown $field + */ + public function getQueryLists($condition, $field, $order, $group = '',$offset=0,$limit=0) + { + $list = $this->field($field)->where($condition)->group($group)->limit($offset,$limit)->order($order)->select(); + return $list; + } + + /** + * 获取关联查询列表 + * + * @param unknown $viewObj + * 对应view对象 + * @param unknown $page_index + * @param unknown $page_size + * @param unknown $condition + * @param unknown $order + * @return multitype:number unknown + */ + public function viewPageQuery($viewObj, $page_index, $page_size, $condition, $order) + { + if ($page_size == 0) { + $list = $viewObj->where($condition) + ->order($order) + ->select(); + } else { + $start_row = $page_size * ($page_index - 1); + + $list = $viewObj->where($condition) + ->order($order) + ->limit($start_row . "," . $page_size) + ->select(); + } + return $list; + } + + /** + * 获取关联查询数量 + * + * @param unknown $viewObj + * 视图对象 + * @param unknown $condition + * 下旬条件 + * @return unknown + */ + public function viewCount($condition, $count = '*') + { + $count = Db::table($this->table)->where($condition)->count($count); + return $count; + } + + /** + * 设置关联查询返回数据格式 + * + * @param unknown $list + * 查询数据列表 + * @param unknown $count + * 查询数据数量 + * @param unknown $page_size + * 每页显示条数 + * @return multitype:unknown number + */ + public function setReturnList($list, $count, $page_size) + { + if ($page_size == 0) { + $page_count = 1; + } else { + if ($count % $page_size == 0) { + $page_count = $count / $page_size; + } else { + $page_count = (int) ($count / $page_size) + 1; + } + } + return array( + 'data' => $list, + 'total_count' => $count, + 'page_count' => $page_count, + ); + } + + /** + * 获取单条记录的基本信息 + * + * @param unknown $condition + * @param string $field + */ + public function getInfo($condition = '', $field = '*',$order = '') + { + + if($order){ + $info = Db::table($this->table)->where($condition) + ->field($field) + ->order($order) + ->find(); + }else{ + $info = Db::table($this->table)->where($condition) + ->field($field) + ->find(); + } + return $info; + } + /** + * 查询数据的数量 + * @param unknown $condition + * @return unknown + */ + public function getCount($condition, $field = '*') + { + $count = Db::table($this->table)->where($condition) + ->count($field); + return $count; + } + /** + * 查询条件数量 + * @param unknown $condition + * @param unknown $field + * @return number|unknown + */ + public function getSum($condition, $field) + { + $sum = Db::table($this->table)->where($condition) + ->sum($field); + if (empty($sum)) { + return 0; + } else { + return $sum; + } + + } + /** + * 查询数据最大值 + * @param unknown $condition + * @param unknown $field + * @return number|unknown + */ + public function getMax($condition, $field) + { + $max = Db::table($this->table)->where($condition) + ->max($field); + if (empty($max)) { + return 0; + } else { + return $max; + } + + } + /** + * 查询数据最小值 + * @param unknown $condition + * @param unknown $field + * @return number|unknown + */ + public function getMin($condition, $field) + { + $min = Db::table($this->table)->where($condition) + ->min($field); + if (empty($min)) { + return 0; + } else { + return $min; + } + + } + /** + * 查询数据均值 + * @param unknown $condition + * @param unknown $field + */ + public function getAvg($condition, $field) + { + $avg = Db::table($this->table)->where($condition) + ->avg($field); + if (empty($avg)) { + return 0; + } else { + return $avg; + } + + } + /** + * 查询第一条数据 + * @param unknown $condition + */ + public function getFirstData($condition, $order) + { + $data = Db::table($this->table)->where($condition)->order($order) + ->limit(1)->select(); + if (!empty($data)) { + return $data[0]; + } else { + return ''; + } + + } + /** + * 修改表单个字段值 + * @param unknown $pk_id + * @param unknown $field_name + * @param unknown $field_value + */ + public function ModifyTableField($pk_name, $pk_id, $field_name, $field_value) + { + $data = array( + $field_name => $field_value, + ); + $res = $this->save($data, [$pk_name => $pk_id]); + return $res; + } + + /** + * 原生SQL分页查询 + * + * @param string $sql + * @param number $page_index + * @param number $page_size + * @param return Array + */ + public function sqlPageQuery($sql, $page_index = 1, $page_size = 'all') + { + + $list = Db::query($sql); + $count = count($list); + + if ($page_size == 0) { + $page_count = 1; + } elseif ($page_size == 'all') { + //返回所有数据 + } else { + $start_row = $page_size * ($page_index - 1); + $sql = $sql . " Limit " . $start_row . "," . $page_size; + $list = Db::query($sql); + if ($count % $page_size == 0) { + $page_count = $count / $page_size; + } else { + $page_count = (int) ($count / $page_size) + 1; + } + } + + return array( + 'data' => $list, + 'total_count' => $count, + 'page_count' => $page_count, + ); + } +} diff --git a/data/model/CountModel.php b/data/model/CountModel.php new file mode 100644 index 0000000000000000000000000000000000000000..d33a54b92e99d086887262157eba442e6d1a4a7c --- /dev/null +++ b/data/model/CountModel.php @@ -0,0 +1,6 @@ + + Options +FollowSymlinks -Multiviews + RewriteEngine On + + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] + + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000000000000000000000000000000000000..22dc158365b3ff360bc146c5f51cae906f0d58f1 --- /dev/null +++ b/public/index.php @@ -0,0 +1,21 @@ + +// +---------------------------------------------------------------------- + +// [ 应用入口文件 ] +namespace think; + +// 加载基础文件 +require __DIR__ . '/../thinkphp/base.php'; + +// 支持事先使用静态方法设置Request对象和Config对象 + +// 执行应用并响应 +Container::get('app')->run()->send(); diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000000000000000000000000000000000000..eb0536286f3081c6c0646817037faf5446e3547d --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: diff --git a/public/router.php b/public/router.php new file mode 100644 index 0000000000000000000000000000000000000000..4f916b4079c4bcbe9ac64d04331cd2bc4cae6bfe --- /dev/null +++ b/public/router.php @@ -0,0 +1,17 @@ + +// +---------------------------------------------------------------------- +// $Id$ + +if (is_file($_SERVER["DOCUMENT_ROOT"] . $_SERVER["SCRIPT_NAME"])) { + return false; +} else { + require __DIR__ . "/index.php"; +} diff --git a/route/route.php b/route/route.php new file mode 100644 index 0000000000000000000000000000000000000000..fa0b1a3f8201423238859cbc9c898a9f2ae9ea99 --- /dev/null +++ b/route/route.php @@ -0,0 +1,24 @@ + +// +---------------------------------------------------------------------- + +//Route::miss('api/api/error'); +////一般路由规则,访问的url为:v1/address/1,对应的文件为Address类下的read方法 +//Route::get(':version/cgi-bin/get','api/:version.facefusion/test'); +//Route::post(':version/cgi-bin/facefusion/get','api/:version.facefusion/getcount'); +//Route::post(':version/cgi-bin/facefusion/save','api/:version.facefusion/savecount'); +//Route::post(':version/cgi-bin/facefusion/check','api/:version.facefusion/check'); +//Route::post(':version/cgi-bin/facefusion/testbase','api/:version.facefusion/testBase64'); +//Route::post(':version/cgi-bin/facefusion','api/:version.facefusion/index'); +//Route::get(':version/cgi-bin/facefusion/get','api/api/error'); +//Route::get(':version/cgi-bin/facefusion/save','api/api/error'); +//Route::get(':version/cgi-bin/facefusion','api/api/error'); + +//Route::post('facefusion','api/v1/facefusion/index'); diff --git a/runtime/.gitignore b/runtime/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..c96a04f008ee21e260b28f7701595ed59e2839e3 --- /dev/null +++ b/runtime/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/thinkphp/.gitignore b/thinkphp/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..f7775ba419fd23959b549ac5542de7a1d720f1e9 --- /dev/null +++ b/thinkphp/.gitignore @@ -0,0 +1,8 @@ +/vendor +composer.phar +composer.lock +.DS_Store +Thumbs.db +/phpunit.xml +/.idea +/.vscode \ No newline at end of file diff --git a/thinkphp/.htaccess b/thinkphp/.htaccess new file mode 100644 index 0000000000000000000000000000000000000000..3418e55a68383c1cbc687c52a2994d1e8ed83800 --- /dev/null +++ b/thinkphp/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/thinkphp/CONTRIBUTING.md b/thinkphp/CONTRIBUTING.md new file mode 100644 index 0000000000000000000000000000000000000000..6cefcb38cb2321eb2cd3f8c059bb873a4025a632 --- /dev/null +++ b/thinkphp/CONTRIBUTING.md @@ -0,0 +1,119 @@ +如何贡献我的源代码 +=== + +此文档介绍了 ThinkPHP 团队的组成以及运转机制,您提交的代码将给 ThinkPHP 项目带来什么好处,以及如何才能加入我们的行列。 + +## 通过 Github 贡献代码 + +ThinkPHP 目前使用 Git 来控制程序版本,如果你想为 ThinkPHP 贡献源代码,请先大致了解 Git 的使用方法。我们目前把项目托管在 GitHub 上,任何 GitHub 用户都可以向我们贡献代码。 + +参与的方式很简单,`fork`一份 ThinkPHP 的代码到你的仓库中,修改后提交,并向我们发起`pull request`申请,我们会及时对代码进行审查并处理你的申请并。审查通过后,你的代码将被`merge`进我们的仓库中,这样你就会自动出现在贡献者名单里了,非常方便。 + +我们希望你贡献的代码符合: + +* ThinkPHP 的编码规范 +* 适当的注释,能让其他人读懂 +* 遵循 Apache2 开源协议 + +**如果想要了解更多细节或有任何疑问,请继续阅读下面的内容** + +### 注意事项 + +* 本项目代码格式化标准选用 [**PSR-2**](http://www.kancloud.cn/thinkphp/php-fig-psr/3141); +* 类名和类文件名遵循 [**PSR-4**](http://www.kancloud.cn/thinkphp/php-fig-psr/3144); +* 对于 Issues 的处理,请使用诸如 `fix #xxx(Issue ID)` 的 commit title 直接关闭 issue。 +* 系统会自动在 PHP 5.4 5.5 5.6 7.0 和 HHVM 上测试修改,其中 HHVM 下的测试容许报错,请确保你的修改符合 PHP 5.4 ~ 5.6 和 PHP 7.0 的语法规范; +* 管理员不会合并造成 CI faild 的修改,若出现 CI faild 请检查自己的源代码或修改相应的[单元测试文件](tests); + +## GitHub Issue + +GitHub 提供了 Issue 功能,该功能可以用于: + +* 提出 bug +* 提出功能改进 +* 反馈使用体验 + +该功能不应该用于: + + * 提出修改意见(涉及代码署名和修订追溯问题) + * 不友善的言论 + +## 快速修改 + +**GitHub 提供了快速编辑文件的功能** + +1. 登录 GitHub 帐号; +2. 浏览项目文件,找到要进行修改的文件; +3. 点击右上角铅笔图标进行修改; +4. 填写 `Commit changes` 相关内容(Title 必填); +5. 提交修改,等待 CI 验证和管理员合并。 + +**若您需要一次提交大量修改,请继续阅读下面的内容** + +## 完整流程 + +1. `fork`本项目; +2. 克隆(`clone`)你 `fork` 的项目到本地; +3. 新建分支(`branch`)并检出(`checkout`)新分支; +4. 添加本项目到你的本地 git 仓库作为上游(`upstream`); +5. 进行修改,若你的修改包含方法或函数的增减,请记得修改[单元测试文件](tests); +6. 变基(衍合 `rebase`)你的分支到上游 master 分支; +7. `push` 你的本地仓库到 GitHub; +8. 提交 `pull request`; +9. 等待 CI 验证(若不通过则重复 5~7,GitHub 会自动更新你的 `pull request`); +10. 等待管理员处理,并及时 `rebase` 你的分支到上游 master 分支(若上游 master 分支有修改)。 + +*若有必要,可以 `git push -f` 强行推送 rebase 后的分支到自己的 `fork`* + +*绝对不可以使用 `git push -f` 强行推送修改到上游* + +### 注意事项 + +* 若对上述流程有任何不清楚的地方,请查阅 GIT 教程,如 [这个](http://backlogtool.com/git-guide/cn/); +* 对于代码**不同方面**的修改,请在自己 `fork` 的项目中**创建不同的分支**(原因参见`完整流程`第9条备注部分); +* 变基及交互式变基操作参见 [Git 交互式变基](http://pakchoi.me/2015/03/17/git-interactive-rebase/) + +## 推荐资源 + +### 开发环境 + +* XAMPP for Windows 5.5.x +* WampServer (for Windows) +* upupw Apache PHP5.4 ( for Windows) + +或自行安装 + +- Apache / Nginx +- PHP 5.4 ~ 5.6 +- MySQL / MariaDB + +*Windows 用户推荐添加 PHP bin 目录到 PATH,方便使用 composer* + +*Linux 用户自行配置环境, Mac 用户推荐使用内置 Apache 配合 Homebrew 安装 PHP 和 MariaDB* + +### 编辑器 + +Sublime Text 3 + phpfmt 插件 + +phpfmt 插件参数 + +```json +{ + "autocomplete": true, + "enable_auto_align": true, + "format_on_save": true, + "indent_with_space": true, + "psr1_naming": false, + "psr2": true, + "version": 4 +} +``` + +或其他 编辑器 / IDE 配合 PSR2 自动格式化工具 + +### Git GUI + +* SourceTree +* GitHub Desktop + +或其他 Git 图形界面客户端 diff --git a/thinkphp/LICENSE.txt b/thinkphp/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..574a39c401ff71ffcb90d15edb906b8046c7661b --- /dev/null +++ b/thinkphp/LICENSE.txt @@ -0,0 +1,32 @@ + +ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 +版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn) +All rights reserved。 +ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 + +Apache Licence是著名的非盈利开源组织Apache采用的协议。 +该协议和BSD类似,鼓励代码共享和尊重原作者的著作权, +允许代码修改,再作为开源或商业软件发布。需要满足 +的条件: +1. 需要给代码的用户一份Apache Licence ; +2. 如果你修改了代码,需要在被修改的文件中说明; +3. 在延伸的代码中(修改和有源代码衍生的代码中)需要 +带有原来代码中的协议,商标,专利声明和其他原来作者规 +定需要包含的说明; +4. 如果再发布的产品中包含一个Notice文件,则在Notice文 +件中需要带有本协议内容。你可以在Notice中增加自己的 +许可,但不可以表现为对Apache Licence构成更改。 +具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0 + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/thinkphp/README.md b/thinkphp/README.md new file mode 100644 index 0000000000000000000000000000000000000000..09b8b2ca7bee172c5d461c764b8cac9ad9112716 --- /dev/null +++ b/thinkphp/README.md @@ -0,0 +1,88 @@ + + +ThinkPHP 5.1 —— 12载初心,你值得信赖的PHP框架 +=============== + +[](https://travis-ci.org/top-think/framework) +[](https://packagist.org/packages/topthink/framework) +[](https://packagist.org/packages/topthink/framework) +[](https://packagist.org/packages/topthink/framework) + +ThinkPHP5.1对底层架构做了进一步的改进,减少依赖,其主要特性包括: + + + 采用容器统一管理对象 + + 支持Facade + + 更易用的路由 + + 注解路由支持 + + 路由跨域请求支持 + + 验证类增强 + + 配置和路由目录独立 + + 取消系统常量 + + 类库别名机制 + + 模型和数据库增强 + + 依赖注入完善 + + 支持PSR-3日志规范 + + 中间件支持(`V5.1.6+`) + + 支持`Swoole`/`Workerman`运行(`V5.1.18+`) + +### 废除的功能: + + + 聚合模型 + + 内置控制器扩展类 + + 模型自动验证 + +> ThinkPHP5.1的运行环境要求PHP5.6+。 + +## 安装 + +使用composer安装 + +~~~ +composer create-project topthink/think tp +~~~ + +启动服务 + +~~~ +cd tp +php think run +~~~ + +然后就可以在浏览器中访问 + +~~~ +http://localhost:8000 +~~~ + +更新框架 +~~~ +composer update topthink/framework +~~~ + + +## 在线手册 + ++ [完全开发手册](https://www.kancloud.cn/manual/thinkphp5_1/content) ++ [升级指导](https://www.kancloud.cn/manual/thinkphp5_1/354155) + +## 命名规范 + +`ThinkPHP5`遵循PSR-2命名规范和PSR-4自动加载规范。 + +## 参与开发 + +请参阅 [ThinkPHP5 核心框架包](https://github.com/top-think/framework)。 + +## 版权信息 + +ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 + +本项目包含的第三方源码和二进制文件之版权信息另行标注。 + +版权所有Copyright © 2006-2018 by ThinkPHP (http://thinkphp.cn) + +All rights reserved。 + +ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 + +更多细节参阅 [LICENSE.txt](LICENSE.txt) diff --git a/thinkphp/base.php b/thinkphp/base.php new file mode 100644 index 0000000000000000000000000000000000000000..084dd74dba3d99fdd6ed137d46762eb048eaf526 --- /dev/null +++ b/thinkphp/base.php @@ -0,0 +1,74 @@ + +// +---------------------------------------------------------------------- +namespace think; + +// 载入Loader类 +require __DIR__ . '/library/think/Loader.php'; + +// 注册自动加载 +Loader::register(); + +// 注册错误和异常处理机制 +Error::register(); + +// 实现日志接口 +if (interface_exists('Psr\Log\LoggerInterface')) { + interface LoggerInterface extends \Psr\Log\LoggerInterface + {} +} else { + interface LoggerInterface + {} +} + +// 注册核心类的静态代理 +Facade::bind([ + facade\App::class => App::class, + facade\Build::class => Build::class, + facade\Cache::class => Cache::class, + facade\Config::class => Config::class, + facade\Cookie::class => Cookie::class, + facade\Debug::class => Debug::class, + facade\Env::class => Env::class, + facade\Hook::class => Hook::class, + facade\Lang::class => Lang::class, + facade\Log::class => Log::class, + facade\Middleware::class => Middleware::class, + facade\Request::class => Request::class, + facade\Response::class => Response::class, + facade\Route::class => Route::class, + facade\Session::class => Session::class, + facade\Url::class => Url::class, + facade\Validate::class => Validate::class, + facade\View::class => View::class, +]); + +// 注册类库别名 +Loader::addClassAlias([ + 'App' => facade\App::class, + 'Build' => facade\Build::class, + 'Cache' => facade\Cache::class, + 'Config' => facade\Config::class, + 'Cookie' => facade\Cookie::class, + 'Db' => Db::class, + 'Debug' => facade\Debug::class, + 'Env' => facade\Env::class, + 'Facade' => Facade::class, + 'Hook' => facade\Hook::class, + 'Lang' => facade\Lang::class, + 'Log' => facade\Log::class, + 'Request' => facade\Request::class, + 'Response' => facade\Response::class, + 'Route' => facade\Route::class, + 'Session' => facade\Session::class, + 'Url' => facade\Url::class, + 'Validate' => facade\Validate::class, + 'View' => facade\View::class, +]); diff --git a/thinkphp/composer.json b/thinkphp/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..cc4fca9121543c469c53686b5c4d466e48afdf3f --- /dev/null +++ b/thinkphp/composer.json @@ -0,0 +1,35 @@ +{ + "name": "topthink/framework", + "description": "the new thinkphp framework", + "type": "think-framework", + "keywords": [ + "framework", + "thinkphp", + "ORM" + ], + "homepage": "http://thinkphp.cn/", + "license": "Apache-2.0", + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + }, + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "require": { + "php": ">=5.6.0", + "topthink/think-installer": "2.*" + }, + "require-dev": { + "phpunit/phpunit": "^5.0|^6.0", + "johnkary/phpunit-speedtrap": "^1.0", + "mikey179/vfsStream": "~1.6", + "phploc/phploc": "2.*", + "sebastian/phpcpd": "2.*", + "squizlabs/php_codesniffer": "2.*", + "phpdocumentor/reflection-docblock": "^2.0" + } +} diff --git a/thinkphp/convention.php b/thinkphp/convention.php new file mode 100644 index 0000000000000000000000000000000000000000..6675a57a9cc0f2c9fe40845a1b7f1173c8e97534 --- /dev/null +++ b/thinkphp/convention.php @@ -0,0 +1,324 @@ + [ + // 应用名称 + 'app_name' => '', + // 应用地址 + 'app_host' => '', + // 应用调试模式 + 'app_debug' => false, + // 应用Trace + 'app_trace' => false, + // 应用模式状态 + 'app_status' => '', + // 是否HTTPS + 'is_https' => false, + // 入口自动绑定模块 + 'auto_bind_module' => false, + // 注册的根命名空间 + 'root_namespace' => [], + // 默认输出类型 + 'default_return_type' => 'html', + // 默认AJAX 数据返回格式,可选json xml ... + 'default_ajax_return' => 'json', + // 默认JSONP格式返回的处理方法 + 'default_jsonp_handler' => 'jsonpReturn', + // 默认JSONP处理方法 + 'var_jsonp_handler' => 'callback', + // 默认时区 + 'default_timezone' => 'Asia/Shanghai', + // 是否开启多语言 + 'lang_switch_on' => false, + // 默认验证器 + 'default_validate' => '', + // 默认语言 + 'default_lang' => 'zh-cn', + + // +---------------------------------------------------------------------- + // | 模块设置 + // +---------------------------------------------------------------------- + + // 自动搜索控制器 + 'controller_auto_search' => false, + // 操作方法前缀 + 'use_action_prefix' => false, + // 操作方法后缀 + 'action_suffix' => '', + // 默认的空控制器名 + 'empty_controller' => 'Error', + // 默认的空模块名 + 'empty_module' => '', + // 默认模块名 + 'default_module' => 'index', + // 是否支持多模块 + 'app_multi_module' => true, + // 禁止访问模块 + 'deny_module_list' => ['common'], + // 默认控制器名 + 'default_controller' => 'Index', + // 默认操作名 + 'default_action' => 'index', + // 是否自动转换URL中的控制器和操作名 + 'url_convert' => true, + // 默认的访问控制器层 + 'url_controller_layer' => 'controller', + // 应用类库后缀 + 'class_suffix' => false, + // 控制器类后缀 + 'controller_suffix' => false, + + // +---------------------------------------------------------------------- + // | URL请求设置 + // +---------------------------------------------------------------------- + + // 默认全局过滤方法 用逗号分隔多个 + 'default_filter' => '', + // PATHINFO变量名 用于兼容模式 + 'var_pathinfo' => 's', + // 兼容PATH_INFO获取 + 'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'], + // HTTPS代理标识 + 'https_agent_name' => '', + // IP代理获取标识 + 'http_agent_ip' => 'HTTP_X_REAL_IP', + // URL伪静态后缀 + 'url_html_suffix' => 'html', + // 域名根,如thinkphp.cn + 'url_domain_root' => '', + // 表单请求类型伪装变量 + 'var_method' => '_method', + // 表单ajax伪装变量 + 'var_ajax' => '_ajax', + // 表单pjax伪装变量 + 'var_pjax' => '_pjax', + // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则 + 'request_cache' => false, + // 请求缓存有效期 + 'request_cache_expire' => null, + // 全局请求缓存排除规则 + 'request_cache_except' => [], + + // +---------------------------------------------------------------------- + // | 路由设置 + // +---------------------------------------------------------------------- + + // pathinfo分隔符 + 'pathinfo_depr' => '/', + // URL普通方式参数 用于自动生成 + 'url_common_param' => false, + // URL参数方式 0 按名称成对解析 1 按顺序解析 + 'url_param_type' => 0, + // 是否开启路由延迟解析 + 'url_lazy_route' => false, + // 是否强制使用路由 + 'url_route_must' => false, + // 合并路由规则 + 'route_rule_merge' => false, + // 路由是否完全匹配 + 'route_complete_match' => false, + // 使用注解路由 + 'route_annotation' => false, + // 默认的路由变量规则 + 'default_route_pattern' => '\w+', + // 是否开启路由缓存 + 'route_check_cache' => false, + // 路由缓存的Key自定义设置(闭包),默认为当前URL和请求类型的md5 + 'route_check_cache_key' => '', + + // +---------------------------------------------------------------------- + // | 异常及错误设置 + // +---------------------------------------------------------------------- + + // 默认跳转页面对应的模板文件 + 'dispatch_success_tmpl' => __DIR__ . '/tpl/dispatch_jump.tpl', + 'dispatch_error_tmpl' => __DIR__ . '/tpl/dispatch_jump.tpl', + // 异常页面的模板文件 + 'exception_tmpl' => __DIR__ . '/tpl/think_exception.tpl', + // 错误显示信息,非调试模式有效 + 'error_message' => '页面错误!请稍后再试~', + // 显示错误信息 + 'show_error_msg' => false, + // 异常处理handle类 留空使用 \think\exception\Handle + 'exception_handle' => '', + ], + + // +---------------------------------------------------------------------- + // | 模板设置 + // +---------------------------------------------------------------------- + + 'template' => [ + // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 + 'auto_rule' => 1, + // 模板引擎类型 支持 php think 支持扩展 + 'type' => 'Think', + // 视图基础目录,配置目录为所有模块的视图起始目录 + 'view_base' => '', + // 当前模板的视图目录 留空为自动获取 + 'view_path' => '', + // 模板后缀 + 'view_suffix' => 'html', + // 模板文件名分隔符 + 'view_depr' => DIRECTORY_SEPARATOR, + // 模板引擎普通标签开始标记 + 'tpl_begin' => '{', + // 模板引擎普通标签结束标记 + 'tpl_end' => '}', + // 标签库标签开始标记 + 'taglib_begin' => '{', + // 标签库标签结束标记 + 'taglib_end' => '}', + ], + + // +---------------------------------------------------------------------- + // | 日志设置 + // +---------------------------------------------------------------------- + + 'log' => [ + // 日志记录方式,内置 file socket 支持扩展 + 'type' => 'File', + // 日志保存目录 + //'path' => LOG_PATH, + // 日志记录级别 + 'level' => [], + // 是否记录trace信息到日志 + 'record_trace' => false, + // 是否JSON格式记录 + 'json' => false, + ], + + // +---------------------------------------------------------------------- + // | Trace设置 开启 app_trace 后 有效 + // +---------------------------------------------------------------------- + + 'trace' => [ + // 内置Html Console 支持扩展 + 'type' => 'Html', + 'file' => __DIR__ . '/tpl/page_trace.tpl', + ], + + // +---------------------------------------------------------------------- + // | 缓存设置 + // +---------------------------------------------------------------------- + + 'cache' => [ + // 驱动方式 + 'type' => 'File', + // 缓存保存目录 + //'path' => CACHE_PATH, + // 缓存前缀 + 'prefix' => '', + // 缓存有效期 0表示永久缓存 + 'expire' => 0, + ], + + // +---------------------------------------------------------------------- + // | 会话设置 + // +---------------------------------------------------------------------- + + 'session' => [ + 'id' => '', + // SESSION_ID的提交变量,解决flash上传跨域 + 'var_session_id' => '', + // SESSION 前缀 + 'prefix' => 'think', + // 驱动方式 支持redis memcache memcached + 'type' => '', + // 是否自动开启 SESSION + 'auto_start' => true, + 'httponly' => true, + 'secure' => false, + ], + + // +---------------------------------------------------------------------- + // | Cookie设置 + // +---------------------------------------------------------------------- + + 'cookie' => [ + // cookie 名称前缀 + 'prefix' => '', + // cookie 保存时间 + 'expire' => 0, + // cookie 保存路径 + 'path' => '/', + // cookie 有效域名 + 'domain' => '', + // cookie 启用安全传输 + 'secure' => false, + // httponly设置 + 'httponly' => '', + // 是否使用 setcookie + 'setcookie' => true, + ], + + // +---------------------------------------------------------------------- + // | 数据库设置 + // +---------------------------------------------------------------------- + + 'database' => [ + // 数据库类型 + 'type' => 'mysql', + // 数据库连接DSN配置 + 'dsn' => '', + // 服务器地址 + 'hostname' => '127.0.0.1', + // 数据库名 + 'database' => '', + // 数据库用户名 + 'username' => 'root', + // 数据库密码 + 'password' => '', + // 数据库连接端口 + 'hostport' => '', + // 数据库连接参数 + 'params' => [], + // 数据库编码默认采用utf8 + 'charset' => 'utf8', + // 数据库表前缀 + 'prefix' => '', + // 数据库调试模式 + 'debug' => false, + // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) + 'deploy' => 0, + // 数据库读写是否分离 主从式有效 + 'rw_separate' => false, + // 读写分离后 主服务器数量 + 'master_num' => 1, + // 指定从服务器序号 + 'slave_no' => '', + // 是否严格检查字段是否存在 + 'fields_strict' => true, + // 数据集返回类型 + 'resultset_type' => 'array', + // 自动写入时间戳字段 + 'auto_timestamp' => false, + // 时间字段取出后的默认时间格式 + 'datetime_format' => 'Y-m-d H:i:s', + // 是否需要进行SQL性能分析 + 'sql_explain' => false, + // 查询对象 + 'query' => '\\think\\db\\Query', + ], + + //分页配置 + 'paginate' => [ + 'type' => 'bootstrap', + 'var_page' => 'page', + 'list_rows' => 15, + ], + + //控制台配置 + 'console' => [ + 'name' => 'Think Console', + 'version' => '0.1', + 'user' => null, + ], + + // 中间件配置 + 'middleware' => [ + 'default_namespace' => 'app\\http\\middleware\\', + ], +]; diff --git a/thinkphp/helper.php b/thinkphp/helper.php new file mode 100644 index 0000000000000000000000000000000000000000..372357f1284fe44f7b1d1a3419dc852ae1122a85 --- /dev/null +++ b/thinkphp/helper.php @@ -0,0 +1,691 @@ + +// +---------------------------------------------------------------------- + +//------------------------ +// ThinkPHP 助手函数 +//------------------------- + +use think\Container; +use think\Db; +use think\exception\HttpException; +use think\exception\HttpResponseException; +use think\facade\Cache; +use think\facade\Config; +use think\facade\Cookie; +use think\facade\Debug; +use think\facade\Env; +use think\facade\Hook; +use think\facade\Lang; +use think\facade\Log; +use think\facade\Request; +use think\facade\Route; +use think\facade\Session; +use think\facade\Url; +use think\Response; +use think\route\RuleItem; + +if (!function_exists('abort')) { + /** + * 抛出HTTP异常 + * @param integer|Response $code 状态码 或者 Response对象实例 + * @param string $message 错误信息 + * @param array $header 参数 + */ + function abort($code, $message = null, $header = []) + { + if ($code instanceof Response) { + throw new HttpResponseException($code); + } else { + throw new HttpException($code, $message, null, $header); + } + } +} + +if (!function_exists('action')) { + /** + * 调用模块的操作方法 参数格式 [模块/控制器/]操作 + * @param string $url 调用地址 + * @param string|array $vars 调用参数 支持字符串和数组 + * @param string $layer 要调用的控制层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @return mixed + */ + function action($url, $vars = [], $layer = 'controller', $appendSuffix = false) + { + return app()->action($url, $vars, $layer, $appendSuffix); + } +} + +if (!function_exists('app')) { + /** + * 快速获取容器中的实例 支持依赖注入 + * @param string $name 类名或标识 默认获取当前应用实例 + * @param array $args 参数 + * @param bool $newInstance 是否每次创建新的实例 + * @return mixed|\think\App + */ + function app($name = 'think\App', $args = [], $newInstance = false) + { + return Container::get($name, $args, $newInstance); + } +} + +if (!function_exists('behavior')) { + /** + * 执行某个行为(run方法) 支持依赖注入 + * @param mixed $behavior 行为类名或者别名 + * @param mixed $args 参数 + * @return mixed + */ + function behavior($behavior, $args = null) + { + return Hook::exec($behavior, $args); + } +} + +if (!function_exists('bind')) { + /** + * 绑定一个类到容器 + * @access public + * @param string $abstract 类标识、接口 + * @param mixed $concrete 要绑定的类、闭包或者实例 + * @return Container + */ + function bind($abstract, $concrete = null) + { + return Container::getInstance()->bindTo($abstract, $concrete); + } +} + +if (!function_exists('cache')) { + /** + * 缓存管理 + * @param mixed $name 缓存名称,如果为数组表示进行缓存设置 + * @param mixed $value 缓存值 + * @param mixed $options 缓存参数 + * @param string $tag 缓存标签 + * @return mixed + */ + function cache($name, $value = '', $options = null, $tag = null) + { + if (is_array($options)) { + // 缓存操作的同时初始化 + Cache::connect($options); + } elseif (is_array($name)) { + // 缓存初始化 + return Cache::connect($name); + } + + if ('' === $value) { + // 获取缓存 + return 0 === strpos($name, '?') ? Cache::has(substr($name, 1)) : Cache::get($name); + } elseif (is_null($value)) { + // 删除缓存 + return Cache::rm($name); + } else { + // 缓存数据 + if (is_array($options)) { + $expire = isset($options['expire']) ? $options['expire'] : null; //修复查询缓存无法设置过期时间 + } else { + $expire = is_numeric($options) ? $options : null; //默认快捷缓存设置过期时间 + } + + if (is_null($tag)) { + return Cache::set($name, $value, $expire); + } else { + return Cache::tag($tag)->set($name, $value, $expire); + } + } + } +} + +if (!function_exists('call')) { + /** + * 调用反射执行callable 支持依赖注入 + * @param mixed $callable 支持闭包等callable写法 + * @param array $args 参数 + * @return mixed + */ + function call($callable, $args = []) + { + return Container::getInstance()->invoke($callable, $args); + } +} + +if (!function_exists('class_basename')) { + /** + * 获取类名(不包含命名空间) + * + * @param string|object $class + * @return string + */ + function class_basename($class) + { + $class = is_object($class) ? get_class($class) : $class; + return basename(str_replace('\\', '/', $class)); + } +} + +if (!function_exists('class_uses_recursive')) { + /** + *获取一个类里所有用到的trait,包括父类的 + * + * @param $class + * @return array + */ + function class_uses_recursive($class) + { + if (is_object($class)) { + $class = get_class($class); + } + + $results = []; + $classes = array_merge([$class => $class], class_parents($class)); + foreach ($classes as $class) { + $results += trait_uses_recursive($class); + } + + return array_unique($results); + } +} + +if (!function_exists('config')) { + /** + * 获取和设置配置参数 + * @param string|array $name 参数名 + * @param mixed $value 参数值 + * @return mixed + */ + function config($name = '', $value = null) + { + if (is_null($value) && is_string($name)) { + if ('.' == substr($name, -1)) { + return Config::pull(substr($name, 0, -1)); + } + + return 0 === strpos($name, '?') ? Config::has(substr($name, 1)) : Config::get($name); + } else { + return Config::set($name, $value); + } + } +} + +if (!function_exists('container')) { + /** + * 获取容器对象实例 + * @return Container + */ + function container() + { + return Container::getInstance(); + } +} + +if (!function_exists('controller')) { + /** + * 实例化控制器 格式:[模块/]控制器 + * @param string $name 资源地址 + * @param string $layer 控制层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @return \think\Controller + */ + function controller($name, $layer = 'controller', $appendSuffix = false) + { + return app()->controller($name, $layer, $appendSuffix); + } +} + +if (!function_exists('cookie')) { + /** + * Cookie管理 + * @param string|array $name cookie名称,如果为数组表示进行cookie设置 + * @param mixed $value cookie值 + * @param mixed $option 参数 + * @return mixed + */ + function cookie($name, $value = '', $option = null) + { + if (is_array($name)) { + // 初始化 + Cookie::init($name); + } elseif (is_null($name)) { + // 清除 + Cookie::clear($value); + } elseif ('' === $value) { + // 获取 + return 0 === strpos($name, '?') ? Cookie::has(substr($name, 1), $option) : Cookie::get($name); + } elseif (is_null($value)) { + // 删除 + return Cookie::delete($name); + } else { + // 设置 + return Cookie::set($name, $value, $option); + } + } +} + +if (!function_exists('db')) { + /** + * 实例化数据库类 + * @param string $name 操作的数据表名称(不含前缀) + * @param array|string $config 数据库配置参数 + * @param bool $force 是否强制重新连接 + * @return \think\db\Query + */ + function db($name = '', $config = [], $force = true) + { + return Db::connect($config, $force)->name($name); + } +} + +if (!function_exists('debug')) { + /** + * 记录时间(微秒)和内存使用情况 + * @param string $start 开始标签 + * @param string $end 结束标签 + * @param integer|string $dec 小数位 如果是m 表示统计内存占用 + * @return mixed + */ + function debug($start, $end = '', $dec = 6) + { + if ('' == $end) { + Debug::remark($start); + } else { + return 'm' == $dec ? Debug::getRangeMem($start, $end) : Debug::getRangeTime($start, $end, $dec); + } + } +} + +if (!function_exists('dump')) { + /** + * 浏览器友好的变量输出 + * @param mixed $var 变量 + * @param boolean $echo 是否输出 默认为true 如果为false 则返回输出字符串 + * @param string $label 标签 默认为空 + * @return void|string + */ + function dump($var, $echo = true, $label = null) + { + return Debug::dump($var, $echo, $label); + } +} + +if (!function_exists('env')) { + /** + * 获取环境变量值 + * @access public + * @param string $name 环境变量名(支持二级 .号分割) + * @param string $default 默认值 + * @return mixed + */ + function env($name = null, $default = null) + { + return Env::get($name, $default); + } +} + +if (!function_exists('exception')) { + /** + * 抛出异常处理 + * + * @param string $msg 异常消息 + * @param integer $code 异常代码 默认为0 + * @param string $exception 异常类 + * + * @throws Exception + */ + function exception($msg, $code = 0, $exception = '') + { + $e = $exception ?: '\think\Exception'; + throw new $e($msg, $code); + } +} + +if (!function_exists('halt')) { + /** + * 调试变量并且中断输出 + * @param mixed $var 调试变量或者信息 + */ + function halt($var) + { + dump($var); + + throw new HttpResponseException(new Response); + } +} + +if (!function_exists('input')) { + /** + * 获取输入数据 支持默认值和过滤 + * @param string $key 获取的变量名 + * @param mixed $default 默认值 + * @param string $filter 过滤方法 + * @return mixed + */ + function input($key = '', $default = null, $filter = '') + { + if (0 === strpos($key, '?')) { + $key = substr($key, 1); + $has = true; + } + + if ($pos = strpos($key, '.')) { + // 指定参数来源 + $method = substr($key, 0, $pos); + if (in_array($method, ['get', 'post', 'put', 'patch', 'delete', 'route', 'param', 'request', 'session', 'cookie', 'server', 'env', 'path', 'file'])) { + $key = substr($key, $pos + 1); + } else { + $method = 'param'; + } + } else { + // 默认为自动判断 + $method = 'param'; + } + + if (isset($has)) { + return request()->has($key, $method, $default); + } else { + return request()->$method($key, $default, $filter); + } + } +} + +if (!function_exists('json')) { + /** + * 获取\think\response\Json对象实例 + * @param mixed $data 返回的数据 + * @param integer $code 状态码 + * @param array $header 头部 + * @param array $options 参数 + * @return \think\response\Json + */ + function json($data = [], $code = 200, $header = [], $options = []) + { + return Response::create($data, 'json', $code, $header, $options); + } +} + +if (!function_exists('jsonp')) { + /** + * 获取\think\response\Jsonp对象实例 + * @param mixed $data 返回的数据 + * @param integer $code 状态码 + * @param array $header 头部 + * @param array $options 参数 + * @return \think\response\Jsonp + */ + function jsonp($data = [], $code = 200, $header = [], $options = []) + { + return Response::create($data, 'jsonp', $code, $header, $options); + } +} + +if (!function_exists('lang')) { + /** + * 获取语言变量值 + * @param string $name 语言变量名 + * @param array $vars 动态变量值 + * @param string $lang 语言 + * @return mixed + */ + function lang($name, $vars = [], $lang = '') + { + return Lang::get($name, $vars, $lang); + } +} + +if (!function_exists('model')) { + /** + * 实例化Model + * @param string $name Model名称 + * @param string $layer 业务层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @return \think\Model + */ + function model($name = '', $layer = 'model', $appendSuffix = false) + { + return app()->model($name, $layer, $appendSuffix); + } +} + +if (!function_exists('parse_name')) { + /** + * 字符串命名风格转换 + * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格 + * @param string $name 字符串 + * @param integer $type 转换类型 + * @param bool $ucfirst 首字母是否大写(驼峰规则) + * @return string + */ + function parse_name($name, $type = 0, $ucfirst = true) + { + if ($type) { + $name = preg_replace_callback('/_([a-zA-Z])/', function ($match) { + return strtoupper($match[1]); + }, $name); + + return $ucfirst ? ucfirst($name) : lcfirst($name); + } else { + return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_")); + } + } +} + +if (!function_exists('redirect')) { + /** + * 获取\think\response\Redirect对象实例 + * @param mixed $url 重定向地址 支持Url::build方法的地址 + * @param array|integer $params 额外参数 + * @param integer $code 状态码 + * @return \think\response\Redirect + */ + function redirect($url = [], $params = [], $code = 302) + { + if (is_integer($params)) { + $code = $params; + $params = []; + } + + return Response::create($url, 'redirect', $code)->params($params); + } +} + +if (!function_exists('request')) { + /** + * 获取当前Request对象实例 + * @return Request + */ + function request() + { + return app('request'); + } +} + +if (!function_exists('response')) { + /** + * 创建普通 Response 对象实例 + * @param mixed $data 输出数据 + * @param int|string $code 状态码 + * @param array $header 头信息 + * @param string $type + * @return Response + */ + function response($data = [], $code = 200, $header = [], $type = 'html') + { + return Response::create($data, $type, $code, $header); + } +} + +if (!function_exists('route')) { + /** + * 路由注册 + * @param string $rule 路由规则 + * @param mixed $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 + * @return RuleItem + */ + function route($rule, $route, $option = [], $pattern = []) + { + return Route::rule($rule, $route, '*', $option, $pattern); + } +} + +if (!function_exists('session')) { + /** + * Session管理 + * @param string|array $name session名称,如果为数组表示进行session设置 + * @param mixed $value session值 + * @param string $prefix 前缀 + * @return mixed + */ + function session($name, $value = '', $prefix = null) + { + if (is_array($name)) { + // 初始化 + Session::init($name); + } elseif (is_null($name)) { + // 清除 + Session::clear($value); + } elseif ('' === $value) { + // 判断或获取 + return 0 === strpos($name, '?') ? Session::has(substr($name, 1), $prefix) : Session::get($name, $prefix); + } elseif (is_null($value)) { + // 删除 + return Session::delete($name, $prefix); + } else { + // 设置 + return Session::set($name, $value, $prefix); + } + } +} + +if (!function_exists('token')) { + /** + * 生成表单令牌 + * @param string $name 令牌名称 + * @param mixed $type 令牌生成方法 + * @return string + */ + function token($name = '__token__', $type = 'md5') + { + $token = Request::token($name, $type); + + return ''; + } +} + +if (!function_exists('trace')) { + /** + * 记录日志信息 + * @param mixed $log log信息 支持字符串和数组 + * @param string $level 日志级别 + * @return array|void + */ + function trace($log = '[think]', $level = 'log') + { + if ('[think]' === $log) { + return Log::getLog(); + } else { + Log::record($log, $level); + } + } +} + +if (!function_exists('trait_uses_recursive')) { + /** + * 获取一个trait里所有引用到的trait + * + * @param string $trait + * @return array + */ + function trait_uses_recursive($trait) + { + $traits = class_uses($trait); + foreach ($traits as $trait) { + $traits += trait_uses_recursive($trait); + } + + return $traits; + } +} + +if (!function_exists('url')) { + /** + * Url生成 + * @param string $url 路由地址 + * @param string|array $vars 变量 + * @param bool|string $suffix 生成的URL后缀 + * @param bool|string $domain 域名 + * @return string + */ + function url($url = '', $vars = '', $suffix = true, $domain = false) + { + return Url::build($url, $vars, $suffix, $domain); + } +} + +if (!function_exists('validate')) { + /** + * 实例化验证器 + * @param string $name 验证器名称 + * @param string $layer 业务层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @return \think\Validate + */ + function validate($name = '', $layer = 'validate', $appendSuffix = false) + { + return app()->validate($name, $layer, $appendSuffix); + } +} + +if (!function_exists('view')) { + /** + * 渲染模板输出 + * @param string $template 模板文件 + * @param array $vars 模板变量 + * @param integer $code 状态码 + * @param callable $filter 内容过滤 + * @return \think\response\View + */ + function view($template = '', $vars = [], $code = 200, $filter = null) + { + return Response::create($template, 'view', $code)->assign($vars)->filter($filter); + } +} + +if (!function_exists('widget')) { + /** + * 渲染输出Widget + * @param string $name Widget名称 + * @param array $data 传入的参数 + * @return mixed + */ + function widget($name, $data = []) + { + return app()->action($name, $data, 'widget'); + } +} + +if (!function_exists('xml')) { + /** + * 获取\think\response\Xml对象实例 + * @param mixed $data 返回的数据 + * @param integer $code 状态码 + * @param array $header 头部 + * @param array $options 参数 + * @return \think\response\Xml + */ + function xml($data = [], $code = 200, $header = [], $options = []) + { + return Response::create($data, 'xml', $code, $header, $options); + } +} diff --git a/thinkphp/lang/zh-cn.php b/thinkphp/lang/zh-cn.php new file mode 100644 index 0000000000000000000000000000000000000000..d7c82f0c19a913c9e532de64a7a34faf6c5dc8c5 --- /dev/null +++ b/thinkphp/lang/zh-cn.php @@ -0,0 +1,142 @@ + +// +---------------------------------------------------------------------- + +// 核心中文语言包 +return [ + // 系统错误提示 + 'Undefined variable' => '未定义变量', + 'Undefined index' => '未定义数组索引', + 'Undefined offset' => '未定义数组下标', + 'Parse error' => '语法解析错误', + 'Type error' => '类型错误', + 'Fatal error' => '致命错误', + 'syntax error' => '语法错误', + + // 框架核心错误提示 + 'dispatch type not support' => '不支持的调度类型', + 'method param miss' => '方法参数错误', + 'method not exists' => '方法不存在', + 'function not exists' => '函数不存在', + 'module not exists' => '模块不存在', + 'controller not exists' => '控制器不存在', + 'class not exists' => '类不存在', + 'property not exists' => '类的属性不存在', + 'template not exists' => '模板文件不存在', + 'illegal controller name' => '非法的控制器名称', + 'illegal action name' => '非法的操作名称', + 'url suffix deny' => '禁止的URL后缀访问', + 'Route Not Found' => '当前访问路由未定义或不匹配', + 'Undefined db type' => '未定义数据库类型', + 'variable type error' => '变量类型错误', + 'PSR-4 error' => 'PSR-4 规范错误', + 'not support total' => '简洁模式下不能获取数据总数', + 'not support last' => '简洁模式下不能获取最后一页', + 'error session handler' => '错误的SESSION处理器类', + 'not allow php tag' => '模板不允许使用PHP语法', + 'not support' => '不支持', + 'redisd master' => 'Redisd 主服务器错误', + 'redisd slave' => 'Redisd 从服务器错误', + 'must run at sae' => '必须在SAE运行', + 'memcache init error' => '未开通Memcache服务,请在SAE管理平台初始化Memcache服务', + 'KVDB init error' => '没有初始化KVDB,请在SAE管理平台初始化KVDB服务', + 'fields not exists' => '数据表字段不存在', + 'where express error' => '查询表达式错误', + 'no data to update' => '没有任何数据需要更新', + 'miss data to insert' => '缺少需要写入的数据', + 'not support data' => '不支持的数据表达式', + 'miss complex primary data' => '缺少复合主键数据', + 'miss update condition' => '缺少更新条件', + 'model data Not Found' => '模型数据不存在', + 'table data not Found' => '表数据不存在', + 'delete without condition' => '没有条件不会执行删除操作', + 'miss relation data' => '缺少关联表数据', + 'tag attr must' => '模板标签属性必须', + 'tag error' => '模板标签错误', + 'cache write error' => '缓存写入失败', + 'sae mc write error' => 'SAE mc 写入错误', + 'route name not exists' => '路由标识不存在(或参数不够)', + 'invalid request' => '非法请求', + 'bind attr has exists' => '模型的属性已经存在', + 'relation data not exists' => '关联数据不存在', + 'relation not support' => '关联不支持', + 'chunk not support order' => 'Chunk不支持调用order方法', + 'route pattern error' => '路由变量规则定义错误', + 'route behavior will not support' => '路由行为废弃(使用中间件替代)', + 'closure not support cache(true)' => '使用闭包查询不支持cache(true),请指定缓存Key', + + // 上传错误信息 + 'unknown upload error' => '未知上传错误!', + 'file write error' => '文件写入失败!', + 'upload temp dir not found' => '找不到临时文件夹!', + 'no file to uploaded' => '没有文件被上传!', + 'only the portion of file is uploaded' => '文件只有部分被上传!', + 'upload File size exceeds the maximum value' => '上传文件大小超过了最大值!', + 'upload write error' => '文件上传保存错误!', + 'has the same filename: {:filename}' => '存在同名文件:{:filename}', + 'upload illegal files' => '非法上传文件', + 'illegal image files' => '非法图片文件', + 'extensions to upload is not allowed' => '上传文件后缀不允许', + 'mimetype to upload is not allowed' => '上传文件MIME类型不允许!', + 'filesize not match' => '上传文件大小不符!', + 'directory {:path} creation failed' => '目录 {:path} 创建失败!', + + 'The middleware must return Response instance' => '中间件方法必须返回Response对象实例', + 'The queue was exhausted, with no response returned' => '中间件队列为空', + // Validate Error Message + ':attribute require' => ':attribute不能为空', + ':attribute must' => ':attribute必须', + ':attribute must be numeric' => ':attribute必须是数字', + ':attribute must be integer' => ':attribute必须是整数', + ':attribute must be float' => ':attribute必须是浮点数', + ':attribute must be bool' => ':attribute必须是布尔值', + ':attribute not a valid email address' => ':attribute格式不符', + ':attribute not a valid mobile' => ':attribute格式不符', + ':attribute must be a array' => ':attribute必须是数组', + ':attribute must be yes,on or 1' => ':attribute必须是yes、on或者1', + ':attribute not a valid datetime' => ':attribute不是一个有效的日期或时间格式', + ':attribute not a valid file' => ':attribute不是有效的上传文件', + ':attribute not a valid image' => ':attribute不是有效的图像文件', + ':attribute must be alpha' => ':attribute只能是字母', + ':attribute must be alpha-numeric' => ':attribute只能是字母和数字', + ':attribute must be alpha-numeric, dash, underscore' => ':attribute只能是字母、数字和下划线_及破折号-', + ':attribute not a valid domain or ip' => ':attribute不是有效的域名或者IP', + ':attribute must be chinese' => ':attribute只能是汉字', + ':attribute must be chinese or alpha' => ':attribute只能是汉字、字母', + ':attribute must be chinese,alpha-numeric' => ':attribute只能是汉字、字母和数字', + ':attribute must be chinese,alpha-numeric,underscore, dash' => ':attribute只能是汉字、字母、数字和下划线_及破折号-', + ':attribute not a valid url' => ':attribute不是有效的URL地址', + ':attribute not a valid ip' => ':attribute不是有效的IP地址', + ':attribute must be dateFormat of :rule' => ':attribute必须使用日期格式 :rule', + ':attribute must be in :rule' => ':attribute必须在 :rule 范围内', + ':attribute be notin :rule' => ':attribute不能在 :rule 范围内', + ':attribute must between :1 - :2' => ':attribute只能在 :1 - :2 之间', + ':attribute not between :1 - :2' => ':attribute不能在 :1 - :2 之间', + 'size of :attribute must be :rule' => ':attribute长度不符合要求 :rule', + 'max size of :attribute must be :rule' => ':attribute长度不能超过 :rule', + 'min size of :attribute must be :rule' => ':attribute长度不能小于 :rule', + ':attribute cannot be less than :rule' => ':attribute日期不能小于 :rule', + ':attribute cannot exceed :rule' => ':attribute日期不能超过 :rule', + ':attribute not within :rule' => '不在有效期内 :rule', + 'access IP is not allowed' => '不允许的IP访问', + 'access IP denied' => '禁止的IP访问', + ':attribute out of accord with :2' => ':attribute和确认字段:2不一致', + ':attribute cannot be same with :2' => ':attribute和比较字段:2不能相同', + ':attribute must greater than or equal :rule' => ':attribute必须大于等于 :rule', + ':attribute must greater than :rule' => ':attribute必须大于 :rule', + ':attribute must less than or equal :rule' => ':attribute必须小于等于 :rule', + ':attribute must less than :rule' => ':attribute必须小于 :rule', + ':attribute must equal :rule' => ':attribute必须等于 :rule', + ':attribute has exists' => ':attribute已存在', + ':attribute not conform to the rules' => ':attribute不符合指定规则', + 'invalid Request method' => '无效的请求类型', + 'invalid token' => '令牌数据无效', + 'not conform to the rules' => '规则错误', +]; diff --git a/thinkphp/library/think/App.php b/thinkphp/library/think/App.php new file mode 100644 index 0000000000000000000000000000000000000000..235c4d856f734a846e0fac4844fd4321a0b02d8a --- /dev/null +++ b/thinkphp/library/think/App.php @@ -0,0 +1,971 @@ + +// +---------------------------------------------------------------------- + +namespace think; + +use think\exception\ClassNotFoundException; +use think\exception\HttpResponseException; +use think\route\Dispatch; + +/** + * App 应用管理 + */ +class App extends Container +{ + const VERSION = '5.1.19'; + + /** + * 当前模块路径 + * @var string + */ + protected $modulePath; + + /** + * 应用调试模式 + * @var bool + */ + protected $appDebug = true; + + /** + * 应用开始时间 + * @var float + */ + protected $beginTime; + + /** + * 应用内存初始占用 + * @var integer + */ + protected $beginMem; + + /** + * 应用类库命名空间 + * @var string + */ + protected $namespace = 'app'; + + /** + * 应用类库后缀 + * @var bool + */ + protected $suffix = false; + + /** + * 严格路由检测 + * @var bool + */ + protected $routeMust; + + /** + * 应用类库目录 + * @var string + */ + protected $appPath; + + /** + * 框架目录 + * @var string + */ + protected $thinkPath; + + /** + * 应用根目录 + * @var string + */ + protected $rootPath; + + /** + * 运行时目录 + * @var string + */ + protected $runtimePath; + + /** + * 配置目录 + * @var string + */ + protected $configPath; + + /** + * 路由目录 + * @var string + */ + protected $routePath; + + /** + * 配置后缀 + * @var string + */ + protected $configExt; + + /** + * 应用调度实例 + * @var Dispatch + */ + protected $dispatch; + + /** + * 绑定模块(控制器) + * @var string + */ + protected $bindModule; + + /** + * 初始化 + * @var bool + */ + protected $initialized = false; + + public function __construct($appPath = '') + { + $this->appPath = $appPath ? realpath($appPath) . DIRECTORY_SEPARATOR : $this->getAppPath(); + + $this->thinkPath = dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR; + $this->rootPath = dirname($this->appPath) . DIRECTORY_SEPARATOR; + $this->runtimePath = $this->rootPath . 'runtime' . DIRECTORY_SEPARATOR; + $this->routePath = $this->rootPath . 'route' . DIRECTORY_SEPARATOR; + $this->configPath = $this->rootPath . 'config' . DIRECTORY_SEPARATOR; + } + + /** + * 绑定模块或者控制器 + * @access public + * @param string $bind + * @return $this + */ + public function bind($bind) + { + $this->bindModule = $bind; + return $this; + } + + /** + * 设置应用类库目录 + * @access public + * @param string $path 路径 + * @return $this + */ + public function path($path) + { + $this->appPath = $path; + return $this; + } + + /** + * 初始化应用 + * @access public + * @return void + */ + public function initialize() + { + if ($this->initialized) { + return; + } + + $this->initialized = true; + $this->beginTime = microtime(true); + $this->beginMem = memory_get_usage(); + + static::setInstance($this); + + $this->instance('app', $this); + + // 加载惯例配置文件 + $this->config->set(include $this->thinkPath . 'convention.php'); + + // 设置路径环境变量 + $this->env->set([ + 'think_path' => $this->thinkPath, + 'root_path' => $this->rootPath, + 'app_path' => $this->appPath, + 'config_path' => $this->configPath, + 'route_path' => $this->routePath, + 'runtime_path' => $this->runtimePath, + 'extend_path' => $this->rootPath . 'extend' . DIRECTORY_SEPARATOR, + 'vendor_path' => $this->rootPath . 'vendor' . DIRECTORY_SEPARATOR, + ]); + + // 加载环境变量配置文件 + if (is_file($this->rootPath . '.env')) { + $this->env->load($this->rootPath . '.env'); + } + + $this->namespace = $this->env->get('app_namespace', $this->namespace); + $this->env->set('app_namespace', $this->namespace); + + // 注册应用命名空间 + Loader::addNamespace($this->namespace, $this->appPath); + + $this->configExt = $this->env->get('config_ext', '.php'); + + // 初始化应用 + $this->init(); + + // 开启类名后缀 + $this->suffix = $this->config('app.class_suffix'); + + // 应用调试模式 + $this->appDebug = $this->env->get('app_debug', $this->config('app.app_debug')); + $this->env->set('app_debug', $this->appDebug); + + if (!$this->appDebug) { + ini_set('display_errors', 'Off'); + } elseif (PHP_SAPI != 'cli') { + //重新申请一块比较大的buffer + if (ob_get_level() > 0) { + $output = ob_get_clean(); + } + ob_start(); + if (!empty($output)) { + echo $output; + } + } + + // 注册异常处理类 + if ($this->config('app.exception_handle')) { + Error::setExceptionHandler($this->config('app.exception_handle')); + } + + // 注册根命名空间 + if (!empty($this->config('app.root_namespace'))) { + Loader::addNamespace($this->config('app.root_namespace')); + } + + // 加载composer autofile文件 + Loader::loadComposerAutoloadFiles(); + + // 注册类库别名 + Loader::addClassAlias($this->config->pull('alias')); + + // 数据库配置初始化 + Db::init($this->config->pull('database')); + + // 设置系统时区 + date_default_timezone_set($this->config('app.default_timezone')); + + // 读取语言包 + $this->loadLangPack(); + + // 路由初始化 + $this->routeInit(); + } + + /** + * 初始化应用或模块 + * @access public + * @param string $module 模块名 + * @return void + */ + public function init($module = '') + { + // 定位模块目录 + $module = $module ? $module . DIRECTORY_SEPARATOR : ''; + $path = $this->appPath . $module; + + // 加载初始化文件 + if (is_file($path . 'init.php')) { + include $path . 'init.php'; + } elseif (is_file($this->runtimePath . $module . 'init.php')) { + include $this->runtimePath . $module . 'init.php'; + } else { + // 加载行为扩展文件 + if (is_file($path . 'tags.php')) { + $tags = include $path . 'tags.php'; + if (is_array($tags)) { + $this->hook->import($tags); + } + } + + // 加载公共文件 + if (is_file($path . 'common.php')) { + include_once $path . 'common.php'; + } + + if ('' == $module) { + // 加载系统助手函数 + include $this->thinkPath . 'helper.php'; + } + + // 加载中间件 + if (is_file($path . 'middleware.php')) { + $middleware = include $path . 'middleware.php'; + if (is_array($middleware)) { + $this->middleware->import($middleware); + } + } + + // 注册服务的容器对象实例 + if (is_file($path . 'provider.php')) { + $provider = include $path . 'provider.php'; + if (is_array($provider)) { + $this->bindTo($provider); + } + } + + // 自动读取配置文件 + if (is_dir($path . 'config')) { + $dir = $path . 'config'; + } elseif (is_dir($this->configPath . $module)) { + $dir = $this->configPath . $module; + } + + $files = isset($dir) ? scandir($dir) : []; + + foreach ($files as $file) { + if ('.' . pathinfo($file, PATHINFO_EXTENSION) === $this->configExt) { + $filename = $dir . DIRECTORY_SEPARATOR . $file; + $this->config->load($filename, pathinfo($file, PATHINFO_FILENAME)); + } + } + } + + $this->setModulePath($path); + + if ($module) { + // 对容器中的对象实例进行配置更新 + $this->containerConfigUpdate($module); + } + } + + protected function containerConfigUpdate($module) + { + $config = $this->config->get(); + + // 注册异常处理类 + if ($config['app']['exception_handle']) { + Error::setExceptionHandler($config['app']['exception_handle']); + } + + Db::init($config['database']); + $this->middleware->setConfig($config['middleware']); + $this->route->setConfig($config['app']); + $this->request->init($config['app']); + $this->cookie->init($config['cookie']); + $this->view->init($config['template']); + $this->log->init($config['log']); + $this->session->setConfig($config['session']); + $this->debug->setConfig($config['trace']); + $this->cache->init($config['cache'], true); + + // 加载当前模块语言包 + $this->lang->load($this->appPath . $module . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR . $this->request->langset() . '.php'); + + // 模块请求缓存检查 + $this->checkRequestCache( + $config['app']['request_cache'], + $config['app']['request_cache_expire'], + $config['app']['request_cache_except'] + ); + } + + /** + * 执行应用程序 + * @access public + * @return Response + * @throws Exception + */ + public function run() + { + try { + // 初始化应用 + $this->initialize(); + + // 监听app_init + $this->hook->listen('app_init'); + + if ($this->bindModule) { + // 模块/控制器绑定 + $this->route->bind($this->bindModule); + } elseif ($this->config('app.auto_bind_module')) { + // 入口自动绑定 + $name = pathinfo($this->request->baseFile(), PATHINFO_FILENAME); + if ($name && 'index' != $name && is_dir($this->appPath . $name)) { + $this->route->bind($name); + } + } + + // 监听app_dispatch + $this->hook->listen('app_dispatch'); + + $dispatch = $this->dispatch; + + if (empty($dispatch)) { + // 路由检测 + $dispatch = $this->routeCheck()->init(); + } + + // 记录当前调度信息 + $this->request->dispatch($dispatch); + + // 记录路由和请求信息 + if ($this->appDebug) { + $this->log('[ ROUTE ] ' . var_export($this->request->routeInfo(), true)); + $this->log('[ HEADER ] ' . var_export($this->request->header(), true)); + $this->log('[ PARAM ] ' . var_export($this->request->param(), true)); + } + + // 监听app_begin + $this->hook->listen('app_begin'); + + // 请求缓存检查 + $this->checkRequestCache( + $this->config('request_cache'), + $this->config('request_cache_expire'), + $this->config('request_cache_except') + ); + + $data = null; + } catch (HttpResponseException $exception) { + $dispatch = null; + $data = $exception->getResponse(); + } + + $this->middleware->add(function (Request $request, $next) use ($dispatch, $data) { + return is_null($data) ? $dispatch->run() : $data; + }); + + $response = $this->middleware->dispatch($this->request); + + // 监听app_end + $this->hook->listen('app_end', $response); + + return $response; + } + + protected function getRouteCacheKey() + { + if ($this->config->get('route_check_cache_key')) { + $closure = $this->config->get('route_check_cache_key'); + $routeKey = $closure($this->request); + } else { + $routeKey = md5($this->request->baseUrl(true) . ':' . $this->request->method()); + } + + return $routeKey; + } + + protected function loadLangPack() + { + // 读取默认语言 + $this->lang->range($this->config('app.default_lang')); + + if ($this->config('app.lang_switch_on')) { + // 开启多语言机制 检测当前语言 + $this->lang->detect(); + } + + $this->request->setLangset($this->lang->range()); + + // 加载系统语言包 + $this->lang->load([ + $this->thinkPath . 'lang' . DIRECTORY_SEPARATOR . $this->request->langset() . '.php', + $this->appPath . 'lang' . DIRECTORY_SEPARATOR . $this->request->langset() . '.php', + ]); + } + + /** + * 设置当前地址的请求缓存 + * @access public + * @param string $key 缓存标识,支持变量规则 ,例如 item/:name/:id + * @param mixed $expire 缓存有效期 + * @param array $except 缓存排除 + * @param string $tag 缓存标签 + * @return void + */ + public function checkRequestCache($key, $expire = null, $except = [], $tag = null) + { + $cache = $this->request->cache($key, $expire, $except, $tag); + + if ($cache) { + list($key, $expire, $tag) = $cache; + if (strtotime($this->request->server('HTTP_IF_MODIFIED_SINCE')) + $expire > $this->request->server('REQUEST_TIME')) { + // 读取缓存 + $response = Response::create()->code(304); + throw new HttpResponseException($response); + } elseif ($this->cache->has($key)) { + list($content, $header) = $this->cache->get($key); + + $response = Response::create($content)->header($header); + throw new HttpResponseException($response); + } + } + } + + /** + * 设置当前请求的调度信息 + * @access public + * @param Dispatch $dispatch 调度信息 + * @return $this + */ + public function dispatch(Dispatch $dispatch) + { + $this->dispatch = $dispatch; + return $this; + } + + /** + * 记录调试信息 + * @access public + * @param mixed $msg 调试信息 + * @param string $type 信息类型 + * @return void + */ + public function log($msg, $type = 'info') + { + $this->appDebug && $this->log->record($msg, $type); + } + + /** + * 获取配置参数 为空则获取所有配置 + * @access public + * @param string $name 配置参数名(支持二级配置 .号分割) + * @return mixed + */ + public function config($name = '') + { + return $this->config->get($name); + } + + /** + * 路由初始化 导入路由定义规则 + * @access public + * @return void + */ + public function routeInit() + { + // 路由检测 + $files = scandir($this->routePath); + foreach ($files as $file) { + if (strpos($file, '.php')) { + $filename = $this->routePath . $file; + // 导入路由配置 + $rules = include $filename; + if (is_array($rules)) { + $this->route->import($rules); + } + } + } + + if ($this->route->config('route_annotation')) { + // 自动生成路由定义 + if ($this->appDebug) { + $this->build->buildRoute($this->route->config('controller_suffix')); + } + + $filename = $this->runtimePath . 'build_route.php'; + + if (is_file($filename)) { + include $filename; + } + } + } + + /** + * URL路由检测(根据PATH_INFO) + * @access public + * @return Dispatch + */ + public function routeCheck() + { + // 检测路由缓存 + if (!$this->appDebug && $this->config->get('route_check_cache')) { + $routeKey = $this->getRouteCacheKey(); + $option = $this->config->get('route_cache_option') ?: $this->cache->getConfig(); + + if ($this->cache->connect($option)->has($routeKey)) { + return $this->cache->connect($option)->get($routeKey); + } + } + + // 获取应用调度信息 + $path = $this->request->path(); + + // 是否强制路由模式 + $must = !is_null($this->routeMust) ? $this->routeMust : $this->route->config('url_route_must'); + + // 路由检测 返回一个Dispatch对象 + $dispatch = $this->route->check($path, $must); + + if (!empty($routeKey)) { + try { + $this->cache + ->connect($option) + ->tag('route_cache') + ->set($routeKey, $dispatch); + } catch (\Exception $e) { + // 存在闭包的时候缓存无效 + } + } + + return $dispatch; + } + + /** + * 设置应用的路由检测机制 + * @access public + * @param bool $must 是否强制检测路由 + * @return $this + */ + public function routeMust($must = false) + { + $this->routeMust = $must; + return $this; + } + + /** + * 解析模块和类名 + * @access protected + * @param string $name 资源地址 + * @param string $layer 验证层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @return array + */ + protected function parseModuleAndClass($name, $layer, $appendSuffix) + { + if (false !== strpos($name, '\\')) { + $class = $name; + $module = $this->request->module(); + } else { + if (strpos($name, '/')) { + list($module, $name) = explode('/', $name, 2); + } else { + $module = $this->request->module(); + } + + $class = $this->parseClass($module, $layer, $name, $appendSuffix); + } + + return [$module, $class]; + } + + /** + * 实例化应用类库 + * @access public + * @param string $name 类名称 + * @param string $layer 业务层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @param string $common 公共模块名 + * @return object + * @throws ClassNotFoundException + */ + public function create($name, $layer, $appendSuffix = false, $common = 'common') + { + $guid = $name . $layer; + + if ($this->__isset($guid)) { + return $this->__get($guid); + } + + list($module, $class) = $this->parseModuleAndClass($name, $layer, $appendSuffix); + + if (class_exists($class)) { + $object = $this->__get($class); + } else { + $class = str_replace('\\' . $module . '\\', '\\' . $common . '\\', $class); + if (class_exists($class)) { + $object = $this->__get($class); + } else { + throw new ClassNotFoundException('class not exists:' . $class, $class); + } + } + + $this->__set($guid, $class); + + return $object; + } + + /** + * 实例化(分层)模型 + * @access public + * @param string $name Model名称 + * @param string $layer 业务层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @param string $common 公共模块名 + * @return Model + * @throws ClassNotFoundException + */ + public function model($name = '', $layer = 'model', $appendSuffix = false, $common = 'common') + { + return $this->create($name, $layer, $appendSuffix, $common); + } + + /** + * 实例化(分层)控制器 格式:[模块名/]控制器名 + * @access public + * @param string $name 资源地址 + * @param string $layer 控制层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @param string $empty 空控制器名称 + * @return object + * @throws ClassNotFoundException + */ + public function controller($name, $layer = 'controller', $appendSuffix = false, $empty = '') + { + list($module, $class) = $this->parseModuleAndClass($name, $layer, $appendSuffix); + + if (class_exists($class)) { + return $this->__get($class); + } elseif ($empty && class_exists($emptyClass = $this->parseClass($module, $layer, $empty, $appendSuffix))) { + return $this->__get($emptyClass); + } + + throw new ClassNotFoundException('class not exists:' . $class, $class); + } + + /** + * 实例化验证类 格式:[模块名/]验证器名 + * @access public + * @param string $name 资源地址 + * @param string $layer 验证层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @param string $common 公共模块名 + * @return Validate + * @throws ClassNotFoundException + */ + public function validate($name = '', $layer = 'validate', $appendSuffix = false, $common = 'common') + { + $name = $name ?: $this->config('default_validate'); + + if (empty($name)) { + return new Validate; + } + + return $this->create($name, $layer, $appendSuffix, $common); + } + + /** + * 数据库初始化 + * @access public + * @param mixed $config 数据库配置 + * @param bool|string $name 连接标识 true 强制重新连接 + * @return \think\db\Query + */ + public function db($config = [], $name = false) + { + return Db::connect($config, $name); + } + + /** + * 远程调用模块的操作方法 参数格式 [模块/控制器/]操作 + * @access public + * @param string $url 调用地址 + * @param string|array $vars 调用参数 支持字符串和数组 + * @param string $layer 要调用的控制层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @return mixed + * @throws ClassNotFoundException + */ + public function action($url, $vars = [], $layer = 'controller', $appendSuffix = false) + { + $info = pathinfo($url); + $action = $info['basename']; + $module = '.' != $info['dirname'] ? $info['dirname'] : $this->request->controller(); + $class = $this->controller($module, $layer, $appendSuffix); + + if (is_scalar($vars)) { + if (strpos($vars, '=')) { + parse_str($vars, $vars); + } else { + $vars = [$vars]; + } + } + + return $this->invokeMethod([$class, $action . $this->config('action_suffix')], $vars); + } + + /** + * 解析应用类的类名 + * @access public + * @param string $module 模块名 + * @param string $layer 层名 controller model ... + * @param string $name 类名 + * @param bool $appendSuffix + * @return string + */ + public function parseClass($module, $layer, $name, $appendSuffix = false) + { + $name = str_replace(['/', '.'], '\\', $name); + $array = explode('\\', $name); + $class = Loader::parseName(array_pop($array), 1) . ($this->suffix || $appendSuffix ? ucfirst($layer) : ''); + $path = $array ? implode('\\', $array) . '\\' : ''; + + return $this->namespace . '\\' . ($module ? $module . '\\' : '') . $layer . '\\' . $path . $class; + } + + /** + * 获取框架版本 + * @access public + * @return string + */ + public function version() + { + return static::VERSION; + } + + /** + * 是否为调试模式 + * @access public + * @return bool + */ + public function isDebug() + { + return $this->appDebug; + } + + /** + * 获取模块路径 + * @access public + * @return string + */ + public function getModulePath() + { + return $this->modulePath; + } + + /** + * 设置模块路径 + * @access public + * @param string $path 路径 + * @return void + */ + public function setModulePath($path) + { + $this->modulePath = $path; + $this->env->set('module_path', $path); + } + + /** + * 获取应用根目录 + * @access public + * @return string + */ + public function getRootPath() + { + return $this->rootPath; + } + + /** + * 获取应用类库目录 + * @access public + * @return string + */ + public function getAppPath() + { + if (is_null($this->appPath)) { + $this->appPath = Loader::getRootPath() . 'application' . DIRECTORY_SEPARATOR; + } + + return $this->appPath; + } + + /** + * 获取应用运行时目录 + * @access public + * @return string + */ + public function getRuntimePath() + { + return $this->runtimePath; + } + + /** + * 获取核心框架目录 + * @access public + * @return string + */ + public function getThinkPath() + { + return $this->thinkPath; + } + + /** + * 获取路由目录 + * @access public + * @return string + */ + public function getRoutePath() + { + return $this->routePath; + } + + /** + * 获取应用配置目录 + * @access public + * @return string + */ + public function getConfigPath() + { + return $this->configPath; + } + + /** + * 获取配置后缀 + * @access public + * @return string + */ + public function getConfigExt() + { + return $this->configExt; + } + + /** + * 获取应用类库命名空间 + * @access public + * @return string + */ + public function getNamespace() + { + return $this->namespace; + } + + /** + * 设置应用类库命名空间 + * @access public + * @param string $namespace 命名空间名称 + * @return $this + */ + public function setNamespace($namespace) + { + $this->namespace = $namespace; + return $this; + } + + /** + * 是否启用类库后缀 + * @access public + * @return bool + */ + public function getSuffix() + { + return $this->suffix; + } + + /** + * 获取应用开启时间 + * @access public + * @return float + */ + public function getBeginTime() + { + return $this->beginTime; + } + + /** + * 获取应用初始内存占用 + * @access public + * @return integer + */ + public function getBeginMem() + { + return $this->beginMem; + } + +} diff --git a/thinkphp/library/think/Build.php b/thinkphp/library/think/Build.php new file mode 100644 index 0000000000000000000000000000000000000000..f12c79093292754e54b45c66992d2f58bcc9eb28 --- /dev/null +++ b/thinkphp/library/think/Build.php @@ -0,0 +1,407 @@ + +// +---------------------------------------------------------------------- + +namespace think; + +class Build +{ + /** + * 应用对象 + * @var App + */ + protected $app; + + /** + * 应用目录 + * @var string + */ + protected $basePath; + + public function __construct(App $app) + { + $this->app = $app; + $this->basePath = $this->app->getAppPath(); + } + + /** + * 根据传入的build资料创建目录和文件 + * @access public + * @param array $build build列表 + * @param string $namespace 应用类库命名空间 + * @param bool $suffix 类库后缀 + * @return void + */ + public function run(array $build = [], $namespace = 'app', $suffix = false) + { + // 锁定 + $lockfile = $this->basePath . 'build.lock'; + + if (is_writable($lockfile)) { + return; + } elseif (!touch($lockfile)) { + throw new Exception('应用目录[' . $this->basePath . ']不可写,目录无法自动生成!
' . $label . $output . ''; + } + if ($echo) { + echo($output); + return; + } + return $output; + } + + public function inject(Response $response, &$content) + { + $config = $this->config; + $type = isset($config['type']) ? $config['type'] : 'Html'; + + unset($config['type']); + + $trace = Loader::factory($type, '\\think\\debug\\', $config); + + if ($response instanceof Redirect) { + //TODO 记录 + } else { + $output = $trace->output($response, $this->app['log']->getLog()); + if (is_string($output)) { + // trace调试信息注入 + $pos = strripos($content, '