为了对用户更友好,我们会给一个网站做一个安装文件的程序,用可视化界面来引导安装。那么如何来用PHP制作MySql的安装文件呢?
实现这个程序,先要了解清楚原理。一个PHP网页要运行,一般都会基于一个数据库,最佳选择就是MySql,那么安装就是用PHP来执行SQL语句建立数据表的过程,其中可以包括插入一些默认的数据。像MySql导出的数据文件是都可执行的SQL语句(其中还有注释信息),于是我们可以把这些语句用正则表达式分为一条一条的来执行,碰到是数据表的,就提示用户正在安装该表,表名一并显示出来。安装文件执行完毕之后,一个网站便可以运行了。
那么如何来实现具体的功能呢?我写了一个程序,并结合JS定位安装时的数据表信息的滚动条始终在底部、制作了显示安装的进度条。
下面是整个页面的源代码:
在第二个步骤中,先对表单提交过来的数据进行校验,有不符合规则的停止程序往下执行,并给一个按钮让户用返回重新填写。所有的数据全部校验通过后,再做好数据库的连接,建立一个数据库,判断一个test.sql的文件是否存在(这个文件是由建立表、插入一些默认数据的SQL语 句组成的),如果不存在的话停止安装程序,提示用户安装不能继续。如果test.sql该文件存在的话,用fopen()、fread()函数读出 test.sql文件里的内容,把里面前缀为{table_prefix}内容替换为$table_prefix的值(test.sql文件的制作视频里 有讲解,这个很简单,就是替换),该值如果表单里填了就为表单传过来的值,没填的话就为qxhtml_。接着再用explode的函数以";\r"分割 test.sql文件里的内容,分成了一条一条可执行的SQL语 句,被分割出的数组,最后一个是空的执行语句,array_pop()出栈,去掉最后一个数组元素,当然要摸拟出安装进度条的效果,还需要用正则匹配出 test.sql里的内容有多少句创建表的命令,统计出数据表的数量,赋值给$total_table,$n为计数器。下面就是foreach遍历被 explode分割的数组,每次循环都去执行SQL语句,同时判断该次执行的语句是否是创建表的,是的话,就显示出数据表的名称,$n++,这个$n就知道是在创建第几张表了。再结合JS控制显示的进度,安装使创建数据的信息超出容器时,就会出现滚动条JS控制滚动条始终在最底部,JS代码是可以在PHP服务端输出的,每执行一次创建数据表的操作,JS便会改变相应控制DOM元素的样式。flush()这个函数是每循环一次刷新出显示的内容,如果不写的话,只有执行完毕之后,页面上才会显示出信息,这样进度条效果便不存在。
所有的SQL语句执行完后,就应该把表单提交过来的数据写进配置文件,这里就是一个读档、开档、替换、开档、写入的过程。可能代码还是多了点,不过仔细去理解一下,还是满充实的。
实现这个程序,先要了解清楚原理。一个PHP网页要运行,一般都会基于一个数据库,最佳选择就是MySql,那么安装就是用PHP来执行SQL语句建立数据表的过程,其中可以包括插入一些默认的数据。像MySql导出的数据文件是都可执行的SQL语句(其中还有注释信息),于是我们可以把这些语句用正则表达式分为一条一条的来执行,碰到是数据表的,就提示用户正在安装该表,表名一并显示出来。安装文件执行完毕之后,一个网站便可以运行了。
那么如何来实现具体的功能呢?我写了一个程序,并结合JS定位安装时的数据表信息的滚动条始终在底部、制作了显示安装的进度条。
下面是整个页面的源代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>安装向导</title>
<style type="text/css">
* { margin: 0; padding: 0; }
label { width: 200px; float: left; }
p { margin-bottom: 14px; }
h1 { font-size: 20px; background: #888; color: #fff; height: 37px; line-height: 37px; margin-bottom: 10px; }
h2 { font-size: 100%; margin-bottom: 10px; }
#wrapper { width: 500px; height: 250px; padding: 15px 10px; border: 1px solid #ccc; overflow: auto; }
#progress_w { width: 500px; height: 18px; border: 1px solid #333; margin-bottom: 10px; }
#progress { height: 18px; }
</style>
</head>
<body>
<h1>安装向导</h1>
<?php
/*安装的第一步*/
if(!$_POST['step']||$_POST['step']=='1'){
?>
<h2>开始安装</h2>
<form action="install.php" method="post">
<p><label>服务器地址:</label><input type="text" name="host" value="localhost" />* 一般为localhost</p>
<p><label>服务器用户名:</label><input type="text" name="name_s" />*</p>
<p><label>服务器用户密码:</label><input type="text" name="pass" /> 如果没有设置就不用填</p>
<p><label>数据库名称:</label><input type="text" name="database" />*</p>
<p><label>数据表前缀:</label><input type="text" name="table_prefix" /> 如果不填就为qxhtml_</p>
<p><input type="hidden" name="step" value="2" /></p>
<p><input type="submit" value="下一步" name="ok" /></p>
</form>
<?php
/*安装的第二步*/
}elseif($_POST['step']=='2'){
$host = trim($_POST['host']);
$name = trim($_POST['name_s']);
$pass = trim($_POST['pass']);
$database = trim($_POST['database']);
$table_prefix = trim($_POST['table_prefix']) ? trim($_POST['table_prefix']) : 'qxhtml_';
if($host==''||$name==''||$database==''){
echo '<p>请确认必填写是否填写</p>','<p><input type="button" value="上一步" onclick="history.back()" /></p>';
exit();
}
$conn = @mysql_connect($host,$name,$pass) or die('
<p>请确认服务器地址、服务器用户名、服务器用户密码是否正确!</p>
<p><input type="button" value="上一步" onclick="history.back()" /></p>
');
mysql_query("CREATE DATABASE IF NOT EXISTS `".$database."`") or die(mysql_error());
mysql_select_db($database,$conn) or die("没有该数据库");
mysql_query("set names 'GBK'");
$file = 'test.sql';
echo '<h2 id="prompt">正在安装,请稍等...</h2>',
'<div id="progress_w"><div id="progress"></div></div>',
'<div id="wrapper"><div id="info">';
if(file_exists($file)){
$handle = fopen($file,'r');
$buffer = fread($handle,filesize($file));
fclose($handle);
$buffer = str_replace('{table_prefix}',$table_prefix,$buffer);
$arr = explode(";\r",$buffer);
//出栈,删除最后一个空SQL语句的数组
array_pop($arr);
//计算一共有多少张表
$total_table = preg_match_all("/CREATE TABLE `(.*)` /i",$buffer,$a);
//计数器
$n = 0;
//遍历开割开的SQL语句并执行
foreach($arr as $query){
//安装进度条的宽度
$width = 500;
mysql_query($query) or die(mysql_error());
//匹配建立表的SQL语句
$is = preg_match("/CREATE TABLE `(.*)` /i",$query,$arr_preg);
if($is){
$n++;
$progress = ceil(($n/$total_table)*$width);
echo '正在创建表 ',$arr_preg[1],'... <font color=red>成功</font><br />',
'<script type="text/javascript">',
'var wrapper = document.getElementById("wrapper");',
'var height = wrapper.clientHeight;',
'wrapper.scrollTop = document.getElementById("info").offsetHeight + 30 - height;',
'var progress = document.getElementById("progress");',
'progress.style.background = "#999";',
'progress.style.width = "',$progress,'px"',
'</script>';
//循环一次显示一次
flush();
}
}
echo '</div></div>';
}else{
echo 'SQL的导入文件不存在,安装不无继续!',dirname(__FILE__),'/test.sql';
exit();
}
$file = 'config.php';
//把提交过来的表单信息写入配置文件之中
if(file_exists($file)){
$handle = fopen($file,'r');
$buffer = fread($handle,filesize($file));
fclose($handle);
$mode = array('#host#','#name#','#pass#','#database#');
$subject = array($host,$name,$pass,$database);
$buffer = str_replace($mode,$subject,$buffer);
$handle = fopen($file,'w');
fwrite($handle,$buffer);
fclose($handle);
}
echo '<script type="text/javascript"> document.getElementById("prompt").innerHTML = "安装完成^_^";</script>';
}
?>
</body>
</html>
首先是用一个if语句判断$_POST['step']的值,如果没有值或是1的话就只显示表单的界面,如果值为2的话进入安装的第二步,因为在表单中有一个隐藏域名为step,赋给它值为2,只要提交后就会进入安装的第二步。<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>安装向导</title>
<style type="text/css">
* { margin: 0; padding: 0; }
label { width: 200px; float: left; }
p { margin-bottom: 14px; }
h1 { font-size: 20px; background: #888; color: #fff; height: 37px; line-height: 37px; margin-bottom: 10px; }
h2 { font-size: 100%; margin-bottom: 10px; }
#wrapper { width: 500px; height: 250px; padding: 15px 10px; border: 1px solid #ccc; overflow: auto; }
#progress_w { width: 500px; height: 18px; border: 1px solid #333; margin-bottom: 10px; }
#progress { height: 18px; }
</style>
</head>
<body>
<h1>安装向导</h1>
<?php
/*安装的第一步*/
if(!$_POST['step']||$_POST['step']=='1'){
?>
<h2>开始安装</h2>
<form action="install.php" method="post">
<p><label>服务器地址:</label><input type="text" name="host" value="localhost" />* 一般为localhost</p>
<p><label>服务器用户名:</label><input type="text" name="name_s" />*</p>
<p><label>服务器用户密码:</label><input type="text" name="pass" /> 如果没有设置就不用填</p>
<p><label>数据库名称:</label><input type="text" name="database" />*</p>
<p><label>数据表前缀:</label><input type="text" name="table_prefix" /> 如果不填就为qxhtml_</p>
<p><input type="hidden" name="step" value="2" /></p>
<p><input type="submit" value="下一步" name="ok" /></p>
</form>
<?php
/*安装的第二步*/
}elseif($_POST['step']=='2'){
$host = trim($_POST['host']);
$name = trim($_POST['name_s']);
$pass = trim($_POST['pass']);
$database = trim($_POST['database']);
$table_prefix = trim($_POST['table_prefix']) ? trim($_POST['table_prefix']) : 'qxhtml_';
if($host==''||$name==''||$database==''){
echo '<p>请确认必填写是否填写</p>','<p><input type="button" value="上一步" onclick="history.back()" /></p>';
exit();
}
$conn = @mysql_connect($host,$name,$pass) or die('
<p>请确认服务器地址、服务器用户名、服务器用户密码是否正确!</p>
<p><input type="button" value="上一步" onclick="history.back()" /></p>
');
mysql_query("CREATE DATABASE IF NOT EXISTS `".$database."`") or die(mysql_error());
mysql_select_db($database,$conn) or die("没有该数据库");
mysql_query("set names 'GBK'");
$file = 'test.sql';
echo '<h2 id="prompt">正在安装,请稍等...</h2>',
'<div id="progress_w"><div id="progress"></div></div>',
'<div id="wrapper"><div id="info">';
if(file_exists($file)){
$handle = fopen($file,'r');
$buffer = fread($handle,filesize($file));
fclose($handle);
$buffer = str_replace('{table_prefix}',$table_prefix,$buffer);
$arr = explode(";\r",$buffer);
//出栈,删除最后一个空SQL语句的数组
array_pop($arr);
//计算一共有多少张表
$total_table = preg_match_all("/CREATE TABLE `(.*)` /i",$buffer,$a);
//计数器
$n = 0;
//遍历开割开的SQL语句并执行
foreach($arr as $query){
//安装进度条的宽度
$width = 500;
mysql_query($query) or die(mysql_error());
//匹配建立表的SQL语句
$is = preg_match("/CREATE TABLE `(.*)` /i",$query,$arr_preg);
if($is){
$n++;
$progress = ceil(($n/$total_table)*$width);
echo '正在创建表 ',$arr_preg[1],'... <font color=red>成功</font><br />',
'<script type="text/javascript">',
'var wrapper = document.getElementById("wrapper");',
'var height = wrapper.clientHeight;',
'wrapper.scrollTop = document.getElementById("info").offsetHeight + 30 - height;',
'var progress = document.getElementById("progress");',
'progress.style.background = "#999";',
'progress.style.width = "',$progress,'px"',
'</script>';
//循环一次显示一次
flush();
}
}
echo '</div></div>';
}else{
echo 'SQL的导入文件不存在,安装不无继续!',dirname(__FILE__),'/test.sql';
exit();
}
$file = 'config.php';
//把提交过来的表单信息写入配置文件之中
if(file_exists($file)){
$handle = fopen($file,'r');
$buffer = fread($handle,filesize($file));
fclose($handle);
$mode = array('#host#','#name#','#pass#','#database#');
$subject = array($host,$name,$pass,$database);
$buffer = str_replace($mode,$subject,$buffer);
$handle = fopen($file,'w');
fwrite($handle,$buffer);
fclose($handle);
}
echo '<script type="text/javascript"> document.getElementById("prompt").innerHTML = "安装完成^_^";</script>';
}
?>
</body>
</html>
在第二个步骤中,先对表单提交过来的数据进行校验,有不符合规则的停止程序往下执行,并给一个按钮让户用返回重新填写。所有的数据全部校验通过后,再做好数据库的连接,建立一个数据库,判断一个test.sql的文件是否存在(这个文件是由建立表、插入一些默认数据的SQL语 句组成的),如果不存在的话停止安装程序,提示用户安装不能继续。如果test.sql该文件存在的话,用fopen()、fread()函数读出 test.sql文件里的内容,把里面前缀为{table_prefix}内容替换为$table_prefix的值(test.sql文件的制作视频里 有讲解,这个很简单,就是替换),该值如果表单里填了就为表单传过来的值,没填的话就为qxhtml_。接着再用explode的函数以";\r"分割 test.sql文件里的内容,分成了一条一条可执行的SQL语 句,被分割出的数组,最后一个是空的执行语句,array_pop()出栈,去掉最后一个数组元素,当然要摸拟出安装进度条的效果,还需要用正则匹配出 test.sql里的内容有多少句创建表的命令,统计出数据表的数量,赋值给$total_table,$n为计数器。下面就是foreach遍历被 explode分割的数组,每次循环都去执行SQL语句,同时判断该次执行的语句是否是创建表的,是的话,就显示出数据表的名称,$n++,这个$n就知道是在创建第几张表了。再结合JS控制显示的进度,安装使创建数据的信息超出容器时,就会出现滚动条JS控制滚动条始终在最底部,JS代码是可以在PHP服务端输出的,每执行一次创建数据表的操作,JS便会改变相应控制DOM元素的样式。flush()这个函数是每循环一次刷新出显示的内容,如果不写的话,只有执行完毕之后,页面上才会显示出信息,这样进度条效果便不存在。
所有的SQL语句执行完后,就应该把表单提交过来的数据写进配置文件,这里就是一个读档、开档、替换、开档、写入的过程。可能代码还是多了点,不过仔细去理解一下,还是满充实的。