ThinkPHP6.0学习之项目安装页面的开发
在我们做一个项目的时候,如果是自己用或者是给同行用的话往往不需要做一个安装页面的,但是如果是将项目给一些不怎么会操作服务器,不怎么会程序的人用的时候,我们就需要一个安装页面来帮助他们更好的将项目安装好。废话补多少了,我们直接开始教学吧,我这个是基于tp6.0上的,如果不是tp6.0也可以使用,稍作修改就行了,按自己的需求来。
首先,我们先从入口文件入手,先判断一下是否已经安装好项目了,我们通过文件锁来进行判断。判断是否存在install.lock文件,如果存在证明已经安装了,否则就还没有安装,就需要跳转到安装页面了,代码如下:
// [ 应用入口文件 ] namespace think; // 定义目录分隔符 define(‘DS‘, DIRECTORY_SEPARATOR); // 定义根目录 define(‘ROOT_PATH‘, __DIR__ . DS . ‘..‘ . DS); // 定义应用目录 define(‘APP_PATH‘, ROOT_PATH . ‘app‘ . DS); // 判断是否安装了项目 if (!is_file(APP_PATH . ‘install/install.lock‘)) { header("location:./install.php"); exit; } require __DIR__ . ‘/../vendor/autoload.php‘; // 执行HTTP应用并响应 $http = (new App())->http; $response = $http->run(); $response->send(); $http->end($response);
我们需要再public文件夹下新建一个install.php的文件。还有在app文件夹下创建一个install文件夹,并将我们项目的数据库命名为install.sql放到install文件夹下面。
我们先定义几个常量和会用到的变量,方便以后使用。
// 定义目录分隔符 define(‘DS‘, DIRECTORY_SEPARATOR); // 定义根目录 define(‘ROOT_PATH‘, __DIR__ . DS . ‘..‘ . DS); // 定义应用目录 define(‘APP_PATH‘, ROOT_PATH . ‘app‘ . DS); // 安装包目录 define(‘INSTALL_PATH‘, APP_PATH . ‘install‘ . DS); //项目名称 $sitename = "tp6"; //链接 $link = array( ‘qqun‘ => "", ‘home‘ => ‘‘, ‘doc‘ => ‘‘, ); // 检测目录是否存在,这个可以按自己的需求进行修改 $checkDirs = [ ‘vendor‘ ]; //缓存目录 $runtimeDir = APP_PATH . ‘runtime‘; //错误信息 $errInfo = ‘‘; //数据库配置文件 $dbConfigFile = ROOT_PATH. ‘config‘. DS. ‘database.php‘; //后台入口文件 $adminFile = ROOT_PATH . ‘public‘ . DS . ‘admin.php‘; // 锁定的文件 $lockFile = INSTALL_PATH . ‘install.lock‘;
定义好后,我们先写个函数来判断特定文件或文件夹的读写权限,如果没有读写权限的话,我们是没法操作的,Windows系统一般不用担心这个问题,如果是Linux的话需要我们去修改一下权限为777。
// 判断文件或目录是否有写的权限
function is_really_writable($file) { if (DIRECTORY_SEPARATOR == ‘/‘ AND @ ini_get("safe_mode") == false) { return is_writable($file); } if (!is_file($file) OR ($fp = @fopen($file, "r+")) === false) { return false; } fclose($fp); return true; }
接下来我们就要进行一系列的判断,这个主要是为了能够正常安装项目,首先需要判断是否已经安装了项目,然后就是环境的判断,比如PHP版本是否大于或等于7.1.0,是否开启了PDO,数据库配置文件是否可读写等等。来,直接上代码:
// 当前是POST请求 if (isset($_SERVER[‘REQUEST_METHOD‘]) && $_SERVER[‘REQUEST_METHOD‘] == ‘POST‘) { if ($errInfo) {//错误信息 echo $errInfo; exit; } $err = ‘‘; $mysqlHostname = isset($_POST[‘mysqlHost‘]) ? $_POST[‘mysqlHost‘] : ‘127.0.0.1‘;//数据库地址 $mysqlHostport = isset($_POST[‘mysqlHostport‘]) ? $_POST[‘mysqlHostport‘] : 3306;//端口号 $hostArr = explode(‘:‘, $mysqlHostname);//如果数据库地址中填写了端口号,将他们分开 if (count($hostArr) > 1) { $mysqlHostname = $hostArr[0]; $mysqlHostport = $hostArr[1]; } $mysqlUsername = isset($_POST[‘mysqlUsername‘]) ? $_POST[‘mysqlUsername‘] : ‘root‘;//用户名 $mysqlPassword = isset($_POST[‘mysqlPassword‘]) ? $_POST[‘mysqlPassword‘] : ‘‘;//密码 $mysqlDatabase = isset($_POST[‘mysqlDatabase‘]) ? $_POST[‘mysqlDatabase‘] : ‘tp6‘;//数据库名 $mysqlPrefix = isset($_POST[‘mysqlPrefix‘]) ? $_POST[‘mysqlPrefix‘] : ‘tp_‘;//前缀 $adminUsername = isset($_POST[‘adminUsername‘]) ? $_POST[‘adminUsername‘] : ‘admin‘;//后台管理者用户名 $adminPassword = isset($_POST[‘adminPassword‘]) ? $_POST[‘adminPassword‘] : ‘123456‘;//后台管理者密码 $adminPasswordConfirmation = isset($_POST[‘adminPasswordConfirmation‘]) ? $_POST[‘adminPasswordConfirmation‘] : ‘123456‘;//重复密码 $adminEmail = isset($_POST[‘adminEmail‘]) ? $_POST[‘adminEmail‘] : ‘[email protected]‘;//邮箱 if (!preg_match("/^\w{3,12}$/", $adminUsername)) { echo "用户名只能由3-12位数字、字母、下划线组合"; exit; } if (!preg_match("/^[\S]{6,16}$/", $adminPassword)) { echo "密码长度必须在6-16位之间,不能包含空格"; exit; } if ($adminPassword !== $adminPasswordConfirmation) { echo "两次输入的密码不一致"; exit; } try { //检测能否读取安装文件 $sql = @file_get_contents(INSTALL_PATH . ‘install.sql‘); if (!$sql) { throw new Exception("无法读取app/install/install.sql文件,请检查是否有读权限"); } $sql = str_replace("`fa_", "`{$mysqlPrefix}", $sql); $pdo = new PDO("mysql:host={$mysqlHostname};port={$mysqlHostport}", $mysqlUsername, $mysqlPassword, array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8" )); //检测是否支持innodb存储引擎 $pdoStatement = $pdo->query("SHOW VARIABLES LIKE ‘innodb_version‘"); $result = $pdoStatement->fetch(); if (!$result) { throw new Exception("当前数据库不支持innodb存储引擎,请开启后再重新尝试安装"); } $pdo->query("CREATE DATABASE IF NOT EXISTS `{$mysqlDatabase}` CHARACTER SET utf8 COLLATE utf8_general_ci;"); $pdo->query("USE `{$mysqlDatabase}`"); $pdo->exec($sql); $config = @file_get_contents($dbConfigFile); $callback = function ($matches) use ($mysqlHostname, $mysqlHostport, $mysqlUsername, $mysqlPassword, $mysqlDatabase, $mysqlPrefix) { $field = ucfirst($matches[1]);//首字符大写 $replace = ${"mysql{$field}"};//$mysqlHostname,$mysqlHostport,$mysqlUsername,$mysqlPassword,$mysqlDatabase,$mysqlPrefix if ($matches[1] == ‘hostport‘ && $mysqlHostport == 3306) { $replace = ‘‘; } return "‘{$matches[1]}‘{$matches[2]}=>{$matches[3]}Env::get(‘database.{$matches[1]}‘, ‘{$replace}‘),"; }; $config = preg_replace_callback("/‘(hostname|database|username|password|hostport|prefix)‘(\s+)=>(\s+)Env::get\((.*)\)\,/", $callback, $config); //检测能否成功写入数据库配置 $result = @file_put_contents($dbConfigFile, $config); if (!$result) { throw new Exception("无法写入数据库信息到config/database.php文件,,请检查是否有写权限"); } //检测能否成功写入lock文件 $result = @file_put_contents($lockFile, 1); if (!$result) { throw new Exception("无法写入安装锁定到app/install/install.lock文件,请检查是否有写权限"); } $newSalt = substr(md5(uniqid(true)), 0, 6); $newPassword = md5(md5($adminPassword) . $newSalt); $pdo->query("UPDATE {$mysqlPrefix}admin SET username = ‘{$adminUsername}‘, email = ‘{$adminEmail}‘,password = ‘{$newPassword}‘, salt = ‘{$newSalt}‘ WHERE username = ‘admin‘"); $adminName = ‘‘; if (is_file($adminFile)) {//修改后台入口文件名 $x = ‘0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ‘; $adminName = substr(str_shuffle(str_repeat($x, ceil(10 / strlen($x)))), 1, 10) . ‘.php‘; rename($adminFile, ROOT_PATH . ‘public‘ . DS . $adminName); } echo "success|{$adminName}"; } catch (PDOException $e) { $err = $e->getMessage(); } catch (Exception $e) { $err = $e->getMessage(); } echo $err; exit; }
下面是完整的代码:
温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/40588.html