dedecms5.7(织梦)源码解析之程序安装
来源:SegmentFault
2023-02-16 15:29:08
0浏览
收藏
数据库小白一枚,正在不断学习积累知识,现将学习到的知识记录一下,也是将我的所得分享给大家!而今天这篇文章《dedecms5.7(织梦)源码解析之程序安装》带大家来了解一下dedecms5.7(织梦)源码解析之程序安装,希望对大家的知识积累有所帮助,从而弥补自己的不足,助力实战开发!
代码
默认服务器配置入口文件是index.html,index.php等,织梦uploads文件夹中仅有index.php,遂直接运行index.php文件啊,源码如下:
<?php /**
1. @version $Id: index.php 1 9:23 2010-11-11 tianya $
2. @package DedeCMS.Site
3. @copyright Copyright (c) 2007 - 2010, DesDev, Inc.
4. @license http://help.dedecms.com/usersguide/license.html
5. @link https://www.dedecms.com/
*/
if(!file_exists(dirname(__FILE__).'/data/common.inc.php'))
{
header('Location:install/index.php');
exit();
}
//自动生成HTML版
if(isset($_GET['upcache']) || !file_exists('index.html'))
{
require_once (dirname(__FILE__) . "/include/common.inc.php");
require_once DEDEINC."/arc.partview.class.php";
$GLOBALS['_arclistEnv'] = 'index';
$row = $dsql->GetOne("Select * From `#@__homepageset`");
$row['templet'] = MfTemplet($row['templet']);
$pv = new PartView();
$pv->SetTemplet($cfg_basedir . $cfg_templets_dir . "/" . $row['templet']);
$row['showmod'] = isset($row['showmod'])? $row['showmod'] : 0;
if ($row['showmod'] == 1)
{
$pv->SaveToHtml(dirname(__FILE__).'/index.html');
include(dirname(__FILE__).'/index.html');
exit();
} else {
$pv->Display();
exit();
}
}
else
{
header('HTTP/1.1 301 Moved Permanently');
header('Location:index.html');
}
?>
纵观整个文件,其中代码大概分成了两部分:
判断是存在全局配置文件(是否安装)
判断根目录是否存在index.html文件,没有则生成
具体请看下面带有注释的代码:
<?php /**
* @version $Id: index.php 1 9:23 2010-11-11 tianya $
* @package DedeCMS.Site
* @copyright Copyright (c) 2007 - 2010, DesDev, Inc.
* @license http://help.dedecms.com/usersguide/license.html
* @link https://www.dedecms.com/
*/
/**
* 这里是判断data文件夹下是否存在common.inc.php全局配置文件
* 程序初始未安装状态下,这个文件是没有的
* 那么如果检测到不存在,则会跳转到根目录下的install文件夹下,执行index.php文件
*/
if(!file_exists(dirname(__FILE__).'/data/common.inc.php'))
{
header('Location:install/index.php'); // 不存在则跳转
exit(); // 终止
}
//自动生成HTML版
/**
* 判断是否接收到upcache参数,如果接收到,说明当前正处于调试预览模式,直接运行php
* 判断本地index.html文件是否存在,如果不存在则直接运行php
*
*/
if(isset($_GET['upcache']) || !file_exists('index.html'))
{
// 包含全局配置文件
require_once (dirname(__FILE__) . "/include/common.inc.php");
// 载入视图类文件
require_once DEDEINC."/arc.partview.class.php";
// 设置全局变量
$GLOBALS['_arclistEnv'] = 'index';
// 查询homepageset表(#@是前缀,会经过替换)
$row = $dsql->GetOne("Select * From `#@__homepageset`");
// 模板目录规则
$row['templet'] = MfTemplet($row['templet']);
// 创建视图对象
$pv = new PartView();
// 设置要解析的模板
$pv->SetTemplet($cfg_basedir . $cfg_templets_dir . "/" . $row['templet']);
// 这里接收的应该是模块参数,方便后面进行判断
$row['showmod'] = isset($row['showmod'])? $row['showmod'] : 0;
// 判断当前模块
if ($row['showmod'] == 1)
{
// 生成index.html文件
$pv->SaveToHtml(dirname(__FILE__).'/index.html');
// 生成后包含进来(注意不是跳转哦)
include(dirname(__FILE__).'/index.html');
// 终止
exit();
} else {
// 直接执行
$pv->Display();
// 终止
exit();
}
}
else
{
// 设置301header跳啊转
header('HTTP/1.1 301 Moved Permanently');
// 跳转进入index.html页面
header('Location:index.html');
}
?>
好,index.php入口文件我们从上面的注释中已经能够大概明白他的内容和作用了,下面就顺着安装步骤找安装文文件install/index.php吧,由于这个文件内容太多,源码我就不放了,直接放上我注释过的源码内容:
<?php /**
* @version $Id: index.php 1 13:41 2010年7月26日Z tianya $
* @package DedeCMS.Install
* @copyright Copyright (c) 2007 - 2010, DesDev, Inc.
* @license http://help.dedecms.com/usersguide/license.html
* @link https://www.dedecms.com/
*/
// 设置超时时间-永不超时
@set_time_limit(0);
//error_reporting(E_ALL);
// 设置报错等级-显示除了notice警告之外的所有错误
error_reporting(E_ALL || ~E_NOTICE);
// 定义版本信息
$verMsg = ' V5.7 GBKSP1';
// 定义语言编码信息
$s_lang = 'gb2312';
// 定义默认数据库名称
$dfDbname = 'dedecmsv57gbksp1';
// 错误信息,默认为空
$errmsg = '';
// 定义数据体验包名称
$install_demo_name = 'dedev57demo.txt';
// 安装锁文件名称
$insLockfile = dirname(__FILE__).'/install_lock.txt';
// 定义模型临时配置文件
$moduleCacheFile = dirname(__FILE__).'/modules.tmp.inc';
// 定义程序配置文件路径常量
define('DEDEINC',dirname(__FILE__).'/../include');
// 定义程序数据文件路径常量
define('DEDEDATA',dirname(__FILE__).'/../data');
// 定义程序根目录路径常量啊
define('DEDEROOT',preg_replace("#[\\\\\/]install#", '', dirname(__FILE__)));
// 设置编码-根据上面定义的$s_lang显示
header("Content-Type: text/html; charset={$s_lang}");
// 包含进入安装配置文件-主要包含一些函数方法
require_once(DEDEROOT.'/install/install.inc.php');
// 包含进入zip压缩类文件
require_once(DEDEINC.'/zip.class.php');
// 遍历三个超全局变量键名
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
// 过滤超全局变量值内容-如果get_magic_quotes_gpc没有开启,则使用addslashes进行转义,并且直接按照表单过来的name名称作为变量名称
foreach($$_request as $_k => $_v) ${$_k} = RunMagicQuotes($_v);
}
// 包含进入系统核心函数文件
require_once(DEDEINC.'/common.func.php');
// 检测安装锁文件是否已经存在,如果存在终止程序执行,并提示文件已经安装
if(file_exists($insLockfile))
{
exit(" 程序已运行安装,如果你确定要重新安装,请先从FTP中删除 install/install_lock.txt!");
}
// 初始化文件安装步骤
if(empty($step))
{
$step = 1;
}
/*------------------------
使用协议书
function _1_Agreement()
------------------------*/
// 如果为第一步,则引入使用协议书页面
if($step==1)
{
// 引入第一个页面(使用协议书)
include('./templates/step-1.html');
// 终止当前执行
exit();
}
/*------------------------
环境测试
function _2_TestEnv()
------------------------*/
// 如果为第二部,则引入环境测试页面
else if($step==2)
{
// 获取php版本
$phpv = phpversion();
// 获取当前操作系统类型
$sp_os = PHP_OS;
// 获得GD的版本
$sp_gd = gdversion();
// 获取服务器标识的字串
$sp_server = $_SERVER['SERVER_SOFTWARE'];
// 获取当前host-如果ip不存在,则直接获取主机名,否则为ip
$sp_host = (empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_HOST'] : $_SERVER['REMOTE_ADDR']);
// 获取当前服务器主机名称
$sp_name = $_SERVER['SERVER_NAME'];
// 获取当前配置最大执行时间
$sp_max_execution_time = ini_get('max_execution_time');
// 获取当前在函数调用时参数被按照引用传递时是否发出警告-php5.4以上已经移除
$sp_allow_reference = (ini_get('allow_call_time_pass_reference') ? '<font color="green">[√]On</font>' : '<font color="red">[×]Off</font>');
// 获取当前是否 URL 形式的 fopen 封装协议
$sp_allow_url_fopen = (ini_get('allow_url_fopen') ? '<font color="green">[√]On</font>' : '<font color="red">[×]Off</font>');
// 获取当前是否已经打开php的安全模式
$sp_safe_mode = (ini_get('safe_mode') ? '<font color="red">[×]On</font>' : '<font color="green">[√]Off</font>');
// 获取当前是否打开gd库
$sp_gd = ($sp_gd>0 ? '<font color="green">[√]On</font>' : '<font color="red">[×]Off</font>');
// 获取当前是否打开mysql扩展
$sp_mysql = (function_exists('mysql_connect') ? '<font color="green">[√]On</font>' : '<font color="red">[×]Off</font>');
// 判断并定义mysql错误
if($sp_mysql=='<font color="red">[×]Off</font>')
$sp_mysql_err = TRUE;
else
$sp_mysql_err = FALSE;
// 定义测试目录
$sp_testdirs = array(
'/',
'/plus/*',
'/dede/*',
'/data/*',
'/a/*',
'/install',
'/special',
'/uploads/*'
);
// 包含第二部文件
include('./templates/step-2.html');
// 终止本次执行
exit();
}
/*------------------------
设置参数
function _3_WriteSeting()
------------------------*/
// 第三部设置参数
else if($step==3)
{
// 取得当前URL的 路径地址
if(!empty($_SERVER['REQUEST_URI']))
$scriptName = $_SERVER['REQUEST_URI']; // 如果存在,则直接写入
else
$scriptName = $_SERVER['PHP_SELF']; // 获取正在执行脚本的文件名
// 通过正则替换,获得基础目录-根目录路径
$basepath = preg_replace("#\/install(.*)$#i", '', $scriptName);
// 获取当前请求的 Host: 头部的内容。
if(!empty($_SERVER['HTTP_HOST']))
$baseurl = 'http://'.$_SERVER['HTTP_HOST']; // 存在则写入
else
$baseurl = "http://".$_SERVER['SERVER_NAME']; // 获取服务器主机的名称
// 大小写字母和阿拉伯数字
$chars='abcdefghigklmnopqrstuvwxwyABCDEFGHIGKLMNOPQRSTUVWXWY0123456789';
// 随机cookie编码
$rnd_cookieEncode='';
// 随机长度
$length = rand(28,32);
// $chars最大长度
$max = strlen($chars) - 1;
// 按随机生成的长度进行for循环
for($i = 0; $i alert('数据库服务器或登录密码无效,\\n\\n无法连接数据库,请重新设定!');history.go(-1);");
// 如果数据库不存在,则创建数据库
mysql_query("CREATE DATABASE IF NOT EXISTS `".$dbname."`;",$conn);
// 选择数据库
mysql_select_db($dbname, $conn) or die("<script>alert('选择数据库失败,可能是你没权限,请预先创建一个数据库!');history.go(-1);</script>");
//获得数据库版本信息
$rs = mysql_query("SELECT VERSION();",$conn);
// 从结果集中取得一行作为数组
$row = mysql_fetch_array($rs);
// 按.分割
$mysqlVersions = explode('.',trim($row[0]));
// 重组,只要前两个主要和次要版本即可
$mysqlVersion = $mysqlVersions[0].".".$mysqlVersions[1];
// 设置字符集
mysql_query("SET NAMES '$dblang',character_set_client=binary,sql_mode='';",$conn);
// 创建全局配置文件
$fp = fopen(dirname(__FILE__)."/common.inc.php","r");
// 读取全局配置文件
$configStr1 = fread($fp,filesize(dirname(__FILE__)."/common.inc.php"));
// 关闭文件资源
fclose($fp);
// 打开安装配置缓存文件
$fp = fopen(dirname(__FILE__)."/config.cache.inc.php","r");
// 读取安装配置缓存文件
$configStr2 = fread($fp,filesize(dirname(__FILE__)."/config.cache.inc.php"));
// 关闭资源
fclose($fp);
//common.inc.php 定义部分需要写入全局配置文件的内容
$configStr1 = str_replace("~dbhost~",$dbhost,$configStr1);
$configStr1 = str_replace("~dbname~",$dbname,$configStr1);
$configStr1 = str_replace("~dbuser~",$dbuser,$configStr1);
$configStr1 = str_replace("~dbpwd~",$dbpwd,$configStr1);
$configStr1 = str_replace("~dbprefix~",$dbprefix,$configStr1);
$configStr1 = str_replace("~dblang~",$dblang,$configStr1);
// 设置根目录data目录权限
@chmod(DEDEDATA,0777);
// 打开全局配置文件(创建),如果无法创建,则说明目录没有写入权限
$fp = fopen(DEDEDATA."/common.inc.php","w") or die("<script>alert('写入配置失败,请检查../data目录是否可写入!');history.go(-1);</script>");
// 将自带的缓存配置文件中部分相应内容写入全局配置文件中
fwrite($fp,$configStr1);
// 关闭文件资源
fclose($fp);
//config.cache.inc.php
// CMS安装目录,匹配至少一个/
$cmspath = trim(preg_replace("#\/{1,}#", '/', $cmspath));
// 如果匹配到了至少一个/而且也没有匹配到以/开头的(加上/,即加上根目录)
if($cmspath!='' && !preg_match("#^\/#", $cmspath)) $cmspath = '/'.$cmspath;
// 如果cms路径为空,则indexUrl为/
if($cmspath=='') $indexUrl = '/';
// 否则indexUrl等于cms路径
else $indexUrl = $cmspath;
// 从安装配置缓存文件中读取部分配置用于后面写入
$configStr2 = str_replace("~baseurl~",$baseurl,$configStr2);
$configStr2 = str_replace("~basepath~",$cmspath,$configStr2);
$configStr2 = str_replace("~indexurl~",$indexUrl,$configStr2);
$configStr2 = str_replace("~cookieEncode~",$cookieencode,$configStr2);
$configStr2 = str_replace("~webname~",$webname,$configStr2);
$configStr2 = str_replace("~adminmail~",$adminmail,$configStr2);
// 创建data目录下的缓存配置文件
$fp = fopen(DEDEDATA.'/config.cache.inc.php','w');
// 写入
fwrite($fp,$configStr2);
// 关闭资源
fclose($fp);
// 创建data目录下的缓存配置备份文件
$fp = fopen(DEDEDATA.'/config.cache.bak.php','w');
// 写入
fwrite($fp,$configStr2);
// 关闭资源
fclose($fp);
// 检测mysql版本是否大于4.1
if($mysqlVersion >= 4.1)
{
// 如果大于,则将引擎设置为MyISAM,字符集设置为$dblanag内容
$sql4tmp = "ENGINE=MyISAM DEFAULT CHARSET=".$dblang;
}
//创建数据表
// 初始化定义变量
$query = '';
// 以只读方式打开数据表文件
$fp = fopen(dirname(__FILE__).'/sql-dftables.txt','r');
// while循环-如果文件没有到达末尾 则执行while中的代码
while(!feof($fp))
{
// 从文件指针中读取一行,并去除首尾空格
$line = rtrim(fgets($fp,1024));
// 正则匹配出;号
if(preg_match("#;$#", $line))
{
// 将每行末尾加上\n换行符
$query .= $line."\n";
// 将#@__替换成数据库表前缀
$query = str_replace('#@__',$dbprefix,$query);
// 如果数据库版本小于4.1的情况下
if($mysqlVersion = 4.1) {
// 如果mysql版本大于4.1,则执行此替换
$setupsql = preg_replace("#TYPE=MyISAM#i", $sql41tmp, $setupsql);
}
// 替换rooturl
$setupsql = preg_replace("#_ROOTURL_#i", $rooturl, $setupsql);
// 替换换行符
$setupsql = preg_replace("#[\r\n]{1,}#", "\n", $setupsql);
// 替换表前缀
$setupsql = preg_replace('/#@__/i',$dbprefix,$setupsql);
// 按制表符分割
$sqls = preg_split("#;[ \t]{0,}\n#", $setupsql);
// 遍历执行sql代码
foreach($sqls as $sql) {
if(trim($sql)!='') mysql_query($sql,$conn);
}
// 更新栏目缓存
UpDateCatCache();
} else {
// 没有体验包,提示下载
die("没有体验数据包文件,请检查是否下载.");
}
}
//不安装任何可选模块
if(!isset($modules) || !is_array($modules))
{
//锁定安装程序
// 开始创建锁文件
$fp = fopen($insLockfile,'w');
// 写入内容ok
fwrite($fp,'ok');
// 关闭资源
fclose($fp);
// 包含最后提示文件内容
include('./templates/step-5.html');
// 终止程序执行,如果不安装模块,则程序到此结束
exit();
}
else // 安装模块
{
// 按照逗号分割模块
$module = join(',',$modules);
// 以写入形式打开模块缓存文件
$fp = fopen($moduleCacheFile,'w');
// 写入 <?php fwrite($fp,'<'.'?php'."\r\n");
// 写入模块
fwrite($fp,'$selModule = "'.$module.'"; '."\r\n");
// 写入结束标记
fwrite($fp,'?'.'>');
//如果不能写入缓存文件,退出模块安装
if(!$fp) // 如果无法写入
{
//锁定安装程序
$fp = fopen($insLockfile,'w');
// 写入内容ok
fwrite($fp,'ok');
// 关闭资源
fclose($fp);
// 错误信息
$errmsg = "<font color="red">由于无法写入模块缓存,安装可选模块失败,请登录后在模块管理处安装。</font>";
// 包含最后提示文件内容
include('./templates/step-5.html');
// 终止程序
exit();
}
// 关闭资源
fclose($fp);
// 包含第4
include('./templates/step-4.html');
// 终止
exit();
}
// 终止
exit();
}
/*------------------------
安装可选模块
function _5_SetupModule()
------------------------*/
else if($step==5)
{
// 跳转进入模块安装文件啊
header("location:module-install.php");
exit();
}
/*------------------------
检测数据库是否有效
function _10_TestDbPwd()
------------------------*/
else if($step==10)
{
// 不缓存页面
header("Pragma:no-cache\r\n");
// 不留下页面备份
header("Cache-Control:no-cache\r\n");
// 不过期
header("Expires:0\r\n");
// 连接数据库
$conn = @mysql_connect($dbhost,$dbuser,$dbpwd);
// 如果连接成功
if($conn)
{
// 数据库名称不为空
if(empty($dbname)){
echo "<font color="green">信息正确</font>";
}else{
// 否则提示信息
$info = mysql_select_db($dbname,$conn)?"<font color="red">数据库已经存在,系统将覆盖数据库</font>":"<font color="green">数据库不存在,系统将自动创建</font>";
echo $info;
}
}
else
{
// 连接失败时提示信息
echo "<font color="red">数据库连接失败!</font>";
}
// 关闭数据库
@mysql_close($conn);
// 终止程序执行
exit();
}
// 远程获取体验包
else if($step==11)
{
// 包含更新服务器配置文件
require_once('../data/admin/config_update.php');
// 定义文件名,拼接url
$rmurl = $updateHost."dedecms/demodata.{$s_lang}.txt";
// 按照文件url获取资源
$sql_content = file_get_contents($rmurl);
// 以写入方式创建文件
$fp = fopen($install_demo_name,'w');
// 写入资源内容
if(fwrite($fp,$sql_content))
// 写入成功提示
echo ' <font color="green">[√]</font> 存在(您可以选择安装进行体验)';
else
// 写入失败提示
echo ' <font color="red">[×]</font> 远程获取失败';
// 释放$sql_content变量
unset($sql_content);
// 关闭资源
fclose($fp);
// 终止程序
exit();
}
由上面代码可以看出,主要的安装都是在这个文件中进行的,至于其他的都是辅助性文件,比如sql-dfdata.sql存放数据库数据内容等文件。
总结
安装的话,到此结束了,基本都是接收表单参数,操作文件和数据库的东西。其他的辅助性文件,大家可以自己看看,有空的话,我也会写一些关于那些文件的详解。
文中关于mysql的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《dedecms5.7(织梦)源码解析之程序安装》文章吧,也可关注golang学习网公众号了解相关技术文章。
版本声明
本文转载于:SegmentFault 如有侵犯,请联系study_golang@163.com删除
dedecms5.7(织梦)源码解析之程序安装补全篇
- 上一篇
- dedecms5.7(织梦)源码解析之程序安装补全篇
- 下一篇
- centos7安装mysql及权限配置
查看更多
最新文章
-
- 数据库 · MySQL | 1天前 |
- MySQL数值函数大全及使用技巧
- 117浏览 收藏
-
- 数据库 · MySQL | 3天前 |
- 三种登录MySQL方法详解
- 411浏览 收藏
-
- 数据库 · MySQL | 3天前 |
- MySQL数据备份方法与工具推荐
- 420浏览 收藏
-
- 数据库 · MySQL | 3天前 |
- MySQL数据备份方法与工具推荐
- 264浏览 收藏
-
- 数据库 · MySQL | 4天前 |
- MySQL索引的作用是什么?
- 266浏览 收藏
-
- 数据库 · MySQL | 5天前 |
- MySQL排序原理与实战应用
- 392浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQLwhere条件查询技巧
- 333浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL常用数据类型有哪些?怎么选更合适?
- 234浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL常用命令大全管理员必学30条
- 448浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL高效批量插入数据方法大全
- 416浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL性能优化技巧大全
- 225浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL数据备份4种方法保障安全
- 145浏览 收藏
查看更多
课程推荐
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
查看更多
AI推荐
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3176次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3388次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3417次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4522次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3796次使用
查看更多
相关文章
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- 搞一个自娱自乐的博客(二) 架构搭建
- 2023-02-16 244浏览
-
- B-Tree、B+Tree以及B-link Tree
- 2023-01-19 235浏览
-
- mysql面试题
- 2023-01-17 157浏览
-
- MySQL数据表简单查询
- 2023-01-10 101浏览

