&$v) { $v = str_replace(['./application/lang/','.php'],['',''],$v); } $this->assign('langs', $langs); if(in_array(session('lang'),$langs)){ $lang = Lang::range(session('lang')); Lang::load('./application/lang/'.$lang.'.php',$lang); } switch ($step) { case 2: session('install_error', false); return self::step2(); break; case 3: if (session('install_error')) { return $this->error(lang('install/environment_failed')); } return self::step3(); break; case 4: if (session('install_error')) { return $this->error(lang('install/environment_failed')); } return self::step4(); break; case 5: if (session('install_error')) { return $this->error(lang('install/init_err')); } return self::step5(); break; default: $param = input(); if(!in_array($param['lang'],$langs)) { $param['lang'] = 'zh-cn'; } $lang = Lang::range($param['lang']); Lang::load('./application/lang/'.$lang.'.php',$lang); session('lang',$param['lang']); $this->assign('lang',$param['lang']); session('install_error', false); return $this->fetch('install@/index/index'); break; } } /** * 第二步:环境检测 * @return mixed */ private function step2() { $data = []; $data['env'] = self::checkNnv(); $data['dir'] = self::checkDir(); $data['func'] = self::checkFunc(); $this->assign('data', $data); return $this->fetch('install@index/step2'); } /** * 第三步:初始化配置 * @return mixed */ private function step3() { $install_dir = $_SERVER["SCRIPT_NAME"]; $install_dir = mac_substring($install_dir, strripos($install_dir, "/")+1); $this->assign('install_dir',$install_dir); return $this->fetch('install@index/step3'); } /** * 第四步:执行安装 * @return mixed */ private function step4() { if ($this->request->isPost()) { if (!is_writable(APP_PATH.'database.php')) { return $this->error('[app/database.php]'.lang('install/write_read_err')); } $data = input('post.'); $data['type'] = 'mysql'; $rule = [ 'hostname|'.lang('install/server_address') => 'require', 'hostport|'.lang('install/database_port') => 'require|number', 'database|'.lang('install/database_name') => 'require', 'username|'.lang('install/database_username') => 'require', 'prefix|'.lang('install/database_pre') => 'require|regex:^[a-z0-9]{1,20}[_]{1}', 'cover|'.lang('install/overwrite_database') => 'require|in:0,1', ]; $validate = $this->validate($data, $rule); if (true !== $validate) { return $this->error($validate); } $cover = $data['cover']; unset($data['cover']); $config = include APP_PATH.'database.php'; foreach ($data as $k => $v) { if (array_key_exists($k, $config) === false) { return $this->error(lang('param').''.$k.''.lang('install/not_found')); } } // 不存在的数据库会导致连接失败 $database = $data['database']; unset($data['database']); // 创建数据库连接 $db_connect = Db::connect($data); // 检测数据库连接 try{ $db_connect->execute('select version()'); }catch(\Exception $e){ $this->error(lang('install/database_connect_err')); } // 生成数据库配置文件 $data['database'] = $database; self::mkDatabase($data); // 不覆盖检测是否已存在数据库 if (!$cover) { $check = $db_connect->execute('SELECT * FROM information_schema.schemata WHERE schema_name="'.$database.'"'); if ($check) { $this->success(lang('install/database_name_haved'),''); } } // 创建数据库 if (!$db_connect->execute("CREATE DATABASE IF NOT EXISTS `{$database}` DEFAULT CHARACTER SET utf8")) { return $this->error($db_connect->getError()); } return $this->success(lang('install/database_connect_ok'), ''); } else { return $this->error(lang('install/access_denied')); } } /** * 第五步:数据库安装 * @return mixed */ private function step5() { $account = input('post.account'); $password = input('post.password'); $install_dir = input('post.install_dir'); $initdata = input('post.initdata'); $config = include APP_PATH.'database.php'; if (empty($config['hostname']) || empty($config['database']) || empty($config['username'])) { return $this->error(lang('install/please_test_connect')); } if (empty($account) || empty($password)) { return $this->error(lang('install/please_input_admin_name_pass')); } $rule = [ 'account|'.lang('install/admin_name') => 'require|alphaNum', 'password|'.lang('install/admin_pass') => 'require|length:6,20', ]; $validate = $this->validate(['account' => $account, 'password' => $password], $rule); if (true !== $validate) { return $this->error($validate); } if(empty($install_dir)) { $install_dir='/'; } $config_new = config('maccms'); $cofnig_new['app']['cache_flag'] = substr(md5(time()),0,10); $cofnig_new['app']['lang'] = session('lang'); $config_new['api']['vod']['status'] = 0; $config_new['api']['art']['status'] = 0; $config_new['interface']['status'] = 0; $config_new['interface']['pass'] = mac_get_rndstr(16); $config_new['site']['install_dir'] = $install_dir; // 更新程序配置文件 $res = mac_arr2file(APP_PATH . 'extra/maccms.php', $config_new); if ($res === false) { return $this->error(lang('write_err_config')); } // 导入系统初始数据库结构 // 导入SQL $sql_file = APP_PATH.'install/sql/install.sql'; if (file_exists($sql_file)) { $sql = file_get_contents($sql_file); $sql_list = mac_parse_sql($sql, 0, ['mac_' => $config['prefix']]); if ($sql_list) { $sql_list = array_filter($sql_list); foreach ($sql_list as $v) { try { Db::execute($v); } catch(\Exception $e) { return $this->error(lang('install/sql_err'). $e); } } } } //初始化数据 if($initdata=='1'){ $sql_file = APP_PATH.'install/sql/initdata.sql'; if (file_exists($sql_file)) { $sql = file_get_contents($sql_file); $sql_list = mac_parse_sql($sql, 0, ['mac_' => $config['prefix']]); if ($sql_list) { $sql_list = array_filter($sql_list); foreach ($sql_list as $v) { try { Db::execute($v); } catch(\Exception $e) { return $this->error(lang('install/init_data_err'). $e); } } } } } // 注册管理员账号 $data = [ 'admin_name' => $account, 'admin_pwd' => $password, 'admin_status' =>1, ]; $res = model('Admin')->saveData($data); if (!$res['code']>1) { return $this->error(lang('install/admin_name_err').':'.$res['msg']); } file_put_contents(APP_PATH.'data/install/install.lock', date('Y-m-d H:i:s')); // 获取站点根目录 $root_dir = request()->baseFile(); $root_dir = preg_replace(['/install.php$/'], [''], $root_dir); return $this->success(lang('install/is_ok'), $root_dir.'admin.php'); } /** * 环境检测 * @return array */ private function checkNnv() { $items = [ 'os' => [lang('install/os'), lang('install/not_limited'), 'Windows/Unix', PHP_OS, 'ok'], 'php' => [lang('install/php'), '5.5', '5.5及以上', PHP_VERSION, 'ok'], ]; if ($items['php'][3] < $items['php'][1]) { $items['php'][4] = 'no'; session('install_error', true); } /* $tmp = function_exists('gd_info') ? gd_info() : []; if (empty($tmp['GD Version'])) { $items['gd'][3] = lang('install/not_installed'); $items['gd'][4] = 'no'; session('install_error', true); } else { $items['gd'][3] = $tmp['GD Version']; } */ return $items; } /** * 目录权限检查 * @return array */ private function checkDir() { $items = [ ['file', './application/database.php', lang('install/read_and_write'), lang('install/read_and_write'), 'ok'], ['file', './application/route.php', lang('install/read_and_write'), lang('install/read_and_write'), 'ok'], ['dir', './application/extra', lang('install/read_and_write'), lang('install/read_and_write'), 'ok'], ['dir', './application/data/backup', lang('install/read_and_write'), lang('install/read_and_write'), 'ok'], ['dir', './application/data/update', lang('install/read_and_write'), lang('install/read_and_write'), 'ok'], ['dir', './runtime', lang('install/read_and_write'), lang('install/read_and_write'), 'ok'], ['dir', './upload', lang('install/read_and_write'), lang('install/read_and_write'), 'ok'], ]; foreach ($items as &$v) { if ($v[0] == 'dir') {// 文件夹 if(!is_writable($v[1])) { if(is_dir($v[1])) { $v[3] = lang('install/not_writable'); $v[4] = 'no'; } else { $v[3] = lang('install/not_found'); $v[4] = 'no'; } session('install_error', true); } } else {// 文件 if(!is_writable($v[1])) { $v[3] = lang('install/not_writable'); $v[4] = 'no'; session('install_error', true); } } } return $items; } /** * 函数及扩展检查 * @return array */ private function checkFunc() { $items = [ ['pdo', lang('install/support'), 'yes',lang('install/class')], ['pdo_mysql', lang('install/support'), 'yes', lang('install/model')], ['zip', lang('install/support'), 'yes', lang('install/model')], ['fileinfo', lang('install/support'), 'yes', lang('install/model')], ['curl', lang('install/support'), 'yes', lang('install/model')], ['xml', lang('install/support'), 'yes', lang('install/function')], ['file_get_contents', lang('install/support'), 'yes', lang('install/function')], ['mb_strlen', lang('install/support'), 'yes', lang('install/function')], ]; if(version_compare(PHP_VERSION,'5.6.0','ge') && version_compare(PHP_VERSION,'5.7.0','lt')){ $items[] = ['always_populate_raw_post_data',lang('install/support'),'yes',lang('install/config')]; } foreach ($items as &$v) { if(('类'==$v[3] && !class_exists($v[0])) || (lang('install/model')==$v[3] && !extension_loaded($v[0])) || (lang('install/function')==$v[3] && !function_exists($v[0])) || (lang('install/config')==$v[3] && ini_get('always_populate_raw_post_data')!=-1)) { $v[1] = lang('install/not_support'); $v[2] = 'no'; session('install_error', true); } } return $items; } /** * 生成数据库配置文件 * @return array */ private function mkDatabase(array $data) { $code = << // +---------------------------------------------------------------------- return [ // 数据库类型 'type' => 'mysql', // 服务器地址 'hostname' => '{$data['hostname']}', // 数据库名 'database' => '{$data['database']}', // 用户名 'username' => '{$data['username']}', // 密码 'password' => '{$data['password']}', // 端口 'hostport' => '{$data['hostport']}', // 连接dsn 'dsn' => '', // 数据库连接参数 'params' => [], // 数据库编码默认采用utf8 'charset' => 'utf8', // 数据库表前缀 'prefix' => '{$data['prefix']}', // 数据库调试模式 'debug' => false, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) 'deploy' => 0, // 数据库读写是否分离 主从式有效 'rw_separate' => false, // 读写分离后 主服务器数量 'master_num' => 1, // 指定从服务器序号 'slave_no' => '', // 是否严格检查字段是否存在 'fields_strict' => false, // 数据集返回类型 'resultset_type' => 'array', // 自动写入时间戳字段 'auto_timestamp' => false, // 时间字段取出后的默认时间格式 'datetime_format' => 'Y-m-d H:i:s', // 是否需要进行SQL性能分析 'sql_explain' => false, // Builder类 'builder' => '', // Query类 'query' => '\\think\\db\\Query', ]; INFO; file_put_contents(APP_PATH.'database.php', $code); // 判断写入是否成功 $config = include APP_PATH.'database.php'; if (empty($config['database']) || $config['database'] != $data['database']) { return $this->error('[application/database.php]'.lang('write_err_database')); exit; } } }