上传2025_04_29备份作为记录

This commit is contained in:
2026-04-24 22:19:24 +08:00
commit 2538bb2a1b
56 changed files with 7567 additions and 0 deletions

22
.gitignore vendored Executable file
View File

@@ -0,0 +1,22 @@
#### 忽略目录
# 数据库
databases/*
public/*.sql
public/*.db
##### 博客文档
# 图片
src/image/*
public/image/*
# 可能未知
public/message/static/src/video/*
# 管理员面板
public/blog/admin/*
# 临时区
public/blog/md0/*
# 临时区

9
LICENSE Normal file
View File

@@ -0,0 +1,9 @@
MIT License
Copyright (c) 2025 skimrme
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

13
README.md Normal file
View File

@@ -0,0 +1,13 @@
<a href="https://ww3.tw/">点击访问</a>
## 2025.7.20
open-ww3-project-ww3-tw
个人博客地址(预计)
---
<br>
**署名**
skimrme

0
public/about/index.html Executable file
View File

13
public/blog/about/index.html Executable file
View File

@@ -0,0 +1,13 @@
<html>
<head>
<title>不想写了</title>
<meta charset="utf-8" lang="zh-CN">
</head>
<body>
忘记写了
<br>
所以暂时就不写了
<p>2025.08.05</p>
<p>over</p>
</body>
</html>

View File

@@ -0,0 +1 @@
google-site-verification: google02f6a3f6004a32c6.html

BIN
public/blog/icon/original.ico Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

120
public/blog/index.php Executable file
View File

@@ -0,0 +1,120 @@
<html>
<head>
<title>首页 | ww3</title>
<meta charset="utf-8" lang="zh-CN">
<meta name="viewport" content="width=1366px, initial-scale=1.0"> <!-- 页面等比例缩小 -->
<link rel="icon" type="image/x-icon" href="./icon/original.ico">
</head>
<body>
<div id="black_block">
<div id="navbar1">
<table border="0" style="background-color: rgba(147, 185, 255, 0.644);">
<tbody>
<tr>
<td id="td_navbar_40px"><b><a href="https://ww3.tw/" id="url_">首页</a></b></td>
<td id="td_navbar_40px"><b><a href="https://ww3.tw/about/" id="url_">关于</a></b></td>
<td id="td_navbar_75px"><b><a href="https://ww3.tw/jumping-message/" id="url_">弹幕留言</a></b></td>
<td id="td_navbar_75px"><b><a href="https://ww3.tw/short-url/" id="url_">短链生成</a></b></td>
<td id="td_navbar_52px"><b><a href="https://gitea.ww3.tw/skimrme/" id="url_">gitea</a></b></td>
<td id="td_navbar_135px"><b><a href="https://ww3.tw/docker-registry/" id="url_">docker-registry</a></b></td>
<td id="td_navbar_40px"><b><a href="https://api.ww3.tw/" id="url_">api</a></b></td>
<td id="td_navbar_40px"><b><a href="https://wiki.ww3.tw/" id="url_">wiki</a></b></td>
</tr>
</tbody>
</table>
</div>
<br>
<!-- 屑站日志 -->
<div id="logs">
<h3>屑站日志:<br></h3>
<font size="3.2">
<table border="0">
<tbody>
<tr>
<td id="td_logs">2025.07.26</td>
<td id="td_logs_content">新增<a href="https://wiki.ww3.tw">wiki</a>页面</td>
</tr>
<tr>
<td id="td_logs">2025.07.20</td>
<td id="td_logs_content">新增<a href="https://gitea.ww3.tw/skimrme">gitea</a><a href="https://ww3.tw/docker-registry/">docker-registry</a>页面</td>
</tr>
<tr>
<td id="td_logs">2025.07.09</td>
<td id="td_logs_content">建立页面</td>
</tr>
</tbody>
</table>
</font>
</div>
<!-- 屑站日志 -->
<div id="js_date"></div>
<script>
</script>
</div>
</body>
</html>
<?php
include "../static/html/black-block.html";
?>
<style>
body
{
background-color: rgba(147, 185, 255, 0.644);
}
#url_
{
text-decoration: none;
color: rgb(0, 0, 0);
}
#logs
{
height: 220px;
width: 450px;
overflow: auto;
background: #ffffffbc;
/* up、right、down、left */
margin: 40px 0px 0px 0px;
}
#td_navbar_40px
{
width: 40px;
}
#td_navbar_52px
{
width: 52px;;
}
#td_navbar_75px
{
width: 75px;
}
#td_navbar_135px
{
width: 135px;
}
#td_logs
{
width: 75px;
padding-bottom: 5px;
}
#td_logs_content
{
color: rgb(132, 132, 132);
padding-left: 10px;
padding-bottom: 5px;
}
#js_date{
color: rgb(55, 0, 255);
font-size: 200%;
}
</style>

47
public/blog/logs.php.text Normal file
View File

@@ -0,0 +1,47 @@
<?php
// 设定数据库路径
$db_path = '/var/www/owp/open-ww3-project-ww3-tw/databases/sqlite/owp.db';
try {
// 连接数据库
$db = new SQLite3($db_path);
// 连接成功输出连接成功
echo "<!--数据库连接成功-->";
// 如果连接成功,但是内部状态有问题
if ($db->lastErrorCode() !==0) {
// 依旧显示为连接失败
die("数据库连接失败");
}
// 内容区
// 执行sql命令 查询表单
$select_id_date_content_from_logs_b_to_s /*查询logs表单中的id date content id从大到小排列*/ = $db->query('SELECT id, date, content FROM logs ORDER BY id DESC'); // 执行查询logs表单中的id date content id从大到小排列的命令
// 循环 写入
while ($row = $select_id_date_content_from_logs_b_to_s->fetchArray(SQLITE3_ASSOC)) {
// 设定 '&nbsp;' 占用19个字符
$nbsp_count = 0;
// 设定变量是 换行 加上 空格重复19个
$br_nbsp = '<br>' . str_repeat('&nbsp;',$nbsp_count);
// 设定变量是 修改 && 为 换行 加上19个空格
$alter_br = str_replace('&&', $br_nbsp, $row['content']);
// 输出 date content
echo "<tr>" . "<td id='td_logs'>" . "<a style='font-size: 18px;'>" . $row['date'] . "</a>" . "</td>" . "<td id='td_logs_content'>" . $alter_br . "<br>" . "</tr>";
}
// 关闭数据库连接
$db->close();
// 捕获php报错
} catch (Exception $e) {
// 依旧显示为连接失败
die("数据库连接失败");
// 关闭数据库连接
$db->close();
}
?>

7
public/blog/md0/114514.md Executable file
View File

@@ -0,0 +1,7 @@
## MD介绍页面
顾名思义、本文件夹下使用的基本都是markdown
最后感谢提供php的md插件的开源制作者
[点击跳转](https://ww3.tw/blog/md/src/php-markdown/)

479
public/blog/md0/MD.php Executable file
View File

@@ -0,0 +1,479 @@
<?php
Header('Content:text/html;charset=utf-8');
?>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<style>
body,ol,ul,li,img,p{
padding:0;
margin:0;
border:none;
}
li{
list-style-type: square;
padding:2px;
}
h1,h2,h3,h4,h5,h6{
margin:10px 0 0 0;
}
h1,h2,h3{
border-bottom:solid 1px #ddd;
}
h1{
padding-bottom:12px;
}
h2{
padding-bottom: 6px;
}
h3{
padding-bottom: 2px;
}
body,ul{
padding:10px 20px;
}
body{
max-width:1024px;
margin:0 auto;
}
blockquote{
border-left:solid 4px #bbb;
background-color:#eee;
min-height:24px;
line-height:24px;
padding:0px 10px;
margin:0;
color:#333;
font-size:12px;
font-style: italic;
font-family: consolas,楷体;
}
table{
width:100%;
}
table,td,th{
border:solid 1px #ddd;
border-collapse: collapse;
padding:10px;
font-family: consolas;
font-size:14px;
}
table{
margin:10px 0;
text-align:center;
}
.table-left{
text-align:left;
}
.table-center{
text-align: center;
}
.table-right{
text-align: right;
}
tr:nth-child(even){
background-color:#eee;
}
code,pre{
border-radius:5px;
border:solid 1px #eee;
background-color:#f9f9f9;
font-family: consolas;
font-size:14px;
box-shadow: 1px 2px 3px #ddd;
}
code{
padding:2px 12px;
display: inline-block;
margin:10px 0;
}
pre{
padding:10px 12px;
overflow-x:auto;
}
</style>
<?php
/*
* flag规则:
* h1-h6 标题
* u1,u2 无序列表
* ol 有序列表
* p 普通文本
* code 代码
* table 文本
* check 选择
* uncheck 未选择
* quote 引用
* img 图片
* url 网址
* bold 加粗
* italia 斜体
* el 空行
*
* idel 闲置
*/
class MD{
private $file; //当前文件
private $mdGen; //生成器
private $flag; //当前标志
private $flag_pre; //上一次的flag
private $flag_like; //假定类型
private $line_count; //总行数
private $lines; //所有行
private $buf; //缓存行
public function __construct($filename){
$this->file = $filename; //设置当前文件
$this->mdGen = $this->content($filename); //获取生成器
$this->flag = 'idel'; //闲置
$this->lines = array(); //所有行状态
$this->line_count = 0; //行数归0
}
private function content($file){ //获取生成器
if(file_exists($file)){
$fh = fopen($file,"r");
while(!feof($fh)){
yield fgets($fh);
}
fclose($fh);
}else{
return null;
}
}
//遍历每一个字符
private function every($str){
$l = strlen($str);
for($i=0;$i<$l;$i++)
if(ord($str[$i])<0x80)
yield $str[$i];
else{
yield $str[$i].$str[$i+1].$str[$i+2]; //三个字节
$i+=2;
}
}
//解析
private function parse(){
$ctnt = $this->mdGen; //生成器
$ret=array();
if($ctnt != null){
$ret = array();
foreach($ctnt as $line){
if($this->flag != 'code')
$line=ltrim($line); //删除左边
if(strlen($line)){
$ch = $line[0]; //判断第一个字符
$type=ctype_punct($ch);//标点符号
if($this->flag !== 'code') $line=preg_replace('/\s{2,}$/','<br>',$line); //非代码模式
$ret[] = $this->parseLine($line,$type); //解析行
}else{ //空行
switch($this->flag){
case 'ul':
case 'ol':
$ret[]="</$this->flag>";
$this->flag_pre = $this->flag;
$this->flag = 'idel';
break;
case 'table':
$this->flag = 'idel';
$ret[]='</table>';
break;
default:
if($this->flag != 'el') $ret[] = '<br>';
$this->flag = 'el'; //空行
}
}
}
}
$this->lines = $ret;
return $ret;
}
//生成blockquote
private function genQuote($level,$content){
if($level<=0) return "";
return str_repeat('<blockquote>',$level).$content.str_repeat('</blockquote>',$level);
}
//检查是否处于某个状态,默认检查是否处于代码状态
private function check($value='code'){
return ($this->flag == $value);
}
/**
* 生成一行新的表格列
* $data:需要输入的数据
* $type:生成类型
* $wrap:最快层包裹
* $sep:分隔符
*/
private function genRow($data,$type='td',$wrap='tr',$sep='|'){
$ret='';
$mat = explode($sep,$data);
foreach($mat as $elem)
$ret.="<$type>".$elem."</$type>";
return "<$wrap>".$ret."</$wrap>";
}
/**
* 解析行内元素
* bold,italic,code,link,pic
*/
private function parseInner($str){
$str=preg_replace('/\*\*\*([^\*\n\r]+)\*\*\*/','<b><i>\1</i></b>',$str); //加粗并加斜字体
$str=preg_replace('/\*\*([^\*\n\r]+)\*\*/','<b>\1</b>',$str); //加粗字体
$str=preg_replace('/\*([^\*\n\r]+)\*/','<i>\1</i>',$str); //斜体
$str=preg_replace('/```([^`\n\r]+)```/','<code>\1</code>',$str); //代码
$str=preg_replace('/`([^`\n\r]+)`/','<code>\1</code>',$str); //代码
$str=preg_replace('/!\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<img src="\2" alt="\1" title="\1">',$str); //图片
$str=preg_replace('/\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<a href="\2">\1</a>',$str); //图片
return $str;
}
/**
* 按照给定规则解析字符串:
* type:
* true 符号
* false 文字
* 返回:
* array('type'=>类型,'parts'=>array(...))
*/
private function parseLine($str,$type){
if(strlen($str) == 0){
return array('type'=>'p','parts'=>[]); //返回空段
}
$valid_str = rtrim($str); //去除右边的空格
$str = $valid_str;
$output = ''; //需要输出的字符串
if($type == true){ //标点
$type_str = ''; //类型字符串
$data_str = '';
$flag = 0;
foreach($this->every($str) as $ch){
if(!ctype_punct($ch)){
$flag = 1;
}
if($flag == 0)
$type_str .= $ch;
else
$data_str .= $ch;
}
switch($type_str){
case '#':
$wrap = 'h1';
$this->flag_like = 'h1';
break;
case '##':
$wrap = 'h2';
$this->flag_like = 'h2';
break;
case '###':
$wrap = 'h3';
$this->flag_like = 'h3';
break;
case '####':
$wrap = 'h4';
$this->flag_like = 'h4';
break;
case '#####':
$wrap = 'h5';
$this->flag_like = 'h5';
break;
case '######':
$wrap = 'h6';
$this->flag_like = 'h6';
break;
case '+':
case '-':
$wrap = 'li';
$this->flag_like = 'ul';
if($this->flag != 'code'){
if($this->flag != 'ul'){
$this->flag_pre = $this->flag;
$this->flag = 'ul';
$output.='<ul>';
}
}
break;
case '```': //代码模式,不进行干扰
if($this->flag != 'code'){ //不为code,判断是否为单行代码
$output.='<pre>';
if(preg_match('/^\s*```([^`]+)```([^\s]+)\s*$/',$str,$mat)){ //单行代码
$output.="$mat[1]</pre>$mat[2]";
$str = '';
$data_str = '';
}else{
$this->flag_pre = $this->flag;
$this->flag = 'code'; //代码
}
}else{
$output.='</pre>';
$this->flag_pre = $this->flag;
$this->flag = 'idel'; //闲置
}
break;
case '[':
if(preg_match('/^\[\s\]\s*(.+)$/',$str,$mat)){ //选择
$output.="<label><input type='checkbox' disabled> $mat[1]</label><br>";
$this->flag_like = 'check';
}else if(preg_match('/^\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){ //未选择
$output.="<a href='$mat[2]'>$mat[1]</a>".$this->parseInner($mat[3]);
$this->flag_like = 'a'; //网址
}else if(preg_match('/^\s*(\[\d+\]\:)\s+([^\s]+)\s+([^\r\n]+)\s*$/',$str,$mat)){ //外部资料
$output.="$mat[1] <a href='$mat[2]'>$mat[3]</a>";
}else{
$output.=$str;
}
break;
case '[-]':
$output.="<label><input type='checkbox' checked disabled>$data_str</label><br>";
$this->flag_like = 'check';
break;
case '![':
if(preg_match('/^!\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){
$output.="<img src='$mat[2]' alt='$mat[1]'>".$this->parseInner($mat[3]);
$this->flag_like = 'img';
}else{
$this->flag_like = 'p'; //没有模式
$output.="$str";
}
break;
case '*': //斜体
if(preg_match('/^\*(.*)\*([^\s]+)\s*$/',$str,$mat)){
$output.=$this->parseInner($str);
$this->flag_like = 'i';
}else if(preg_match('/^\s*\*\s+(.+)\s*$/',$str,$mat)){
$str=$mat[1];
$wrap = 'li';
$this->flag_like = 'ul';
if($this->flag != 'code'){
if($this->flag != 'ul'){
$this->flag_pre = $this->flag;
$this->flag = 'ul';
$output.='<ul>';
}
}
}
break;
case '**': //粗体
if(preg_match('/^\*\*(.*)\*\*/',$str,$mat)){
$output.=$this->parseInner($str);
$this->flag_like = 'b';
}
break;
case '<':
$output.=$str;
$this->flag_like = 'html';
break;
default:
if(!$this->check()){ //非代码模式
if(preg_match('/^>+$/',$type_str)){ //引用
$level = strlen($type_str);
$this->flag_like = 'quote';
$output.=$this->genQuote($level,$data_str); //引用
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格确定格式---|---|....
if($this->flag == 'table'){
$this->flag_like = 'table';
$output.='<table><thead>'.$this->genRow($this->buf,'th').'</thead><tbody>';
}else{ //非表格格式,上一行没有标题
$this->flag_like = 'p'; //没有格式
$output.=$this->buf;
$this->buf = '';
}
}else if(preg_match('/^\s*(\-{3,})|(\={3,})$/',$type_str)){ //hr
$output.='<hr>';
$this->flag_like = 'hr';
break;
}else{
$this->flag_like = 'p';
$output.=$str.'<br>';
}
}
}
$br = '';
preg_match('/^(.*)(<br\s*\/?>)?$/',$data_str,$mat);
$data_str = htmlspecialchars($mat[1]);
if(!$this->check()){ //代码
if(!empty($wrap)) $output.="<$wrap>$mat[1]</$wrap>".(isset($mat[2])?'<br>':'');
}else if($type_str!='```'){
$output.=htmlspecialchars($str).'<br>';
}
}else{ //首个非空字符不为符号
if($this->flag == 'code'){ //代码,直接输出
$str=str_replace("\t",' ',$str);
$output.=htmlspecialchars($str).'<br>';
}else if(is_numeric($str[0])){ //可能为有序列表,也可能是表格
if(preg_match('/^\s*\d+\.\s+([^\r\n]+)\s*$/',$str)){ //有序列表
$this->flag_like = 'ol';
$output.=$str;
}else{
$this->flag_like = 'idel';
foreach($this->every($str) as $ch){
$output.=$ch;
}
}
$output.='<br>';
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格
$mat = explode('|',$str);
if($this->flag!='table'){ //进入表格
$this->buf = $str;
$this->flag_like = 'table';
$wrap = '';
}else{
$output.=$this->genRow($str);
}
//echo $mat[0].'<br>';
//var_dump($mat);
}else{ //其他
$this->flag = 'p';
$output.=$str;
}
}
if(!$this->check()){ //不为代码,设置flag
$this->flag_pre = $this->flag;
$this->flag = $this->flag_like;
if($this->flag_pre == 'table' && $this->flag != 'table')
$output='</table>'.$output;
else if($this->flag_pre == 'ul' && $this->flag != 'ul'){
$output='</ul>'.$output;
}
}
return $this->parseInner($output); //输出需要输出的内容
}
//获取输出内容
public function output(){
$this->parse();
echo implode('',$this->lines);
}
}

5
public/blog/md0/index.php Executable file
View File

@@ -0,0 +1,5 @@
<?php
require './MD.php';
$md=new MD('114514.md');
$md->output();

View File

@@ -0,0 +1,479 @@
<?php
Header('Content:text/html;charset=utf-8');
?>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<style>
body,ol,ul,li,img,p{
padding:0;
margin:0;
border:none;
}
li{
list-style-type: square;
padding:2px;
}
h1,h2,h3,h4,h5,h6{
margin:10px 0 0 0;
}
h1,h2,h3{
border-bottom:solid 1px #ddd;
}
h1{
padding-bottom:12px;
}
h2{
padding-bottom: 6px;
}
h3{
padding-bottom: 2px;
}
body,ul{
padding:10px 20px;
}
body{
max-width:1024px;
margin:0 auto;
}
blockquote{
border-left:solid 4px #bbb;
background-color:#eee;
min-height:24px;
line-height:24px;
padding:0px 10px;
margin:0;
color:#333;
font-size:12px;
font-style: italic;
font-family: consolas,楷体;
}
table{
width:100%;
}
table,td,th{
border:solid 1px #ddd;
border-collapse: collapse;
padding:10px;
font-family: consolas;
font-size:14px;
}
table{
margin:10px 0;
text-align:center;
}
.table-left{
text-align:left;
}
.table-center{
text-align: center;
}
.table-right{
text-align: right;
}
tr:nth-child(even){
background-color:#eee;
}
code,pre{
border-radius:5px;
border:solid 1px #eee;
background-color:#f9f9f9;
font-family: consolas;
font-size:14px;
box-shadow: 1px 2px 3px #ddd;
}
code{
padding:2px 12px;
display: inline-block;
margin:10px 0;
}
pre{
padding:10px 12px;
overflow-x:auto;
}
</style>
<?php
/*
* flag规则:
* h1-h6 标题
* u1,u2 无序列表
* ol 有序列表
* p 普通文本
* code 代码
* table 文本
* check 选择
* uncheck 未选择
* quote 引用
* img 图片
* url 网址
* bold 加粗
* italia 斜体
* el 空行
*
* idel 闲置
*/
class MD{
private $file; //当前文件
private $mdGen; //生成器
private $flag; //当前标志
private $flag_pre; //上一次的flag
private $flag_like; //假定类型
private $line_count; //总行数
private $lines; //所有行
private $buf; //缓存行
public function __construct($filename){
$this->file = $filename; //设置当前文件
$this->mdGen = $this->content($filename); //获取生成器
$this->flag = 'idel'; //闲置
$this->lines = array(); //所有行状态
$this->line_count = 0; //行数归0
}
private function content($file){ //获取生成器
if(file_exists($file)){
$fh = fopen($file,"r");
while(!feof($fh)){
yield fgets($fh);
}
fclose($fh);
}else{
return null;
}
}
//遍历每一个字符
private function every($str){
$l = strlen($str);
for($i=0;$i<$l;$i++)
if(ord($str[$i])<0x80)
yield $str[$i];
else{
yield $str[$i].$str[$i+1].$str[$i+2]; //三个字节
$i+=2;
}
}
//解析
private function parse(){
$ctnt = $this->mdGen; //生成器
$ret=array();
if($ctnt != null){
$ret = array();
foreach($ctnt as $line){
if($this->flag != 'code')
$line=ltrim($line); //删除左边
if(strlen($line)){
$ch = $line[0]; //判断第一个字符
$type=ctype_punct($ch);//标点符号
if($this->flag !== 'code') $line=preg_replace('/\s{2,}$/','<br>',$line); //非代码模式
$ret[] = $this->parseLine($line,$type); //解析行
}else{ //空行
switch($this->flag){
case 'ul':
case 'ol':
$ret[]="</$this->flag>";
$this->flag_pre = $this->flag;
$this->flag = 'idel';
break;
case 'table':
$this->flag = 'idel';
$ret[]='</table>';
break;
default:
if($this->flag != 'el') $ret[] = '<br>';
$this->flag = 'el'; //空行
}
}
}
}
$this->lines = $ret;
return $ret;
}
//生成blockquote
private function genQuote($level,$content){
if($level<=0) return "";
return str_repeat('<blockquote>',$level).$content.str_repeat('</blockquote>',$level);
}
//检查是否处于某个状态,默认检查是否处于代码状态
private function check($value='code'){
return ($this->flag == $value);
}
/**
* 生成一行新的表格列
* $data:需要输入的数据
* $type:生成类型
* $wrap:最快层包裹
* $sep:分隔符
*/
private function genRow($data,$type='td',$wrap='tr',$sep='|'){
$ret='';
$mat = explode($sep,$data);
foreach($mat as $elem)
$ret.="<$type>".$elem."</$type>";
return "<$wrap>".$ret."</$wrap>";
}
/**
* 解析行内元素
* bold,italic,code,link,pic
*/
private function parseInner($str){
$str=preg_replace('/\*\*\*([^\*\n\r]+)\*\*\*/','<b><i>\1</i></b>',$str); //加粗并加斜字体
$str=preg_replace('/\*\*([^\*\n\r]+)\*\*/','<b>\1</b>',$str); //加粗字体
$str=preg_replace('/\*([^\*\n\r]+)\*/','<i>\1</i>',$str); //斜体
$str=preg_replace('/```([^`\n\r]+)```/','<code>\1</code>',$str); //代码
$str=preg_replace('/`([^`\n\r]+)`/','<code>\1</code>',$str); //代码
$str=preg_replace('/!\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<img src="\2" alt="\1" title="\1">',$str); //图片
$str=preg_replace('/\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<a href="\2">\1</a>',$str); //图片
return $str;
}
/**
* 按照给定规则解析字符串:
* type:
* true 符号
* false 文字
* 返回:
* array('type'=>类型,'parts'=>array(...))
*/
private function parseLine($str,$type){
if(strlen($str) == 0){
return array('type'=>'p','parts'=>[]); //返回空段
}
$valid_str = rtrim($str); //去除右边的空格
$str = $valid_str;
$output = ''; //需要输出的字符串
if($type == true){ //标点
$type_str = ''; //类型字符串
$data_str = '';
$flag = 0;
foreach($this->every($str) as $ch){
if(!ctype_punct($ch)){
$flag = 1;
}
if($flag == 0)
$type_str .= $ch;
else
$data_str .= $ch;
}
switch($type_str){
case '#':
$wrap = 'h1';
$this->flag_like = 'h1';
break;
case '##':
$wrap = 'h2';
$this->flag_like = 'h2';
break;
case '###':
$wrap = 'h3';
$this->flag_like = 'h3';
break;
case '####':
$wrap = 'h4';
$this->flag_like = 'h4';
break;
case '#####':
$wrap = 'h5';
$this->flag_like = 'h5';
break;
case '######':
$wrap = 'h6';
$this->flag_like = 'h6';
break;
case '+':
case '-':
$wrap = 'li';
$this->flag_like = 'ul';
if($this->flag != 'code'){
if($this->flag != 'ul'){
$this->flag_pre = $this->flag;
$this->flag = 'ul';
$output.='<ul>';
}
}
break;
case '```': //代码模式,不进行干扰
if($this->flag != 'code'){ //不为code,判断是否为单行代码
$output.='<pre>';
if(preg_match('/^\s*```([^`]+)```([^\s]+)\s*$/',$str,$mat)){ //单行代码
$output.="$mat[1]</pre>$mat[2]";
$str = '';
$data_str = '';
}else{
$this->flag_pre = $this->flag;
$this->flag = 'code'; //代码
}
}else{
$output.='</pre>';
$this->flag_pre = $this->flag;
$this->flag = 'idel'; //闲置
}
break;
case '[':
if(preg_match('/^\[\s\]\s*(.+)$/',$str,$mat)){ //选择
$output.="<label><input type='checkbox' disabled> $mat[1]</label><br>";
$this->flag_like = 'check';
}else if(preg_match('/^\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){ //未选择
$output.="<a href='$mat[2]'>$mat[1]</a>".$this->parseInner($mat[3]);
$this->flag_like = 'a'; //网址
}else if(preg_match('/^\s*(\[\d+\]\:)\s+([^\s]+)\s+([^\r\n]+)\s*$/',$str,$mat)){ //外部资料
$output.="$mat[1] <a href='$mat[2]'>$mat[3]</a>";
}else{
$output.=$str;
}
break;
case '[-]':
$output.="<label><input type='checkbox' checked disabled>$data_str</label><br>";
$this->flag_like = 'check';
break;
case '![':
if(preg_match('/^!\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){
$output.="<img src='$mat[2]' alt='$mat[1]'>".$this->parseInner($mat[3]);
$this->flag_like = 'img';
}else{
$this->flag_like = 'p'; //没有模式
$output.="$str";
}
break;
case '*': //斜体
if(preg_match('/^\*(.*)\*([^\s]+)\s*$/',$str,$mat)){
$output.=$this->parseInner($str);
$this->flag_like = 'i';
}else if(preg_match('/^\s*\*\s+(.+)\s*$/',$str,$mat)){
$str=$mat[1];
$wrap = 'li';
$this->flag_like = 'ul';
if($this->flag != 'code'){
if($this->flag != 'ul'){
$this->flag_pre = $this->flag;
$this->flag = 'ul';
$output.='<ul>';
}
}
}
break;
case '**': //粗体
if(preg_match('/^\*\*(.*)\*\*/',$str,$mat)){
$output.=$this->parseInner($str);
$this->flag_like = 'b';
}
break;
case '<':
$output.=$str;
$this->flag_like = 'html';
break;
default:
if(!$this->check()){ //非代码模式
if(preg_match('/^>+$/',$type_str)){ //引用
$level = strlen($type_str);
$this->flag_like = 'quote';
$output.=$this->genQuote($level,$data_str); //引用
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格确定格式---|---|....
if($this->flag == 'table'){
$this->flag_like = 'table';
$output.='<table><thead>'.$this->genRow($this->buf,'th').'</thead><tbody>';
}else{ //非表格格式,上一行没有标题
$this->flag_like = 'p'; //没有格式
$output.=$this->buf;
$this->buf = '';
}
}else if(preg_match('/^\s*(\-{3,})|(\={3,})$/',$type_str)){ //hr
$output.='<hr>';
$this->flag_like = 'hr';
break;
}else{
$this->flag_like = 'p';
$output.=$str.'<br>';
}
}
}
$br = '';
preg_match('/^(.*)(<br\s*\/?>)?$/',$data_str,$mat);
$data_str = htmlspecialchars($mat[1]);
if(!$this->check()){ //代码
if(!empty($wrap)) $output.="<$wrap>$mat[1]</$wrap>".(isset($mat[2])?'<br>':'');
}else if($type_str!='```'){
$output.=htmlspecialchars($str).'<br>';
}
}else{ //首个非空字符不为符号
if($this->flag == 'code'){ //代码,直接输出
$str=str_replace("\t",' ',$str);
$output.=htmlspecialchars($str).'<br>';
}else if(is_numeric($str[0])){ //可能为有序列表,也可能是表格
if(preg_match('/^\s*\d+\.\s+([^\r\n]+)\s*$/',$str)){ //有序列表
$this->flag_like = 'ol';
$output.=$str;
}else{
$this->flag_like = 'idel';
foreach($this->every($str) as $ch){
$output.=$ch;
}
}
$output.='<br>';
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格
$mat = explode('|',$str);
if($this->flag!='table'){ //进入表格
$this->buf = $str;
$this->flag_like = 'table';
$wrap = '';
}else{
$output.=$this->genRow($str);
}
//echo $mat[0].'<br>';
//var_dump($mat);
}else{ //其他
$this->flag = 'p';
$output.=$str;
}
}
if(!$this->check()){ //不为代码,设置flag
$this->flag_pre = $this->flag;
$this->flag = $this->flag_like;
if($this->flag_pre == 'table' && $this->flag != 'table')
$output='</table>'.$output;
else if($this->flag_pre == 'ul' && $this->flag != 'ul'){
$output='</ul>'.$output;
}
}
return $this->parseInner($output); //输出需要输出的内容
}
//获取输出内容
public function output(){
$this->parse();
echo implode('',$this->lines);
}
}

View File

@@ -0,0 +1,5 @@
<?php
require '../MD.php';
$md=new MD('test.md');
$md->output();

View File

@@ -0,0 +1,81 @@
# 一级标题
## 二级标题
### 三级标题
#### 四级标题
##### 五级标题
###### 六级标题
*斜体*
**粗体**
- 项目1
- 项目2
- 项目3
- 项目4
+ 项目5
+ 项目6
+ 项目7
1. apple
2. boy
3. cat
[ ] 选择1
[-] 选择2
[-] 选择3
[ ] 选择4
---
```c
#include<stdio.h>
void test();
int main(){
printf("Hello,World!\n");
return 0;
}
void test(){
printf("Hello,World!");
}
```
[百度](https://www.baidu.com)
![图片](https://www.baidu.com/favicon.ico)
**blockquote使用方法**
>引言,这是一句引言
>Hello,World!
>>二级引言
>>>三级引言
apple|boy|cat
---|---|---
a|b|c
d|e|f
<table>
<thead>
<tr>
<th>Apple</th>
<th>Boy</th>
<th>Cat</th>
</tr>
</thead>
<tbody>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
</tr>
<tr>
<td>d</td>
<td>e</td>
<td>f</td>
</tr>
</tbody>
</table>
> I o u
> This is just a test...
>> Hello
> World

View File

@@ -0,0 +1 @@
<meta http-equiv="refresh" content="0.1;url=https://github.com/ixysoft/php-markdown">

100
public/blog/post/index.php Normal file
View File

@@ -0,0 +1,100 @@
<head>
<link rel="icon" type="image/x-icon" href="https://ww3.tw/blog/icon/original.ico">
<title>文章列表</title> <!-- 标题 -->
</head>
<body id=wallpaper>
<!-- 背景 -->
<div id="div_1">
<?php
// 设定数据库路径
$db_path = '/var/www/owp/open-ww3-project-ww3-tw/databases/sqlite/owp.db';
try {
// 连接数据库
$db = new SQLite3($db_path);
// 连接成功输出连接成功
echo "<!--数据库连接成功-->";
// 如果连接成功,但是内部状态有问题
if ($db->lastErrorCode() !==0) {
// 依旧显示为连接失败
die("数据库连接失败");
}
// 内容区
// 执行sql命令 查询表单
$select_id_date_title_from_posts_btos /*查询posts表单中的id date title id从大到小排列*/ = $db->query('SELECT id, date, title FROM posts ORDER BY id DESC'); // 执行查询posts表单中的id date title id从大到小排列的命令
// 循环 写入
echo "<a href='https://ww3.tw' style='background-color: rgba(147, 185, 255, 0.644);position: absolute;'>返回首页</a>";
echo "<center><b><h2>全部文章</h2></b></center>";
echo "<br>";
echo "文章如下↓";
echo "<br>";
echo "<br>";
echo "<br>";
echo "<div id='content'>"; # 内容排版
while ($row = $select_id_date_title_from_posts_btos->fetchArray(SQLITE3_ASSOC)) {
echo "文章id: " . $row['id'] . "<br>";
echo $row['date'] . "&nbsp;&nbsp;&nbsp;" . "文章标题: " . $row['title'] . "<br>";
echo "<a href='https://ww3.tw/blog/post/s/?id=" . $row['id'] . "'>页面跳转</a><br><br>";
}
echo "</div>"; # 内容排版
// 关闭数据库连接
$db->close();
// 捕获php报错
} catch (Exception $e) {
// 依旧显示为连接失败
die("数据库连接失败");
// 关闭数据库连接
$db->close();
}
// 随机变换图床api
$wallpaper_apis = ['https://www.loliapi.com/acg/pc/', 'https://api.sretna.cn/api/pc.php', 'https://www.api.plus/API/dongman/', 'https://moe.jitsu.top/img/?sort=pc', 'https://www.dmoe.cc/random.php', 'https://api.r10086.com/樱道随机图片api接口.php?图片系列=猫娘1', 'https://api.mtyqx.cn/tapi/random.php', 'https://api.ww3.tw/touhou'];
$suiji_wallpaper = rand(0, count($wallpaper_apis) - 1);
$wallpaper = $wallpaper_apis[$suiji_wallpaper];
// 显示图床url在页面
echo "<div id='wallpaper_url'>图片来源: " . $wallpaper . "</div>";
?>
</div>
</body>
<style>
#wallpaper {
background-image: url(<?php
echo $wallpaper;
?>); /*图片地址*/ /* https://api.sretna.cn/api/pc.php */
background-repeat: no-repeat; /*禁止平铺*/
background-size: 100% 100%; /*图片占满100%*/
margin: 0; /* 外边框为0 */
/*padding: 0;*/
}
#div_1 {
height: 100%;
color: rgb(0, 0, 0);
font-size: 19px;
background-color: rgba(169, 169, 169, 0.48);
}
#content {
/* up、right、down、left */
margin: 0px 0px 0px 100px;
}
#wallpaper_url {
color: rgba(255, 0, 0, 0.354);
/* up、right、down、left */
margin: 20% 0px 0px 75%;
}
</style>

View File

@@ -0,0 +1,100 @@
<?php
// 设置最大接受id
const MAX_ARTICLE_ID = 100000;
// 获取搜索栏url的id
$post_id = $_GET['id'] ?? null;
// 设定数据库路径
$db_path = '/var/www/owp/open-ww3-project-ww3-tw/databases/sqlite/owp.db';
/**
* 2. 严格的输入验证 (健壮性检查)
* 拦截所有非数字、无效范围或为空的输入
*/
if (
empty($post_id) ||
!is_numeric($post_id) ||
(int)$post_id <= 0 ||
(int)$post_id > MAX_ARTICLE_ID
) {
http_response_code(400); // HTTP 400 Bad Request
$error_msg = "错误:文章 ID 格式不正确。ID 必须是 1 到 " . MAX_ARTICLE_ID . " 之间的整数。";
die($error_msg);
}
// 通过检查后,将 ID 强制转换为整数
$post_id = (int)$post_id;
try {
/**
* 3. 连接 SQLite 数据库
* 注意:如果 PHP 运行用户没有读取此路径文件的权限,这里会失败。
*/
$db = new SQLite3($db_path);
/**
* 4. 准备 SQL 查询语句 (核心安全防线:预处理语句)
* 使用占位符 :id 代替用户输入。
*/
$sql = 'SELECT title, content FROM posts WHERE id = :id';
// 准备语句
$stmt = $db->prepare($sql);
// 绑定参数:将 :id 替换为 $post_id 的值,并明确指定它是一个整数类型
$stmt->bindValue(':id', $post_id, SQLITE3_INTEGER);
/**
* 5. 执行查询并获取结果
*/
$result = $stmt->execute();
// 从结果集中获取一行数据
$row = $result->fetchArray(SQLITE3_ASSOC);
/**
* 6. 显示内容或 404 错误
*/
if ($row) {
// 使用 htmlspecialchars() 函数防止 XSS 攻击
$title = $row['title'];
$content = $row['content'];
// --- 页面输出开始 ---
echo "<!DOCTYPE html>";
echo "<html lang='zh-CN'>";
echo "<head><meta charset='UTF-8'><title>{$title}</title></head>";
echo "<body>";
echo "<a href='https://ww3.tw'>返回主页</a>";
echo "<h1>{$title}</h1>";
// nl2br 用于将换行符转换成 <br>
echo "<article>" . nl2br($content) . "</article>";
echo "</body>";
echo "</html>";
// --- 页面输出结束 ---
} else {
// 文章未找到
http_response_code(404); // 404 Not Found
echo "<h1>404 Not Found</h1>";
echo "<p>抱歉ID 为 {$post_id} 的文章不存在。</p>";
}
/**
* 7. 清理资源
*/
$db->close();
//$stmt->close();
} catch (Exception $e) {
// 处理异常
http_response_code(500); // 500 Internal Server Error
error_log("SQLite 错误: " . $e->getMessage());
die("系统错误,请稍后重试。");
}
?>

7
public/blog/robots.txt Normal file
View File

@@ -0,0 +1,7 @@
User-agent: *
Allow: /
Disallow: /admin/
Sitemap: https://open-ww3-project.ww3.tw/blog/sitemap.xml

23
public/blog/sitemap.xml Normal file
View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://open-ww3-project.ww3.tw/blog/</loc>
<lastmod>2025-12-12</lastmod>
<priority>1.0</priority>
</url>
<url>
<loc>https://open-ww3-project.ww3.tw/blog/about/</loc>
<lastmod>2025-12-12</lastmod>
<priority>0.8</priority>
</url>
<url>
<loc>https://open-ww3-project.ww3.tw/blog/post/</loc>
<lastmod>2025-12-12</lastmod>
<priority>0.8</priority>
</url>
<url>
<loc>https://open-ww3-project.ww3.tw/blog/test.html</loc>
<lastmod>2025-12-13</lastmod>
<priority>0.1</priority>
</url>
</urlset>

View File

@@ -0,0 +1,58 @@
/* css页面蓝图 */
/* 外部背景 */
html, body {
height: 100%;
width: 100%;
margin: 0; /*外边框*/
padding: 0; /*内边框*/
overflow: hidden; /* 防止滚动条 */
background-color: #333; /* 背景颜色 */
}
/* 内部容器 */
#app-canvas {
width: 1280px;
height: 800px;
background-color: rgba(147, 185, 255, 0.644);
border: 5px solid #0056b3; /* 定义边框 5px 实线 蓝色 */
/* transform-origin: 0 0; /* 定义缩放起点 左上角 */
position:fixed; /* 固定页面,不滚动 */
left: 50%; /* 调整左边缘位置到中央 */
top: 50%; /* 调整上边缘位置到中央 */
padding: 30px; /* 内部间距 30px */
}
header {
margin-bottom: 30px; /* 外部间距 30px */
text-align: center; /* 文字居中 */
}
h1 {
font-size: 48px;
color: #fff;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
#content-area {
display: flex;
justify-content: space-around;
gap: 40px;
}
/* 自带 */
.box {
width: 500px;
height: 600px;
background-color: #ffffffcc;
border: 1px solid #ccc;
padding: 20px;
font-size: 20px;
text-align: left;
overflow: auto;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

View File

@@ -0,0 +1,29 @@
// js目前不会先靠ai
function resizeCanvas() {
// 定义设计基准尺寸
const designWidth = 1280;
const designHeight = 800;
// 获取当前浏览器视口尺寸
const currentWidth = window.innerWidth;
const currentHeight = window.innerHeight;
const canvas = document.getElementById('app-canvas');
// 计算缩放比例
const scaleX = currentWidth / designWidth;
const scaleY = currentHeight / designHeight;
const scaleFactor = Math.min(scaleX, scaleY);
// 确保元素中心与 left: 50%; top: 50%; 对齐
canvas.style.transform = `translate(-50%, -50%) scale(${scaleFactor})`;
}
// 首次加载时执行
document.addEventListener('DOMContentLoaded', resizeCanvas);
// 监听窗口大小变化时执行,保持动态缩放
window.addEventListener('resize', resizeCanvas);
// 确保在某些情况下也能正确初始化
resizeCanvas();

5033
public/blog/test.html Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,45 @@
<html>
<head>
<title>推荐网页</title>
<meta charset="utf-8" lang="zh-CN">
</head>
<body>
<center>
<h3>漫画</h3>
<th>
<td id="font_a">
<a href="https://xmanhua.com/">xmanhua</a>
</td>
</th>
<th>
<td id="font_a">
<a href="https://komiic.com/">komiic</a>
</td>
</th>
<th>
<td id="font_a">
<a href="https://mangadex.org/">mangadex</a>
</td>
</th>
<th>
<td id="font_a">
<a href="https://mangabz.com/">mangabz</a>
</td>
</th>
<h3>动漫</h3>
<th>
<td id="font_a">
<a href="https://www.agedm.com">age动漫 | 尽量不要开梯</a>
</td>
</th>
</center>
</body>
</html>
<style>
#font_a {
width: 50px;
}
</style>

1
public/blog/video.html Normal file
View File

@@ -0,0 +1 @@
<iframe src="//player.bilibili.com/player.html?isOutside=true&aid=115578442356850&bvid=BV12CCdBkEL6&cid=34120008494&p=1&autoplay=0" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" style="width: 100%; height: 100%;"></iframe>

View File

@@ -0,0 +1,25 @@
<?php
// 1. 定义你的 Docker Registry 地址
// 请将 'http://localhost:5000' 替换为你的实际 Registry 地址。
// 例如:如果你的 Registry 是 'my-registry.io',就改为 'https://my-registry.io'
$registryUrl = "https://regw.ww3.tw/";
// 2. 定义你要获取的 API 端点
// 这个端点用于获取所有仓库列表。
$endpoint = "/v2/_catalog";
// 3. 组合完整的 URL
$fullUrl = $registryUrl . $endpoint;
// 4. 使用 file_get_contents() 获取 JSON 内容
// @ 符号用来抑制可能出现的错误或警告,让输出更干净。
$jsonContent = @file_get_contents($fullUrl);
// 5. 直接输出 JSON 内容
// 如果成功获取到内容,就直接打印出来。
// 如果获取失败会打印一个空字符串或PHP的错误信息如果没用@抑制)。
header('Content-Type: application/json'); // 告诉浏览器这是一个JSON响应
echo $jsonContent;
?>

View File

@@ -0,0 +1,11 @@
<html>
<head>
<title>docker-registry</title>
<meta charset="utf-8" lang="zh-CN">
</head>
<body>
<a href="./all-images/index.php">查看所有镜像</a>
<p>tags/list</p>
</body>
</html>

1
public/index.html Executable file
View File

@@ -0,0 +1 @@
<meta http-equiv="refresh" content="0.1;url=https://open-ww3-project.ww3.tw/blog/">

29
public/index.php Normal file
View File

@@ -0,0 +1,29 @@
<!-- 主路由配置 -->
<?php
$request_uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
// 定义条件
$found_route = false;
switch($request_uri){
case '/':
include './re_blog.php';
exit(); // 执行成功立即结束
break;
}
// posts 路由
// 整改中
// 所有路由匹配结束后,检查是否找到路由
if (!$found_route) {
// 设置 HTTP 状态码为 404
header("HTTP/1.0 404 Not Found");
// 包含 404 页面文件
//exit();
include "../src/views/error/404.html";
exit(); // 执行成功立即结束
}

29
public/index.php.back Executable file
View File

@@ -0,0 +1,29 @@
<!-- 主路由配置 -->
<?php
$request_uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
// 定义条件
$found_route = false;
switch($request_uri){
case '/':
include './re_blog.php';
exit(); // 执行成功立即结束
break;
}
// posts 路由
// 整改中
// 所有路由匹配结束后,检查是否找到路由
if (!$found_route) {
// 设置 HTTP 状态码为 404
header("HTTP/1.0 404 Not Found");
// 包含 404 页面文件
//exit();
include "../src/views/error/404.html";
exit(); // 执行成功立即结束
}

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>弹幕留言 | jumping-message</title>
<meta charset="utf-8" lang="zh-CN">
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>弹幕留言 | jumping-message</title>
<meta charset="utf-8" lang="zh-CN">
</head>
<body>
</body>
</html>

173
public/message/index.php Executable file
View File

@@ -0,0 +1,173 @@
<html>
<head>
<meta charset="utf-8" lang="zh-CN">
<meta name="viewport" content="width=1366px, initial-scale=1.0"> <!-- 页面等比例缩小 -->
<link rel="stylesheet" type="text/css" href="./static/css/navbar/body_color.css">
<link rel="icon" type="img/icon" href="./static/icon/original.ico">
</head>
<body>
<?php
$title = "Message | 留言";
// title 变量
echo "<title>" . "$title" . "</title>";
// 页面标题
?>
<body id="body_color">
<div id="message_block">
<div id="content_page">
<?php
echo "<h1>欢迎来到 $title</h1>";
// 欢迎语
echo "感谢您的访问" . " " . "<br>" . "顾名思义" . "$title" . "就是用来记录留言的地方";
// 介绍部分
?>
<div id="back_blok">
<!-- 返回主页 -->
<a id="back_url" href="https://ww3.tw/"><b>..返回主页</b></a>
</div>
<div id="message_video">
<video src="./static/src/video/cirno-up-down.mp4" controls width="640" height="360">
您的浏览器不支持视频播放。
</video>
</div>
<div id="message_com">
<div id="push_message">
<label for="message">输入内容 : </label>
<input type="text" id="message" placeholder="qwq">
<button onclick="push_message()">发送弹幕</button>
<br>
<p>弹幕列表</p>
<pre id="get_message"></pre>
</div>
<div>
</div>
</div>
</body>
</body>
</html>
<!-- php 引入 -->
<?php
include "./static/css/navbar/index-css.html";
// 引入navbar-css
?>
<!-- php 引入 -->
<style>
/* 这里是专属css */
#content_page
{
color: rgb(255, 74, 74);
text-align: left;
font-size: 18px;
}
#message_video
{
background-color: rgba(0, 0, 0, 0);
color: white;
text-align: center;
width: 700px;
height: 410px;
/* 页面边距 上、右、下、左 */
margin: 1.89% 0px 0px 0%;
}
#message_com
{
background-color: rgba(0, 0, 0, 0);
width: 360px;
height: 410px;
/* 页面边距 上、右、下、左 */
margin: -405px 0px 0px 63.8%;
}
#back_blok{
/* 返回主页 */
color: rgb(0, 0, 0);
width: 20%;
height: 4%;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
/* 页面边距 上、右、下、左 */
margin: 4% 0px 0px 36.8%;
}
#back_url
{
color: black;
text-decoration: none;
}
</style>
<!--这里是专属js-->
<script>
function push_message() {
const messageInput = document.getElementById('message'); // 获取输入框元素本身
const messageContent = messageInput.value.trim(); // 获取输入框的值
if (messageContent === "") {
alert("弹幕内容不能为空!");
return;
}
messageInput.value = '';
// *** 在这里清空输入框 ***
messageInput.focus();
// 如果你想让输入框在清空后立即获得焦点,方便用户继续输入
}
</script>
<script>
const API_URL = 'https://api.ww3.tw/public/danmu/get.php'; //连接api的地址
// 使用 DOMContentLoaded 事件,确保页面 HTML 结构加载完成后再执行 JavaScript
document.addEventListener('DOMContentLoaded', async () => {
// 获取用于显示内容的 <pre> 元素
const getMessageElement = document.getElementById('get_message');
try {
// 发送 GET 请求到 API
const response = await fetch(API_URL);
// 检查 HTTP 响应状态码。如果不是 2xx成功说明有错误
if (!response.ok) {
// 尝试解析 API 返回的错误信息
let errorDetails;
try {
// 假设 API 错误信息也是 JSON 格式
errorDetails = await response.json();
} catch (e) {
// 如果不是 JSON就作为纯文本处理
errorDetails = await response.text();
}
// 抛出带有详细信息的错误
throw new Error(`HTTP 错误! 状态码: ${response.status} - ${typeof errorDetails === 'object' && errorDetails !== null ? (errorDetails.message || JSON.stringify(errorDetails)) : errorDetails}`);
}
// 你的 PHP API 返回的是 message.txt 的纯文本内容,所以这里使用 .text() 方法解析响应体
const content = await response.text();
// **** 核心修改:将获取到的内容直接赋值给 <pre> 元素的 textContent ****
getMessageElement.textContent = content;
getMessageElement.classList.remove('loading'); // 移除加载提示样式
} catch (error) {
// 如果在请求或处理过程中发生任何错误,捕获并显示
console.error('获取弹幕内容失败:', error);
getMessageElement.textContent = `错误: ${error.message}`;
getMessageElement.classList.remove('loading'); // 移除加载提示样式
getMessageElement.classList.add('error'); // 添加错误样式
}
});
</script>

View File

View File

@@ -0,0 +1,4 @@
#body_color
{
background-color: rgba(147, 185, 255, 0.644);
}

View File

@@ -0,0 +1,14 @@
<style>
#message_block
{
background-color: rgba(0, 0, 0, 0.68);
position: fixed;
width: 1150px;
height: 100%;
margin: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
</style>

View File

View File

@@ -0,0 +1,3 @@
<style>
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

View File

View File

@@ -0,0 +1,26 @@
<!-- 谷歌翻译 -->
<div id="google_translate_element"></div>
<!-- 翻译选项 -->
<!-- js 部分 -->
<script type="text/javascript">
function googleTranslateElementInit() {
new google.translate.TranslateElement({pageLanguage: 'zh-CN'}, 'google_translate_element');
}
</script>
<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
<!-- js 部分 -->
<style>
#google_translate_element
{
display: flex;
position: fixed;
/* 页面边距 上、右、下、左 */
margin: -7.6px 0px 0px 0px;
overflow: hidden;
}
</style>
<!-- 谷歌翻译 -->

View File

@@ -0,0 +1 @@
这是测试

View File

@@ -0,0 +1 @@
测试

2
public/re_blog.php Executable file
View File

@@ -0,0 +1,2 @@
<!-- 域名跳转 ./blog/ -->
<meta http-equiv="refresh" content="0.1;url=https://open-ww3-project.ww3.tw/blog/">

BIN
public/short-url/icon/icon.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

12
public/short-url/index.php Executable file
View File

@@ -0,0 +1,12 @@
<html>
<head>
<title>short_url | 短链</title>
<meta charset="utf-8" lang="zh-CN">
<link rel="icon" type="image/x-icon" href="./icon/icon.jpg">
</head>
<body>
<h1>
ww3-short-url | 短链
</h1>
</body>
</html>

1
public/short_url/index.php Executable file
View File

@@ -0,0 +1 @@
<meta http-equiv="refresh" content="0.1;url=https://open-ww3-project.ww3.tw/short-url/">

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,14 @@
<style>
#black_block
{
background-color: rgba(0, 0, 0, 0.68);
position: fixed;
width: 1150px;
height: 100%;
margin: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
</style>

11
src/md/1.md Executable file
View File

@@ -0,0 +1,11 @@
# 今天、2025.7.30
----
blog 正式 完工
测试
**署名**
<br>
SkimrMe_

479
src/md/MD.php Executable file
View File

@@ -0,0 +1,479 @@
<?php
Header('Content:text/html;charset=utf-8');
?>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<style>
body,ol,ul,li,img,p{
padding:0;
margin:0;
border:none;
}
li{
list-style-type: square;
padding:2px;
}
h1,h2,h3,h4,h5,h6{
margin:10px 0 0 0;
}
h1,h2,h3{
border-bottom:solid 1px #ddd;
}
h1{
padding-bottom:12px;
}
h2{
padding-bottom: 6px;
}
h3{
padding-bottom: 2px;
}
body,ul{
padding:10px 20px;
}
body{
max-width:1024px;
margin:0 auto;
}
blockquote{
border-left:solid 4px #bbb;
background-color:#eee;
min-height:24px;
line-height:24px;
padding:0px 10px;
margin:0;
color:#333;
font-size:12px;
font-style: italic;
font-family: consolas,楷体;
}
table{
width:100%;
}
table,td,th{
border:solid 1px #ddd;
border-collapse: collapse;
padding:10px;
font-family: consolas;
font-size:14px;
}
table{
margin:10px 0;
text-align:center;
}
.table-left{
text-align:left;
}
.table-center{
text-align: center;
}
.table-right{
text-align: right;
}
tr:nth-child(even){
background-color:#eee;
}
code,pre{
border-radius:5px;
border:solid 1px #eee;
background-color:#f9f9f9;
font-family: consolas;
font-size:14px;
box-shadow: 1px 2px 3px #ddd;
}
code{
padding:2px 12px;
display: inline-block;
margin:10px 0;
}
pre{
padding:10px 12px;
overflow-x:auto;
}
</style>
<?php
/*
* flag规则:
* h1-h6 标题
* u1,u2 无序列表
* ol 有序列表
* p 普通文本
* code 代码
* table 文本
* check 选择
* uncheck 未选择
* quote 引用
* img 图片
* url 网址
* bold 加粗
* italia 斜体
* el 空行
*
* idel 闲置
*/
class MD{
private $file; //当前文件
private $mdGen; //生成器
private $flag; //当前标志
private $flag_pre; //上一次的flag
private $flag_like; //假定类型
private $line_count; //总行数
private $lines; //所有行
private $buf; //缓存行
public function __construct($filename){
$this->file = $filename; //设置当前文件
$this->mdGen = $this->content($filename); //获取生成器
$this->flag = 'idel'; //闲置
$this->lines = array(); //所有行状态
$this->line_count = 0; //行数归0
}
private function content($file){ //获取生成器
if(file_exists($file)){
$fh = fopen($file,"r");
while(!feof($fh)){
yield fgets($fh);
}
fclose($fh);
}else{
return null;
}
}
//遍历每一个字符
private function every($str){
$l = strlen($str);
for($i=0;$i<$l;$i++)
if(ord($str[$i])<0x80)
yield $str[$i];
else{
yield $str[$i].$str[$i+1].$str[$i+2]; //三个字节
$i+=2;
}
}
//解析
private function parse(){
$ctnt = $this->mdGen; //生成器
$ret=array();
if($ctnt != null){
$ret = array();
foreach($ctnt as $line){
if($this->flag != 'code')
$line=ltrim($line); //删除左边
if(strlen($line)){
$ch = $line[0]; //判断第一个字符
$type=ctype_punct($ch);//标点符号
if($this->flag !== 'code') $line=preg_replace('/\s{2,}$/','<br>',$line); //非代码模式
$ret[] = $this->parseLine($line,$type); //解析行
}else{ //空行
switch($this->flag){
case 'ul':
case 'ol':
$ret[]="</$this->flag>";
$this->flag_pre = $this->flag;
$this->flag = 'idel';
break;
case 'table':
$this->flag = 'idel';
$ret[]='</table>';
break;
default:
if($this->flag != 'el') $ret[] = '<br>';
$this->flag = 'el'; //空行
}
}
}
}
$this->lines = $ret;
return $ret;
}
//生成blockquote
private function genQuote($level,$content){
if($level<=0) return "";
return str_repeat('<blockquote>',$level).$content.str_repeat('</blockquote>',$level);
}
//检查是否处于某个状态,默认检查是否处于代码状态
private function check($value='code'){
return ($this->flag == $value);
}
/**
* 生成一行新的表格列
* $data:需要输入的数据
* $type:生成类型
* $wrap:最快层包裹
* $sep:分隔符
*/
private function genRow($data,$type='td',$wrap='tr',$sep='|'){
$ret='';
$mat = explode($sep,$data);
foreach($mat as $elem)
$ret.="<$type>".$elem."</$type>";
return "<$wrap>".$ret."</$wrap>";
}
/**
* 解析行内元素
* bold,italic,code,link,pic
*/
private function parseInner($str){
$str=preg_replace('/\*\*\*([^\*\n\r]+)\*\*\*/','<b><i>\1</i></b>',$str); //加粗并加斜字体
$str=preg_replace('/\*\*([^\*\n\r]+)\*\*/','<b>\1</b>',$str); //加粗字体
$str=preg_replace('/\*([^\*\n\r]+)\*/','<i>\1</i>',$str); //斜体
$str=preg_replace('/```([^`\n\r]+)```/','<code>\1</code>',$str); //代码
$str=preg_replace('/`([^`\n\r]+)`/','<code>\1</code>',$str); //代码
$str=preg_replace('/!\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<img src="\2" alt="\1" title="\1">',$str); //图片
$str=preg_replace('/\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<a href="\2">\1</a>',$str); //图片
return $str;
}
/**
* 按照给定规则解析字符串:
* type:
* true 符号
* false 文字
* 返回:
* array('type'=>类型,'parts'=>array(...))
*/
private function parseLine($str,$type){
if(strlen($str) == 0){
return array('type'=>'p','parts'=>[]); //返回空段
}
$valid_str = rtrim($str); //去除右边的空格
$str = $valid_str;
$output = ''; //需要输出的字符串
if($type == true){ //标点
$type_str = ''; //类型字符串
$data_str = '';
$flag = 0;
foreach($this->every($str) as $ch){
if(!ctype_punct($ch)){
$flag = 1;
}
if($flag == 0)
$type_str .= $ch;
else
$data_str .= $ch;
}
switch($type_str){
case '#':
$wrap = 'h1';
$this->flag_like = 'h1';
break;
case '##':
$wrap = 'h2';
$this->flag_like = 'h2';
break;
case '###':
$wrap = 'h3';
$this->flag_like = 'h3';
break;
case '####':
$wrap = 'h4';
$this->flag_like = 'h4';
break;
case '#####':
$wrap = 'h5';
$this->flag_like = 'h5';
break;
case '######':
$wrap = 'h6';
$this->flag_like = 'h6';
break;
case '+':
case '-':
$wrap = 'li';
$this->flag_like = 'ul';
if($this->flag != 'code'){
if($this->flag != 'ul'){
$this->flag_pre = $this->flag;
$this->flag = 'ul';
$output.='<ul>';
}
}
break;
case '```': //代码模式,不进行干扰
if($this->flag != 'code'){ //不为code,判断是否为单行代码
$output.='<pre>';
if(preg_match('/^\s*```([^`]+)```([^\s]+)\s*$/',$str,$mat)){ //单行代码
$output.="$mat[1]</pre>$mat[2]";
$str = '';
$data_str = '';
}else{
$this->flag_pre = $this->flag;
$this->flag = 'code'; //代码
}
}else{
$output.='</pre>';
$this->flag_pre = $this->flag;
$this->flag = 'idel'; //闲置
}
break;
case '[':
if(preg_match('/^\[\s\]\s*(.+)$/',$str,$mat)){ //选择
$output.="<label><input type='checkbox' disabled> $mat[1]</label><br>";
$this->flag_like = 'check';
}else if(preg_match('/^\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){ //未选择
$output.="<a href='$mat[2]'>$mat[1]</a>".$this->parseInner($mat[3]);
$this->flag_like = 'a'; //网址
}else if(preg_match('/^\s*(\[\d+\]\:)\s+([^\s]+)\s+([^\r\n]+)\s*$/',$str,$mat)){ //外部资料
$output.="$mat[1] <a href='$mat[2]'>$mat[3]</a>";
}else{
$output.=$str;
}
break;
case '[-]':
$output.="<label><input type='checkbox' checked disabled>$data_str</label><br>";
$this->flag_like = 'check';
break;
case '![':
if(preg_match('/^!\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){
$output.="<img src='$mat[2]' alt='$mat[1]'>".$this->parseInner($mat[3]);
$this->flag_like = 'img';
}else{
$this->flag_like = 'p'; //没有模式
$output.="$str";
}
break;
case '*': //斜体
if(preg_match('/^\*(.*)\*([^\s]+)\s*$/',$str,$mat)){
$output.=$this->parseInner($str);
$this->flag_like = 'i';
}else if(preg_match('/^\s*\*\s+(.+)\s*$/',$str,$mat)){
$str=$mat[1];
$wrap = 'li';
$this->flag_like = 'ul';
if($this->flag != 'code'){
if($this->flag != 'ul'){
$this->flag_pre = $this->flag;
$this->flag = 'ul';
$output.='<ul>';
}
}
}
break;
case '**': //粗体
if(preg_match('/^\*\*(.*)\*\*/',$str,$mat)){
$output.=$this->parseInner($str);
$this->flag_like = 'b';
}
break;
case '<':
$output.=$str;
$this->flag_like = 'html';
break;
default:
if(!$this->check()){ //非代码模式
if(preg_match('/^>+$/',$type_str)){ //引用
$level = strlen($type_str);
$this->flag_like = 'quote';
$output.=$this->genQuote($level,$data_str); //引用
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格确定格式---|---|....
if($this->flag == 'table'){
$this->flag_like = 'table';
$output.='<table><thead>'.$this->genRow($this->buf,'th').'</thead><tbody>';
}else{ //非表格格式,上一行没有标题
$this->flag_like = 'p'; //没有格式
$output.=$this->buf;
$this->buf = '';
}
}else if(preg_match('/^\s*(\-{3,})|(\={3,})$/',$type_str)){ //hr
$output.='<hr>';
$this->flag_like = 'hr';
break;
}else{
$this->flag_like = 'p';
$output.=$str.'<br>';
}
}
}
$br = '';
preg_match('/^(.*)(<br\s*\/?>)?$/',$data_str,$mat);
$data_str = htmlspecialchars($mat[1]);
if(!$this->check()){ //代码
if(!empty($wrap)) $output.="<$wrap>$mat[1]</$wrap>".(isset($mat[2])?'<br>':'');
}else if($type_str!='```'){
$output.=htmlspecialchars($str).'<br>';
}
}else{ //首个非空字符不为符号
if($this->flag == 'code'){ //代码,直接输出
$str=str_replace("\t",' ',$str);
$output.=htmlspecialchars($str).'<br>';
}else if(is_numeric($str[0])){ //可能为有序列表,也可能是表格
if(preg_match('/^\s*\d+\.\s+([^\r\n]+)\s*$/',$str)){ //有序列表
$this->flag_like = 'ol';
$output.=$str;
}else{
$this->flag_like = 'idel';
foreach($this->every($str) as $ch){
$output.=$ch;
}
}
$output.='<br>';
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格
$mat = explode('|',$str);
if($this->flag!='table'){ //进入表格
$this->buf = $str;
$this->flag_like = 'table';
$wrap = '';
}else{
$output.=$this->genRow($str);
}
//echo $mat[0].'<br>';
//var_dump($mat);
}else{ //其他
$this->flag = 'p';
$output.=$str;
}
}
if(!$this->check()){ //不为代码,设置flag
$this->flag_pre = $this->flag;
$this->flag = $this->flag_like;
if($this->flag_pre == 'table' && $this->flag != 'table')
$output='</table>'.$output;
else if($this->flag_pre == 'ul' && $this->flag != 'ul'){
$output='</ul>'.$output;
}
}
return $this->parseInner($output); //输出需要输出的内容
}
//获取输出内容
public function output(){
$this->parse();
echo implode('',$this->lines);
}
}

6
src/md/inite.php Executable file
View File

@@ -0,0 +1,6 @@
<?php
require '/var/www/owp/open-ww3-project-ww3-tw/src/md/MD.php';
$md=new MD('/var/www/owp/open-ww3-project-ww3-tw/src/md/inte.md');
$md->output();

10
src/md/inte.md Executable file
View File

@@ -0,0 +1,10 @@
## MD介绍页面
顾名思义、本文件夹下使用的基本都是markdown
最后感谢提供php的md插件的开源制作者
[点击跳转](https://ww3.tw/blog/md/src/php-markdown/)
日期 2025.07.30

19
src/views/error/404.html Executable file
View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<title>404 Not Found</title>
</head>
<body>
<h1 style="font-size: 250%;">到达世界尽头,这里什么都没有哦</h1>
<a style="font-size: 150%;" href="/">返回主页</a>
</body>
</html>
<style>
body{
background-image: url(https://open-ww3-project.ww3.tw/static/error/cirno-image.jpg);
background-repeat:no-repeat;
background-size: cover;
}
</style>