国庆放假无聊,其他项目没得写,就复刻一下老项目咯
通过ai写的前端![$[泡泡表情]::(滑稽)](/usr/themes/joe-master/assets/images/owo/paopao/E6BB91E7A8BD_2x.png)

,结果写完api发现不能大文件上传,我还看了好久的文档
那我就直接开源了
<?php
/**
* 获取客户端IP地址
*
* @return string 客户端IP地址,如果无法获取则返回'unknown'
*/
function get_ip() {
// 检查是否通过代理访问
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
// X-Forwarded-For可能包含多个IP地址,取第一个
$ip_list = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$ip = trim($ip_list[0]);
// 验证IP格式
if (filter_var($ip, FILTER_VALIDATE_IP)) {
return $ip;
}
}
// 检查Proxy-Client-IP
if (!empty($_SERVER['HTTP_PROXY_CLIENT_IP']) && filter_var($_SERVER['HTTP_PROXY_CLIENT_IP'], FILTER_VALIDATE_IP)) {
return $_SERVER['HTTP_PROXY_CLIENT_IP'];
}
// 检查WL-Proxy-Client-IP
if (!empty($_SERVER['HTTP_WL_PROXY_CLIENT_IP']) && filter_var($_SERVER['HTTP_WL_PROXY_CLIENT_IP'], FILTER_VALIDATE_IP)) {
return $_SERVER['HTTP_WL_PROXY_CLIENT_IP'];
}
// 检查REMOTE_ADDR
if (!empty($_SERVER['REMOTE_ADDR']) && filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP)) {
return $_SERVER['REMOTE_ADDR'];
}
// 无法获取IP时返回默认值
return '未知';
}
$curl = curl_init();
// 1. 先重新获取令牌(避免过期)
$loginUrl = 'https://cloud.kxlove.top/api/auth/login';
$loginData = ['username' => 'acg', 'password' => '123abc'];
$loginCurl = curl_init();
curl_setopt_array($loginCurl, [
CURLOPT_URL => $loginUrl,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($loginData),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true
]);
$loginRes = json_decode(curl_exec($loginCurl), true);
curl_close($loginCurl);
if (empty($loginRes['data']['token'])) {
die("登录失败:" . json_encode($loginRes));
}
$token = $loginRes['data']['token'];
// 2. 准备文件和路径(确保绝对路径+目录存在)
$localFile = $_FILES['file']['tmp_name'];
$fileContent = file_get_contents($localFile);
if ($fileContent === false) {
die("无法读取本地文件: $localFile");
}
$filePath = date('Y-m-d H:i:s').'.png'; // 绝对路径,带/开头
$encodedFilePath = rawurlencode($filePath);
// 3. 执行上传
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://cloud.kxlove.top/api/fs/form',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_POSTFIELDS => $fileContent,
CURLOPT_HTTPHEADER => array(
"Authorization: $token",
"File-Path: $encodedFilePath",
"As-Task: true",
"Content-Length: " . strlen($fileContent),
"Content-Type: application/octet-stream"
),
));
$responseJson = curl_exec($curl);
$error = curl_error($curl);
curl_close($curl);
// if ($error) {
// echo "CURL错误: $error";
// } else {
// echo $responseJson;
// }
// 解析JSON为关联数组
$response = json_decode($responseJson, true);
// 提取name字段内容
$taskName = $response['data']['task']['name'];
// 提取"upload "后面的文件名部分(到" to "为止)
$fileName = '';
if (strpos($taskName, 'upload ') === 0) {
// 去掉开头的"upload "
$remaining = substr($taskName, 7);
// 找到" to "的位置,提取前面的部分
$toPos = strpos($remaining, ' to ');
if ($toPos !== false) {
$fileName = substr($remaining, 0, $toPos);
}
}
$user = $_POST['user'];
$title = $_POST['title'];
$time = date('Y-m-d H:i:s');
$category = $_POST['category'];
$tags = $_POST['tags'];
if($user==''||$title==''||$category==''||$tags==''){
$res = ['code' => 400, 'msg' => '参数不完整'];
echo json_encode($res);
exit;
}
if(!is_dir("img/$category")){
$res = ['code' => 400, 'msg' => '分类不存在'];
echo json_encode($res);
exit;
}
$url = 'https://cloud.kxlove.top/d/次元阁/'.$fileName;
mkdir("img/$category/$time");
file_put_contents("img/$category/$time/title",$title);
file_put_contents("img/$category/$time/user",$user);
file_put_contents("img/$category/$time/time",$time);
file_put_contents("img/$category/$time/tags",$tags);
file_put_contents("img/$category/$time/url",$url);
file_put_contents("img/$category/$time/ip",get_ip());
$res = ['code' => 200, 'msg' => '发布成功'];
echo json_encode($res);
?>