PHP自动更新网站
2014年9月20日 · 331 字 · 2 分钟
目前软件开发主流越来越倾向于B/S模式,不同于C/S模式的软件,B/S模式下的WEB程序自动更新是个麻烦问题。
本人利用PHP下载远程文件和ZIP类,写了一个简单的自动更新DEMO,供大家参考。
服务端
目录结构
|data
|--20140918.zip
|--index.php
其中 data 文件夹用来存放补丁包,index.php 文件用来响应版本数据给客户端。
index.php
<?php
sleep(3);
header('Content-Type:application/json;utf-8');
echo json_encode(array(
'20140918' => array(
'version' => 20140920,
'desc' => 'BUG修正,缓存系统',
'url' => 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . '/data/20140918.zip'
)
));
exit();
20140918 对应的是客户端版本号,20140920 对应的是服务端版本号,desc 是本次补丁的描述,url 则是补丁包下载地址
客户端
目录结构
|tmp
|--config.php
|--Zip.php
|--index.php
config.php 为配置文件,保存本地版本信息,Zip.php 为ZIP操作类(从服务端下载的补丁包均为zip格式),index.php 为自动更新程序(只是为了方便,实际中可以写个方法出来)
index.php
<?php
ob_implicit_flush(true);
$begin = microtime(true);
//检查更新,加载本地版本号
$config = require(__DIR__ . '/config.php');
$server = 'http://localhost/version';
echo '连接更新服务器...<br/>';
ob_flush();
$versions = json_decode(file_get_contents($server), true);
if (!isset($versions[$config['version']])) {
echo '当前已是最新版本!';
} else {
echo '当前版本:<b>', $config['version'], '</b> 服务器版本:<b>',
$versions[$config['version']]['version'], '</b><br/>';
ob_flush();
//开始下载
$remote_fp = fopen($versions[$config['version']]['url'], 'rb');
if(!is_dir(__DIR__.'/tmp')) mkdir(__DIR__.'/tmp');
$tmp = __DIR__ . '/tmp/' . date('YmdHis') . '.zip';
$local_fp = fopen($tmp, 'wb');
echo '开始下载...<br/>';
ob_flush();
while (!feof($remote_fp)) {
fwrite($local_fp, fread($remote_fp, 128));
}
fclose($remote_fp);
fclose($local_fp);
echo '下载完成,准备解压<br/>';
ob_flush();
require(__DIR__ . '/Zip.php');
$zip = new Zip();
$zip->extra($tmp, __DIR__);
echo '解压完成,准备删除临时文件<br/>';
ob_flush();
//删除补丁包
unlink($tmp);
echo '临时文件删除完毕<br/>';
ob_flush();
//更新本地版本号
$content = file_get_contents(__DIR__.'/config.php');
$content = str_replace($config['version'],$versions[$config['version']]['version'],$content);
file_put_contents(__DIR__.'/config.php',$content);
echo '更新完成!耗时',microtime(true) - $begin,'秒<br/>';
ob_flush();
ob_end_clean();
exit();
}
config.php
<?php
return array(
'version' => '20140918'
);
Zip.php
<?php
/**
* @version 1.0
* @date 2014-08-11
* @author 十七号 <xialeistudio@gmail.com>
* @license MIT
* 压缩、解压缩类
*/
class Zip
{
/**
* 打包
* @param $path
* @param $save
*/
public static function archive($path, $save)
{
$zip = new ZipArchive();
if ($zip->open($save, ZipArchive::OVERWRITE) === true) {
self::addZip($path, $zip);
$zip->close();
}
}
/**
* 添加文件或文件夹到zip对象
* @param string $path
* @param ZipArchive $zip
*/
private static function addZip($path, $zip)
{
$handler = opendir($path);
while (($file = readdir($handler)) !== false) {
if ($file != '.' && $file != '..') {
if (is_dir($path . DIRECTORY_SEPARATOR . $file)) {
self::addZip($path . DIRECTORY_SEPARATOR . $file, $zip);
} else {
$zip->addFile($path . DIRECTORY_SEPARATOR . $file);
}
}
}
closedir($handler);
}
/**
* 解压文件
* @param string $file 压缩文件路径
* @param string $path 解压路径,为空则以文件名为路径
*/
public static function extra($file, $path = null)
{
if (!isset($path)) {
$array = explode('.', $file);
$path = reset($array);
}
$zip = new ZipArchive();
if ($zip->open($file) === true) {
$zip->extractTo($path);
$zip->close();
}
}
}
本文只写了一个很简单的自动更新程序,只是为了说明更新程序的基本思路。还有很多细节方面可以定制的。