💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 版本控制 简单理解就是更新系统。(迭代更新) 核心代码(SDK): ``` namespace Admin\Controller; use Think\Model; use Vendor\HttpDownload; use Common\Sdk; use Vendor\Zip; class UpdateController extends BaseController { public function __construct() { parent::__construct(); //$this->server = C('UPDATE_URL'); //$config = M('Websiteconfig')->find(); //$this->key = $config['serverkey']; //$this->domain = substr($_SERVER['HTTP_HOST'],strpos($_SERVER['HTTP_HOST'],'.')+1); } public function index() { $res = authUpdate(); $info = $res['data'][0]??''; $app_id = C('APP_ID'); $version = M('version')->order('id desc')->getField('version'); $post_string = array(); $header = array("Content-Type:multipart/x-www-form-urlencoded"); $url = 'http://auth.yzq88.com/index.php/api/index/getVersion?app_id='.$app_id.'&version='.$version; $ch = curl_init(); // 启动一个CURL会话 curl_setopt($ch, CURLOPT_URL, $url); // 要访问的地址 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查 // https请求 不验证证书和hosts curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在 curl_setopt($ch, CURLOPT_POST, true); // 发送一个常规的Post请求 curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string); // Post提交的数据包 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); // 设置超时限制防止死循环 curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 获取的信息以文件流的形式返回 curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //模拟的header头 $result = curl_exec($ch); $result = json_decode($result, true); if($result && $result['data']['version'] == $version){ $html = '<div id="uploading">当前已经是最新版本!当前版本号:'.$result['data']['version'].'</div>'; }else{ $html = "<div id='update'><p>更新说明:".$result['data']['remark']."</p><p>更新版本:".$result['data']['version']."</p><p id='upmsg'></p></div><div id='uploading'>检查到新版本 ".$result['data']['version'].",<a href='javascript:;' onclick=\"update('".$result['data']['package']."', '".$result['data']['version']."');\">立即升级</a></div>"; } if(!$result){ $html = '<div id="uploading">当前已经是最新版本!</div>'; } $this->assign('html',$html); $this->assign('nav', array('setting', 'update', ''));//导航 $this->display(); } public function updating() { set_time_limit(0); // $res = authDownload($v); $filepath = './Data/';//$res['data']['file']; $url = $_GET['url']; $v = $_GET['v']; $arr=parse_url($url); $fileName='update.zip';//basename($arr['path']); $file=file_get_contents($url); file_put_contents($filepath.$fileName,$file); if ($filepath) { if (!class_exists('ZipArchive')){ $this->ajaxReturn(['message'=>'您的服务器不支持php zip扩展,请配置好此扩展再来升级.']); } if (!is_writable($_SERVER['DOCUMENT_ROOT'].'/Application')){ $this->ajaxReturn(['message'=>'Application,设置好再升级']); } if (!is_writable($_SERVER['DOCUMENT_ROOT'].'/Public')){ $this->ajaxReturn(['message'=>'Public,设置好再升级']); } //升级包下载 // $filepath = $filename; // $filename = 'update.zip'; $locationZipPath= "./Runtime/update/"; //$locationZipPath=iconv('utf-8', 'gbk', $locationZipPath); if(!is_dir($locationZipPath)){ mkdir($locationZipPath); } $this->get_file($filepath,$fileName,$locationZipPath); $cacheUpdateDirName = './Runtime/update/caches_upgrade/'; if(!is_dir($cacheUpdateDirName)) { mkdir($cacheUpdateDirName); } $zip = new \ZipArchive(); $rs = $zip->open($filepath.$fileName); if($rs !== TRUE) { $this->ajaxReturn(array('message' =>'解压失败_2! Error Code:'. $rs.'!')); } $zip->extractTo($cacheUpdateDirName); $zip->close(); $this->recurse_copy($cacheUpdateDirName,getcwd()); //数据库升级 $sqlstatus = true; if (file_exists($cacheUpdateDirName.'update.sql')) { $sql = file_get_contents($cacheUpdateDirName.'/update.sql'); $sqldata = explode(";",$sql); $prefix = C('DB_PREFIX'); $Model = D('Updatelog'); foreach ($sqldata as $item){ if($item){ $sqlstatus = $Model->run($item); } } } // if (!$sqlstatus) { // $this->ajaxReturn(array('message' => '数据库升级失败!请手动导入update.sql文件执行数据库升级!')); // } //删除升级包 $this->deletedir($locationZipPath); @unlink(getcwd().'/update.sql'); //@unlink($locationZipPath); $data['version'] = $v; $data['save_time'] = date('Y-m-d'); M('version')->add($data); $this->ajaxReturn(['message'=>'恭喜,升级成功!']); } else { exit('2');//参数错误 } } private function getRoutefile($url,$recu=0){ if (!$url){ exit('空的url请求'.$recu); } if (function_exists('curl_init')){ $ch = curl_init(); $header = array('Accept-Charset: utf-8'); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //优化 curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)'); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_AUTOREFERER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 3); curl_setopt($ch, CURLOPT_NOSIGNAL, 1); $temp = curl_exec($ch); $headers = curl_getinfo($ch); $haderUrl = ''; if($headers['http_code'] == 302){ $haderUrl=$headers['redirect_url']; if (!$haderUrl){ $haderUrl=$headers['url']; } if (!$haderUrl){ echo 'header有空请求,请查看<br>'; var_export($headers); exit(); } $haderUrl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); return self::getRoutefile($haderUrl,1); } $errorno=curl_errno($ch); curl_close($ch); if ($errorno) { if ($errorno==3){ echo '请求地址是:'.$url.',或者'.$haderUrl.'<br>'; } exit(json_encode(array('message' => 'curl发生错误:错误代码'.$errorno.',如果错误代码是6,您的服务器可能无法连接我们升级服务器'),320)); }else { return $temp; } }else { $str=file_get_contents($url); return $str; } } private function recurse_copy($src,$dst) { // 原目录,复制到的目录 $now=time(); $dir = opendir($src); @mkdir($dst); while(false !== ( $file = readdir($dir)) ) { if (( $file != '.' ) && ( $file != '..' )) { if ( is_dir($src . '/' . $file) ) { self::recurse_copy($src . '/' . $file,$dst . '/' . $file); } else { if (file_exists($dst . DIRECTORY_SEPARATOR . $file)){ if (!is_writeable($dst . DIRECTORY_SEPARATOR . $file)){ exit(json_encode(['message' => $dst . DIRECTORY_SEPARATOR . $file.'不可写'],320)); } @unlink($dst . DIRECTORY_SEPARATOR . $file); } if (file_exists($dst . DIRECTORY_SEPARATOR . $file)){ @unlink($dst . DIRECTORY_SEPARATOR . $file); } $copyrt=copy($src . DIRECTORY_SEPARATOR . $file,$dst . DIRECTORY_SEPARATOR . $file); if (!$copyrt){ exit(json_encode(['message' => 'copy '.$dst . DIRECTORY_SEPARATOR . $file.' failed<br>'],320)); } } } } closedir($dir); } // private function deletedir($dirname){ public function deletedir($dirname){ // $result = false; // if(! is_dir($dirname)){ // echo " $dirname is not a dir!"; // exit(0); // } // $handle = opendir($dirname); //打开目录 // while(($file = readdir($handle)) !== false) { // if($file != '.' && $file != '..'){ //排除"."和"." // $dir = $dirname.DIRECTORY_SEPARATOR.$file; // //$dir是目录时递归调用deletedir,是文件则直接删除 // is_dir($dir) ? self::deletedir($dir) : unlink($dir); // } // } $dh=opendir($dirname); while ($file=readdir($dh)) { if($file!="." && $file!="..") { $fullpath=$dirname."/".$file; if(!is_dir($fullpath)) { unlink($fullpath); } else { $this->deletedir($fullpath); } } } } private function get_file($url,$name,$folder = './') { set_time_limit((24 * 60) * 60); // 设置超时时间 $destination_folder = $folder . '/'; // 文件下载保存目录,默认为当前文件目录 if (!is_dir($destination_folder)) { // 判断目录是否存在 $this->mkdirs($destination_folder); } $newfname = $destination_folder.$name; // 取得文件的名称 $file = fopen($url, 'rb'); // 远程下载文件,二进制模式 if ($file) { // 如果下载成功 $newf = fopen($newfname, 'wb'); // 远在文件文件 if ($newf) { // 如果文件保存成功 while (!feof($file)) { // 判断附件写入是否完整 fwrite($newf, fread($file, 1024 * 8), 1024 * 8); } } } if ($file) { fclose($file); } if ($newf) { fclose($newf); } return true; } private function mkdirs($path, $mode = '0777') { if (!is_dir($path)) { // 判断目录是否存在 self::mkdirs(dirname($path), $mode); // 循环建立目录 mkdir($path, $mode); } return true; } } ``` 由于需要具有一定的开发水平,我就不写那么保姆级别了,如果不会的话请直接联系我们 QQ:2236094129 wx:![](https://img.kancloud.cn/a1/9e/a19e5bfc4a2785066e6004fea0af8329_1284x2778.JPG)