文档章节

安装向导制作

山鹰sniper
 山鹰sniper
发布于 2014/09/12 15:34
字数 4985
阅读 852
收藏 8
基于PHP开发的网站系统安装向导详细图解(支持新浪SAE)...

序言

作为一名php开发工程师,肯定少不了自己开发web系统项目。如果项目是面向大众的,需要他人安装你的产品,不可缺少的就是需要弄个安装向导,这样才能让他们简单轻松的安装你的产品。如果你觉得没必要,觉得写个文档教程就可以,那我想说,你的产品是面向同行人...不过作为程序员,最终我们还是需要学习怎样开发出系统的安装向导,因为这不是有没有用的问题,而是学没学到的问题....

我们都知道,一般系统有没有安装都是通过判断系统中是否有某种文件,有则说明已安装,没有则未安装。而这个文件是安装完成后生成的,所以可以拿来判断。在这里我也是使用判断文件的方式来判断系统是否已安装。但这里有个问题,对于使用新浪SAE来说,由于不支持本地文件写操作,那我们就生成不了文件,这样判断文件是否存在就无效了。而这里的解决方法是将文件生成在新浪的storage,但这里又有个问题,就是生成的操作方式不一样,storage是新浪SAE为开发者提供的分布式文件存储服务,我们只能用它给出的类来生成文件,所以如果系统需要在新浪SAE上完成安装向导的话,则需要判断当前是哪中平台,然后根据不同平台调用不同的方法....

开始

目录结构

install --------------------------------->安装入口文件夹 
├ templates ------------------------->页面模板文件夹 
│ ├ images -------------------------->页面图片文件夹 
│ │ └ .... 
│ ├ js -------------------------------->页面js文件夹 
│ │ ├ jquery.js 
│ │ └ validate.js 
│ ├ css ------------------------------>页面css文件夹 
│ │ └ install.css 
│ ├ 0.php ---------------------------->获取新浪sae storage 页面 
│ ├ 1.php ---------------------------->安装许可协议页面 
│ ├ 2.php ---------------------------->运行环境检测页面 
│ ├ 3.php ---------------------------->安装参数设置页面 
│ ├ 4.php ---------------------------->安装详细过程页面 
│ ├ 5.php ---------------------------->安装完成页面 
│ ├ header.php --------------------->公共页面头部 
│ └ footer.php ---------------------->公共页面尾部 
├ config.ini.php --------------------->数据库配置文件模板 
├ config.php ------------------------>安装配置文件 
├ index.php ------------------------->系统安装入口 
├ location.php ---------------------->本地环境安装,非云平台 
├ main.php -------------------------->当数据写入到数据库后,进行添加管理员,生成配置文件等操作 
├ sae.php --------------------------->新浪sae平台 
├ db.sql ----------------------------->数据库文件 
└ license.txt ------------------------->协议文件

图结构

安装步骤图

install文件夹作为安装入口文件存放的地方,因为在安装完成后这个文件夹是可以删除的,所以在开发的时候,这部分需要独立出来,就是删除后不影响系统运行...

步骤

1、当进入安装时,首先运行index.php入口文件
2、然后获取配置信息config.php
1 //配置信息
2 $config = include './config.php';
3 if(empty($config)){
4     exit(get_tip_html('安装配置信息不存在,无法继续安装!'));
5 }

这里的配置信息的目的是:只需要修改这个文件就能兼容在其他系统上,而不需要修改太多的其他文件

01 return array(
02         /* ------系统------ */
03         //系统名称
04         'name'=>'赞博客,赞生活',
05         //系统版本
06         'version'=>'1.0',
07         //系统powered
08         'powered'=>'Powered by chenhaizan.com',
09         //系统脚部信息
10         'footerInfo'=> 'Copyright © 2012-2013 chenhaizan.cn Corporation',
11  
12         /* ------站点------ */
13         //数据库文件
14         'sqlFileName'=>'db.sql',
15         //生成数据库配置文件的模板
16         'dbSetFile'=>'config.ini.php',
17         //数据库名
18         'dbName' => 'myblog',
19         //数据库表前缀
20         'dbPrefix' => 'haizan_',
21         //站点名称
22         'siteName' => '我的博客',
23         //站点关键字
24         'siteKeywords' => '我的博客',
25         //站点描述
26         'siteDescription' => '我的博客',
27         //附件上传的目录
28         'uploaddir' => 'upload',
29         //需要读写权限的目录
30         'dirAccess' => array(
31             '/',
32             'config',
33             'upload',
34             'template',
35             'install',
36             'includes/uc_client/data',
37         ),
38         /* ------写入数据库完成后处理的文件------ */
39         'handleFile' => 'main.php',
40         /* ------安装验证/生成文件;非云平台安装有效------ */
41         'installFile' => '../config/install.lock',
42         'alreadyInstallInfo' => '你已经安装过该系统,如果想重新安装,请先删除站点config目录下的 install.lock 文件,然后再尝试安装!',
43     );
3、然后进行判断当前运行的平台,获取相应的平台文件
01 //安装环境验证,获取相应判断信息
02 if(function_exists('saeAutoLoader')){
03     //新浪SAE
04     define('INSTALLTYPE', 'SAE');
05     require './sae.php';
06 }elseif(isset($_SERVER['HTTP_BAE_ENV_APPID'])){
07     //百度BAE
08     define('INSTALLTYPE', 'BAE');
09     require './bae.php';
10 }else{
11     define('INSTALLTYPE', 'HOST');
12     //本地
13     require './localhost.php';
14 }

如当是本地环境时,加载location.php文件,我们在这个文件中进行是否安装判断等操作

1 //检测是否已经安装
2 if(file_exists($config['installFile'])){
3     exit(get_tip_html($config['alreadyInstallInfo']));
4 }
5  
6 //写入文件
7 function filewrite($file){
8     @touch($file);
9 }

当在SAE中,加载sae.php,进行获取storage domain操作,判断安装操作和一些服务是否开启

001 //设置storage的domain
002 if($_GET['step'] == 0){
003     if(empty($_POST['storagedomain'])){
004         $step_html = '<li class="current"><em>0</em>Storage设置</li>';
005         include './templates/0.php';
006         exit;
007     } else {
008         $_SESSION['STORAGEDOMAIN'] = $_POST['storagedomain'];
009         if(!empty($_SESSION['STORAGEDOMAIN'])){
010             header('location:./index.php?step=1');
011             exit();
012         }
013     }
014 }
015 if(!isset($_SESSION['STORAGEDOMAIN']) || empty($_SESSION['STORAGEDOMAIN'])){
016     header('location:./index.php?step=0');
017     exit;
018 }
019 $config['uploaddir'] = $_SESSION['STORAGEDOMAIN'];
020 define('SAESTOR_INSTALL_NAME', $_SESSION['STORAGEDOMAIN'].'/saestor_'. $_SERVER['HTTP_APPVERSION'] . '_install.lock');
021 $config['alreadySaeInstallInfo'] = "版本" . $_SERVER['HTTP_APPVERSION'] . "已完成安装!请删除网站根目录下的install目录!<br>如果需要重新安装,请先删除storage内的 saestor_" . $_SERVER['HTTP_APPVERSION'] . "_install.lock 文件";
022 if(fileExists(SAESTOR_INSTALL_NAME)){
023     exit(get_tip_html($config['alreadySaeInstallInfo']));
024 }
025 if(!is_storage){
026     exit(get_tip_html('请开启storage服务!'));
027 }
028 if(!is_mc){
029     exit(get_tip_html('请开启memcahce服务!'));
030 }
031 if(!is_mysql){
032     exit(get_tip_html('请开启mysql服务!'));
033 }
034 if(!is_kv){
035     exit(get_tip_html('请开启KV数据库服务!'));
036 }
037  
038 //SaeStorage
039 function SaeStorage(){
040     static $SaeStorage = array();
041     if(!isset($SaeStorage['SaeStorage'])){
042         $SaeStorage['SaeStorage'] = new SaeStorage();
043     }
044     return $SaeStorage['SaeStorage'];
045 }
046 //domain 路径
047 function file_getdomainfilepath($filename){
048     $arr=explode('/',ltrim($filename,'./'));
049     if($arr[count($arr)-1] == ''){
050         unset($arr[count($arr)-1]);
051     }
052     $domain=array_shift($arr);
053     $filePath=implode('/',$arr);
054     return array('domain'=>$domain,'filepath'=>$filePath);
055 }
056 //检查文件是否存在
057 function fileExists($filename){
058     $arr=file_getdomainfilepath($filename);
059     return SaeStorage()->fileExists($arr['domain'], $arr['filepath']);
060 }
061 //写入文件
062 function filewrite($file = ''){
063     $arr=file_getdomainfilepath(SAESTOR_INSTALL_NAME);
064     SaeStorage()->write($arr['domain'], $arr['filepath'],'1');
065 }
066  
067  
068 //判断是否开启storage
069 function is_storage() {
070     $s = new SaeStorage();
071     if (!$s->write(SAESTOR_NAME, 'is_storage', '1')) {
072         return FALSE;
073     } else {
074         return TRUE;
075     }
076 }
077 //判断是否开启memcahce
078 function is_mc() {
079     $mmc = @memcache_init();
080     if ($mmc) {
081         return TRUE;
082     } else {
083         return FALSE;
084     }
085 }
086 //判断是否开启mysql
087 function is_mysql() {
088     $mysql = @new SaeMysql();
089     $sql = "select database()";
090     $data = @$mysql->getData($sql);
091     if ($data) {
092         return TRUE;
093     } else {
094         return FALSE;
095     }
096 }
097 //判断是否开启KV数据库
098 function is_kv(){
099     $kv=new SaeKV();
100     if($kv->init()){
101         return TRUE;
102     } else {
103         return FALSE;
104     }
105 }
4、然后进行一些配置信息和满足条件的判断
01 //php版本
02 $phpversion = phpversion();
03 //php版本过低提示
04 if($phpversion < '5.2.0'){
05     exit(get_tip_html('您的php版本过低,不能安装本软件,请升级到5.2.0或更高版本再安装,谢谢!'));
06 }
07 //数据库文件
08 if(!file_exists('./'.$config['sqlFileName'])){
09     exit(get_tip_html('数据库文件不存在,无法继续安装!'));
10 }
11 //写入数据库完成后处理的文件
12 if (!file_exists('./'.$config['handleFile'])) {
13     exit(get_tip_html('处理文件不存在,无法继续安装!'));
14 }
5、进行安装流程步骤
1 $step = isset($_GET['step']) ? $_GET['step'] : 1;
2 //安装页面
3 switch ($step) {
4     case '1':
5     case '2':
6     case '3':
7     case '4':
8     case '5':
9 }

0)、设置stirage 当运行在sae上,首先我们需要得到storage的domain,因为需要判断storage中是否存生成的文件

20131008131218

所以需要页面跳转到0.php,进行domain设置

20131008131431

1)、安装许可协议

1 //安装许可协议
2 case '1':
3     $license = @file_get_contents('./license.txt');
4     include ("./templates/1.php");
5     break;

20131008132853

2)、运行环境检测

01 case '2':
02     $server = array(
03         //操作系统
04         'os' => php_uname(),
05         //PHP版本
06         'php' => $phpversion,
07     );
08     $error = 0;
09     //数据库
10     if (function_exists('mysql_connect')) {
11         $server['mysql'] = '<span class="correct_span">√</span> 已安装';
12     } else {
13         $server['mysql'] = '<span class="correct_span error_span">√</span> 出现错误';
14         $error++;
15     }
16     //上传限制
17     if (ini_get('file_uploads')) {
18         $server['uploadSize'] = '<span class="correct_span">√</span> ' . ini_get('upload_max_filesize');
19     } else {
20         $server['uploadSize'] = '<span class="correct_span error_span">√</span>禁止上传';
21     }
22     //session
23     if (function_exists('session_start')) {
24         $server['session'] = '<span class="correct_span">√</span> 支持';
25     } else {
26         $server['session'] = '<span class="correct_span error_span">√</span> 不支持';
27         $error++;
28      }
29     //需要读写权限的目录
30     $folder = $config['dirAccess'];
31     $install_path = str_replace('\\','/',getcwd()).'/';
32     $site_path = str_replace('install/', '', $install_path);
33     include ("./templates/2.php");
34     $_SESSION['INSTALLSTATUS'] = $error == 0?'SUCCESS':$error;
35     break;

检测环境需要记录错误,这里用session保存,如果有错误,将不能进行下一步的安装。在本地环境上

20131008133626

如果在sae上,因为sae已经禁止了本地文件操作,所以没必要检测读写判断,这里通过INSTALLTYPE判断进行隐藏

20131008132912

3)、安装参数设置

01 case '3':
02     //验证
03     verify(3);
04     //测试数据库链接
05     if (isset($_GET['testdbpwd'])) {
06         empty($_POST['dbhost'])?alert(0,'数据库服务器地址不能为空!','dbhost'):'';
07         empty($_POST['dbuser'])?alert(0,'数据库用户名不能为空!','dbuser'):'';
08         empty($_POST['dbname'])?alert(0,'数据库名不能为空!','dbname'):'';
09         empty($_POST['dbport'])?alert(0,'数据库端口不能为空!','dbport'):'';
10         $dbHost = $_POST['dbhost'] . ':' . $_POST['dbport'];
11         $conn = @mysql_connect($dbHost, $_POST['dbuser'], $_POST['dbpw']);
12         $conn?alert(1,'数据库链接成功!','dbpw'):alert(0,'数据库链接失败!','dbpw');
13     }
14     //域名+路径
15     $domain = empty($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'];
16     if ((int) $_SERVER['SERVER_PORT'] != 80) {
17         $domain .= ":" . $_SERVER['SERVER_PORT'];
18     }
19     $scriptName = !empty($_SERVER["REQUEST_URI"]) ? $scriptName = $_SERVER["REQUEST_URI"] : $scriptName = $_SERVER["PHP_SELF"];
20     $rootpath = @preg_replace("/\/(I|i)nstall\/index\.php(.*)$/", "", $scriptName);
21     $domain = $domain . $rootpath;
22     include ("./templates/3.php");
23     break;

在本地环境上

20131008133856

如果在sae上,因为sae已经将数据库的信息设置为常量,所以这里不需要给出数据库输入框,通过INSTALLTYPE判断进行隐藏页面的数据库输入部分,留出表前缀输入框

20131008132940

4)、安装详细过程 困难的部分就在这一步,涉及到数据库的写入。 
这里设计是提交得到配置信息后,跳转到数据库信息写入页面,因为需要在页面中动态显示创建表的信息,所以需要使用ajax来获取信息。验证数据库连接正确性后,将数据库文件提取出来,进行分割解析,得到数组,然后循环运行每条sql语句,同时判断当前语句是否为创建表,如果是创建表,执行这条语句后,返回ajax信息,带回当前数组key+1参数,前后接收后显示在页面,然后再发送ajax请求,带回key参数,循环到结束。

在发送请求时,也需要验证配置参数,这里将配置信息json在页面上

1 var data = <!--?php echo json_encode($_POST);?-->;

通过$_GET['install']判断ajax请求

完整js如下

01 var n=0;
02 var data = <!--?php echo json_encode($_POST);?-->;
03 $.ajaxSetup ({ cache: false });
04 function reloads(n) {
05     var url =  "./index.php?step=4&install=1&n="+n;
06         $.ajax({
07             type: "POST",      
08             url: url,
09             data: data,
10             dataType: 'json',
11             success: function(data){
12                 $('#loginner').append(data.info);
13                 if(data.status == 1){
14                     reloads(data.type);
15                 }
16                 if(data.status == 0){
17                     $('#installloading').removeClass('btn_old').addClass('btn').html('继续安装').unbind('click').click(function(){
18                         reloads(0);
19                     });
20                     alert('安装已停止!');
21                 }
22                 if(data.status == 2){
23                     $('#installloading').removeClass('btn_old').addClass('btn').attr('href','./index.php?step=5').html('安装完成...');
24                     setTimeout(function(){
25                         window.location.href='./index.php?step=5';
26                     },5000);
27                 }
28             }
29     });
30  }
31 $(function(){
32      reloads(n);
33 })

当在sae平台时,需要获取在sae上的数据库信息

01 if (!isset($_GET['install'])){
02     switch (INSTALLTYPE){
03         case 'SAE':
04             // 服务器地址
05             $_POST['dbhost'] = SAE_MYSQL_HOST_M;
06             // 端口
07             $_POST['dbport'] = SAE_MYSQL_PORT;
08             // 数据库名
09             $_POST['dbname'] = SAE_MYSQL_DB;
10             // 用户名
11             $_POST['dbuser'] = SAE_MYSQL_USER;
12             // 密码
13             $_POST['dbpw'] = SAE_MYSQL_PASS;
14             break;
15         case 'BAE':
16             // 服务器地址
17             $_POST['dbhost'] = HTTP_BAE_ENV_ADDR_SQL_IP;
18             // 端口
19             $_POST['dbport'] = HTTP_BAE_ENV_ADDR_SQL_PORT;
20             // 用户名
21             $_POST['dbuser'] = HTTP_BAE_ENV_SK;
22             // 密码
23             $_POST['dbpw'] = SAE_MYSQL_PASS;
24             break;
25     }
26 }
01 verify(4);
02 if (intval($_GET['install'])) {
03     dataVerify();
04     //关闭特殊字符提交处理到数据库
05     if($phpversion <= '5.3.0'){
06         set_magic_quotes_runtime(0);
07     }
08     //设置时区
09     date_default_timezone_set('PRC');
10     //当前进行的数据库操作
11     $n = intval($_GET['n']);
12     $arr = array();
13     //数据库服务器地址
14     $dbHost = trim($_POST['dbhost']);
15     //数据库端口
16     $dbPort = trim($_POST['dbport']);
17     //数据库名
18     $dbName = trim($_POST['dbname']);
19     $dbHost = empty($dbPort) || $dbPort == 3306 ? $dbHost : $dbHost . ':' . $dbPort;
20     //数据库用户名
21     $dbUser = trim($_POST['dbuser']);
22     //数据库密码
23     $dbPwd = trim($_POST['dbpw']);
24     //表前缀
25     $dbPrefix = empty($_POST['dbprefix']) ? 'db_' : trim($_POST['dbprefix']);
26     //链接数据库
27     $c @ mysql_connect($dbHost, $dbUser, $dbPwd);
28     if (!$conn) {
29         alert(0,'连接数据库失败!');
30     }
31     //设置数据库编码
32     mysql_query("SET NAMES 'utf8'"); //,character_set_client=binary,sql_mode='';
33     //获取数据库版本信息
34     $version = mysql_get_server_info($conn);
35     if ($version < 4.1) {
36         alert(0,'连接数版本太低!');
37     }
38     //选择数据库
39     if (!mysql_select_db($dbName, $conn)) {
40         //创建数据时同时设置编码
41         if (!mysql_query("CREATE DATABASE IF NOT EXISTS `" . $dbName . "` DEFAULT CHARACTER SET utf8;", $conn)) {
42             alert(0,'<li><span class="correct_span error_span">√</span>数据库 ' . $dbName . ' 不存在,也没权限创建新的数据库!<span style="float: right;">'.date('Y-m-d H:i:s').'</span></li>');
43         } else {
44             alert(1,"<li><span class="correct_span">√</span>成功创建数据库:{$dbName}<span style="float: right;" '="">".date('Y-m-d H:i:s')."</span></li>",0);
45         }
46     }
47  
48     //读取数据文件
49     $sqldata = file_get_contents('./'.$config['sqlFileName']);
50     if(empty($sqldata)){
51         alert(0,'数据库文件不能为空!');
52     }
53     $sqlFormat = sql_split($sqldata, $dbPrefix,$config['dbPrefix']);
54  
55  
56     /**
57      * 执行SQL语句
58      */
59     $counts = count($sqlFormat);
60  
61     for ($i = $n; $i < $counts; $i++) {
62         $sql = trim($sqlFormat[$i]);
63         if (strstr($sql, 'CREATE TABLE')) {
64             //创建表
65             preg_match('/CREATE TABLE `([^ ]*)`/', $sql, $matches);
66             if(empty($matches)){
67                 preg_match('/CREATE TABLE IF NOT EXISTS `([^ ]*)`/', $sql, $matches);
68             }
69             if(!empty($matches[1])){
70                 mysql_query("DROP TABLE IF EXISTS `$matches[1]",$conn);
71                 $ret = mysql_query($sql,$conn);
72                 $i++;
73                 if(mysql_query($sql,$conn)){
74                     $info = '<li><span class="correct_span">√</span>创建数据表' . $matches[1] . ',完成!<span style="float: right;">'.date('Y-m-d H:i:s').'</span></li> ';
75                     alert(1,$info,$i);
76                 } else {
77                     $info = '<li><span class="correct_span error_span">√</span>创建数据表' . $matches[1] . ',失败,安装停止!<span style="float: right;">'.date('Y-m-d H:i:s').'</span></li>';
78                     alert(0,$info,$i);
79                 }
80             }
81         } else {
82             //插入数据
83             $ret = mysql_query($sql);
84         }
85     }
86  
87     //处理
88     $data = include './'.$config['handleFile'];
89     $_SESSION['INSTALLOK'] = $data['status']?1:0;
90     alert($data['status'],$data['info']);
91 }
92 include ("./templates/4.php");
93 break;

20131008133924

写入成功后,需要进行添加管理员,生成配置文件等操作,如上面代码中的

1 //处理
2 $data = include './'.$config['handleFile'];
3 $_SESSION['INSTALLOK'] = $data['status']?1:0;

在配置文件中$config['handleFile']为main.php

01 $username = trim($_POST['manager']);
02 $password = trim($_POST['manager_pwd']);
03 //网站名称
04 $site_name = addslashes(trim($_POST['sitename']));
05 //网站域名
06 $site_url = trim($_POST['siteurl']);
07 //附件目录
08 $upload_path = $_SESSION['UPLOADPATH'];
09 //描述
10 $seo_description = trim($_POST['sitedescription']);
11 //关键词
12 $seo_keywords = trim($_POST['sitekeywords']);
13 //更新配置信息
14 mysql_query("UPDATE `{$dbPrefix}config` SET  `value` = '$site_name' WHERE varname='site_name'");
15 mysql_query("UPDATE `{$dbPrefix}config` SET  `value` = '$site_url' WHERE varname='site_domain' ");
16 mysql_query("UPDATE `{$dbPrefix}config` SET  `value` = '$seo_description' WHERE varname='site_description'");
17 mysql_query("UPDATE `{$dbPrefix}config` SET  `value` = '$seo_keywords' WHERE varname='site_keywords'");
18  
19 if(!empty($upload_path)){
20     mysql_query("UPDATE `{$dbPrefix}config` SET  `value` = '$upload_path' WHERE varname='attach_storage_domain' ");
21 }
22 if(INSTALLTYPE == 'HOST'){
23     //读取配置文件,并替换真实配置数据
24     $strConfig = file_get_contents('./' . $config['dbSetFile']);
25     $strConfig = str_replace('#DB_HOST#', $dbHost, $strConfig);
26     $strConfig = str_replace('#DB_NAME#', $dbName, $strConfig);
27     $strConfig = str_replace('#DB_USER#', $dbUser, $strConfig);
28     $strConfig = str_replace('#DB_PWD#', $dbPwd, $strConfig);
29     $strConfig = str_replace('#DB_PORT#', $dbPort, $strConfig);
30     $strConfig = str_replace('#DB_PREFIX#', $dbPrefix, $strConfig);
31     $strConfig = str_replace('#AUTHCODE#', genRandomString(18), $strConfig);
32     $strConfig = str_replace('#COOKIE_PREFIX#', genRandomString(6) . "_", $strConfig);
33     $strConfig = str_replace('#DATA_CACHE_PREFIX#', genRandomString(6) . "_", $strConfig);
34     $strConfig = str_replace('#SESSION_PREFIX#', genRandomString(6) . "_", $strConfig);
35     @file_put_contents($config['dbConfig'], $strConfig);
36 }
37  
38 //插入管理员
39 //生成随机认证码
40 $verify = genRandomString(6);
41 $time = time();
42 $ip = get_client_ip();
43 $password = md5($password . md5($verify));
44 $email = trim($_POST['manager_email']);
45 $query = "INSERT INTO `{$dbPrefix}member` VALUES (1, 0, 0, '{$username}', '{$password}', '{$email}', '', '', 0, '', '', '{$verify}', 1, '{$time}', 0, 0, 1, 2, 1, '', 65535, 1, 1, 1, 1, 0, '')";
46 if(mysql_query($query)){
47     return array('status'=>2,'info'=>'成功添加管理员<br>成功写入配置文件<br>安装完成...');
48 }
49 return array('status'=>0,'info'=>'安装失败...');

如果在本地环境,将数据库配置模板文件进行特定位置替换,生成配置文件到设置的$config['dbConfig'] (../config/config.ini.php)中

5)、安装完成

1 case '5':
2     verify(5);
3         include ("./templates/5.php");
4         //安装完成,生成.lock文件
5         if(isset($_SESSION['INSTALLOK']) && $_SESSION['INSTALLOK'] == 1){
6             filewrite($config['installFile']);
7         }
8         unset($_SESSION);
9         break;

20131008133939

在这一步生成.lock文件

安装完成后再次运行时,出现提示信息

20131008134243

20131008133053

其他一些函数

001 /**
002  * 错误提示html
003  */
004 function get_tip_html($info){
005     return '<div style="border: 2px solid #69c; background:#f1f1f1; padding:20px;margin:20px;width:800px;font-weight:bold;color: #69c;text-align:center;margin-left: auto;margin-right: auto;border-radius: 5px;"><h1>'.$info.'</h1></div>';
006 }
007 //返回提示信息
008 function alert($status,$info,$type = 0){
009     exit(json_encode(array('status'=>$status,'info'=>$info,'type'=>$type)));
010 }
011 function verify($step = 3){
012     if($step >= 3){
013         //未运行环境检测,跳转到安装许可协议页面
014         if(!isset($_SESSION['INSTALLSTATUS'])){
015             header('location:./index.php');
016             exit();
017         }
018         //运行环境检测存在错误,返回运行环境检测
019         if($_SESSION['INSTALLSTATUS'] != 'SUCCESS'){
020             header('location:./index.php?step=2');
021             exit();
022         }
023     }
024     if($step == 4){
025         //未提交数据
026         if(empty($_POST)){
027             header('location:./index.php?step=3');
028             exit();
029         }
030     }
031     if($step >= 5){
032         //数据库未写入完成
033         if(!isset($_SESSION['INSTALLOK'])){
034             header('location:./index.php?step=4');
035             exit();
036         }
037     }
038 }
039 function dataVerify(){
040     empty($_POST['dbhost'])?alert(0,'数据库服务器不能为空!'):'';
041     empty($_POST['dbport'])?alert(0,'数据库端口不能为空!'):'';
042     empty($_POST['dbuser'])?alert(0,'数据库用户名不能为空!'):'';
043     empty($_POST['dbname'])?alert(0,'数据库名不能为空!'):'';
044     empty($_POST['dbprefix'])?alert(0,'数据库表前缀不能为空!'):'';
045     empty($_POST['siteurl'])?alert(0,'网站域名不能为空!'):'';
046     empty($_POST['uploaddir'])?alert(0,'附件上传的目录不能为空!'):'';
047     empty($_POST['manager'])?alert(0,'管理员帐号不能为空!'):'';
048     empty($_POST['manager_pwd'])?alert(0,'管理员密码不能为空!'):'';
049     empty($_POST['manager_email'])?alert(0,'管理员邮箱不能为空!'):'';
050 }
051 /**
052  * 判断目录是否可写
053  */
054 function testwrite($d) {
055     $tfile = "_test.txt";
056     $fp = @fopen($d . "/" . $tfile, "w");
057     if (!$fp) {
058         return false;
059     }
060     fclose($fp);
061     $rs = @unlink($d . "/" . $tfile);
062     if ($rs) {
063         return true;
064     }
065     return false;
066 }
067 /**
068  * 创建目录
069  */
070 function dir_create($path, $mode = 0777) {
071     if (is_dir($path))
072         return TRUE;
073     $temp = explode('/', $path);
074     $cur_dir = '';
075     $max = count($temp) - 1;
076     for ($i = 0; $i < $max; $i++) {
077         $cur_dir .= $temp[$i] . '/';
078         if (@is_dir($cur_dir))
079             continue;
080         @mkdir($cur_dir, $mode, true);
081         @chmod($cur_dir, $mode);
082     }
083     return dir_create($path);
084 }
085 /**
086  * 数据库语句解析
087  * @param $sql 数据库
088  * @param $newTablePre 新的前缀
089  * @param $oldTablePre 旧的前缀
090  */
091 function sql_split($sql, $newTablePre, $oldTablePre) {
092     //前缀替换
093     if ($newTablePre != $oldTablePre){
094         $sql = str_replace($oldTablePre, $newTablePre, $sql);
095     }
096     $sql = preg_replace("/TYPE=(InnoDB|MyISAM|MEMORY)( DEFAULT CHARSET=[^; ]+)?/", "ENGINE=\\1 DEFAULT CHARSET=utf8", $sql);
097  
098     $sql = str_replace("\r", "\n", $sql);
099     $ret = array();
100     $queriesarray = explode(";\n", trim($sql));
101     unset($sql);
102     foreach ($queriesarray as $k=>$query) {
103         $ret[$k] = '';
104         $queries = explode("\n", trim($query));
105         $queries = array_filter($queries);
106         foreach ($queries as $query) {
107             $str1 = substr($query, 0, 1);
108             if ($str1 != '#' && $str1 != '-')
109                 $ret[$k] .= $query;
110         }
111     }
112     return $ret;
113 }
114 /**
115  * 产生随机字符串
116 * 产生一个指定长度的随机字符串,并返回给用户
117 * @access public
118 * @param int $len 产生字符串的位数
119 * @return string
120 */
121 function genRandomString($len = 6) {
122     $chars = array(
123             "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
124             "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
125             "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
126             "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
127             "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
128             "3", "4", "5", "6", "7", "8", "9", '!', '@', '#', '$',
129             '%', '^', '&', '*', '(', ')'
130     );
131     $charsLen = count($chars) - 1;
132     shuffle($chars);    // 将数组打乱
133     $output = "";
134     for ($i = 0; $i < $len; $i++) {
135         $output .= $chars[mt_rand(0, $charsLen)];
136     }
137     return $output;
138 }
139 /**
140  * 获取客户端IP地址
141  * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
142  * @return mixed
143  */
144  function get_client_ip($type = 0) {
145     $type       =  $type ? 1 : 0;
146     static $ip  =   NULL;
147     if ($ip !== NULL) return $ip[$type];
148     if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
149         $arr    =   explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
150         $pos    =   array_search('unknown',$arr);
151         if(false !== $pos) unset($arr[$pos]);
152         $ip     =   trim($arr[0]);
153     }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
154         $ip     =   $_SERVER['HTTP_CLIENT_IP'];
155     }elseif (isset($_SERVER['REMOTE_ADDR'])) {
156         $ip     =   $_SERVER['REMOTE_ADDR'];
157     }
158     // IP地址合法验证
159     $l sprintf("%u",ip2long($ip));
160     $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);
161     return $ip[$type];
162  }

代码下载

地址:

总结

安装向导是参照水平凡的代码,在基础上进行增加代码,由于要兼容于sae,便于增加其他平台,便于修改等问题,使得在结构上费了很大的功夫,很多的时间,然后又要写教程,制作图片,使用有点力不从心了,所以在代码上优化的不怎么尽人意,不过花点时间学习也是很好的。

本文转载自:http://www.chenhaizan.cn/article-php~install~detailed~guide.html

山鹰sniper
粉丝 4
博文 84
码字总数 28663
作品 0
南开
程序员
私信 提问
加载中

评论(1)

五毛钱的饼
五毛钱的饼
很详细,mark
使用 Inno Setup 工具创建一个最简单的程序安装包

我的操作系统版本为Win7旗舰版,InnoSetup工具版本为5.5.8(a)。 打开InnoSetup工具,在欢迎页选择“使用脚本向导建立一个新脚本”。 向导第一步:欢迎页。不勾选最下面的“建立一个空脚本文件...

北风其凉
2016/08/29
714
0
在Hyper-V平台上搭建桌面云系统

Deskpool 是一款桌面虚拟化管理软件,支持Hyper-V、XenServer等虚拟化平台。Deskpool采用一体化设计理念,把桌面虚拟化所需的组件打包在一个虚拟机镜像中,极大的简化了虚拟桌面部署的难度。...

yangtzi
2017/06/21
0
0
安装制作软件--Inno Setup

Inno Setup是一个免费的安装制作软件(开源),它既有适合新手的脚本向导,又有良好的脚本编辑环境,能够快速制作出标准Windows2000风格 的安装界面,足以完成一般的安装任务,在新版本版中软...

匿名
2009/06/08
15.5K
0
SCCM2012 R2实战系列之九:OSD(中)-- 捕获镜像

在上篇文章中我们详细的完成了OSD的初始化配置、导入镜像、任务序列的创建和常见问题的排错。但是在实际环境中这样分发了干净的操作系统后还需要手动为客户端安装各种各样的应用程序。所以更...

iLync
2018/07/01
0
0
ORB:新一代 Linux 应用

Orbital Apps 给我们带来了一种新的软件包类型 ORB,它具有便携软件、交互式安装向导支持,以及离线使用的能力。 便携软件很方便。主要是因为它们能够无需任何管理员权限直接运行,也能够带着...

linuxprobe
2016/07/05
26
0

没有更多内容

加载失败,请刷新页面

加载更多

Rust:最小化窗口后 CPU占用率高 (winit,glutin,imgui-rust)

最近试着用 imgui-rust 绘制界面,发现窗口最小化后CPU占用会增大。 查询的资料如下: https://github.com/rust-windowing/winit/issues/783 https://github.com/ocornut/imgui/issues/1151 ...

reter
18分钟前
4
0
cloud-zuul路由网关

九、zuul路由网关 概述 1.1 能干嘛 路由、过滤 路由基本配置 路由访问映射规则 十、springCloud config分布式配置中心

榴莲黑芝麻糊
18分钟前
5
0
Circuit Breaker模式

Circuit Breaker模式会处理一些需要一定时间来重连远程服务和远端资源的错误。该模式可以提高一个应用的稳定性和弹性。 问题 在类似于云的分布式环境中,当一个应用需要执行一些访问远程资源...

mskk
31分钟前
7
0
写论文之前的准备都有哪些?干货来了!

原文链接:https://www.lwfdy.com/archives/144.html 之前跟大家谈了许多有关于初稿修改以及写作事项需要注意的问题,那么今天我们来说一说,在写之前,我们需要做哪些准备呢,为了做到下笔如...

辅导员
37分钟前
6
0
idea快捷键

Alt + Enter 引入类 Ctrl + O 查看我们继承的类或者接口中的方法,以及我们要实现的方法 Ctrl + Alt + b 查看接口实现类中方法(就是我们使用接口编程时,在调用实现类方法处直接Ctrl+鼠标左...

行者终成事
45分钟前
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部