使用PHP與Apache實現服務器端文件管理

引言

作為前端開發者,你可能經常需要與服務器文件系統交互。本文將詳細介紹如何通過PHP配合Apache實現服務器端文件管理功能。即使你沒有任何PHP經驗,也能按照本教程實現完整解決方案!

系統準備

PHP下載與安裝

  1. 訪問PHP官網下載頁面

  2. 選擇與Apache匹配的版本:

    • Apache版本:2.4.x

    • PHP版本:8.4.x TS (Thread Safe)(對應64位Apache的文件名應該類似:VS17 x64 Thread Safe,對應32位Apache的文件名應該類似:VS17 x86?Thread Safe)

    • 架構:x64(64位系統)或x86(32位系統)

  3. 解壓到目錄(如D:\php),目錄結構應包含:

    php.exe
    php8apache2_4.dll
    php.ini-development
    ext/ (擴展目錄)

Apache配置PHP

編輯conf/httpd.conf文件:

# 加載PHP模塊
LoadModule php_module "D:/php/php8apache2_4.dll"# 指定php.ini目錄
PHPIniDir "D:/php"# 將.php文件交給PHP處理
AddHandler application/x-httpd-php .php# 關聯文件擴展名
<FilesMatch \.php$>SetHandler application/x-httpd-php
</FilesMatch>

驗證配置

cd D:\Apache24\bin
httpd -t

看到"Syntax OK"表示配置正確,重啟Apache服務:

httpd -k restart

文件管理API實現

創建file_manager.php文件:

<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *'); // 測試用,生產環境應移除// 安全配置
$BASE_DIR = realpath(__DIR__ . '/Resources');
$ALLOWED_EXTENSIONS = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'txt', 'docx'];// 路徑驗證函數
function validatePath($path) {global $BASE_DIR;$realPath = realpath($BASE_DIR . '/' . $path);return ($realPath && strpos($realPath, $BASE_DIR) === 0) ? $realPath : false;
}// 獲取目錄結構
function listDirectory($path) {$realPath = validatePath($path);if (!$realPath || !is_dir($realPath)) {return ['error' => '無效目錄路徑'];}$result = [];$items = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($realPath, FilesystemIterator::SKIP_DOTS),RecursiveIteratorIterator::SELF_FIRST);foreach ($items as $item) {$relativePath = substr($item->getPathname(), strlen($realPath)) ?: '/';$relativePath = ltrim(str_replace('\\', '/', $relativePath), '/');$result[] = ['name' => $item->getFilename(),'path' => $relativePath,'type' => $item->isDir() ? 'directory' : 'file','size' => $item->isFile() ? $item->getSize() : 0,'modified' => date('Y-m-d H:i:s', $item->getMTime())];}return $result;
}// 主請求處理
$response = ['status' => 'error', 'message' => '無效請求'];
$request = json_decode(file_get_contents('php://input'), true) ?? $_REQUEST;try {if (!isset($request['action'])) {throw new Exception('未指定操作');}$action = $request['action'];switch ($action) {case 'list':$path = $request['path'] ?? '';$data = listDirectory($path);$response = ['status' => 'success', 'data' => $data];break;case 'create-folder':$path = $request['path'] ?? '';$name = $request['name'] ?? '';if (empty($name)) throw new Exception('文件夾名稱不能為空');$realPath = validatePath($path);if (!$realPath) throw new Exception('無效路徑');// 清理文件夾名稱$cleanName = preg_replace('/[^a-zA-Z0-9_-]/', '', $name);$newFolder = $realPath . DIRECTORY_SEPARATOR . $cleanName;if (file_exists($newFolder)) {throw new Exception('文件夾已存在');}if (!mkdir($newFolder, 0755)) {throw new Exception('創建文件夾失敗');}$response = ['status' => 'success', 'message' => '文件夾創建成功'];break;case 'delete-folder':$path = $request['path'] ?? '';$realPath = validatePath($path);if (!$realPath || !is_dir($realPath)) {throw new Exception('無效目錄路徑');}// 安全措施:防止刪除根目錄if ($realPath === $BASE_DIR) {throw new Exception('不能刪除根目錄');}// 遞歸刪除$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($realPath, FilesystemIterator::SKIP_DOTS),RecursiveIteratorIterator::CHILD_FIRST);foreach ($files as $file) {if ($file->isDir()) {rmdir($file->getRealPath());} else {unlink($file->getRealPath());}}if (!rmdir($realPath)) {throw new Exception('刪除文件夾失敗');}$response = ['status' => 'success', 'message' => '文件夾已刪除'];break;case 'rename':$type = $request['type'] ?? 'file';$path = $request['path'] ?? '';$newName = $request['newName'] ?? '';if (empty($newName)) throw new Exception('新名稱不能為空');$realPath = validatePath($path);if (!$realPath) throw new Exception('無效路徑');// 清理新名稱$cleanName = preg_replace('/[^a-zA-Z0-9_.-]/', '', $newName);$newPath = dirname($realPath) . DIRECTORY_SEPARATOR . $cleanName;if (file_exists($newPath)) {throw new Exception('目標名稱已存在');}if (!rename($realPath, $newPath)) {throw new Exception('重命名失敗');}$response = ['status' => 'success', 'message' => '重命名成功'];break;case 'upload-file':$targetPath = $request['path'] ?? '';$realPath = validatePath($targetPath);if (!$realPath || !is_dir($realPath)) {throw new Exception('無效目標目錄');}if (empty($_FILES['file'])) {throw new Exception('未選擇上傳文件');}$file = $_FILES['file'];$filename = preg_replace('/[^a-zA-Z0-9_.-]/', '', basename($file['name']));$targetFile = $realPath . DIRECTORY_SEPARATOR . $filename;$ext = strtolower(pathinfo($targetFile, PATHINFO_EXTENSION));// 文件類型驗證if (!in_array($ext, $ALLOWED_EXTENSIONS)) {throw new Exception('不允許的文件類型: ' . $ext);}// 防止文件覆蓋if (file_exists($targetFile)) {$filename = time() . '_' . $filename;$targetFile = $realPath . DIRECTORY_SEPARATOR . $filename;}if (!move_uploaded_file($file['tmp_name'], $targetFile)) {throw new Exception('文件上傳失敗');}$response = ['status' => 'success', 'filename' => $filename, 'message' => '文件上傳成功'];break;case 'delete-file':$path = $request['path'] ?? '';$realPath = validatePath($path);if (!$realPath || !is_file($realPath)) {throw new Exception('無效文件路徑');}if (!unlink($realPath)) {throw new Exception('文件刪除失敗');}$response = ['status' => 'success', 'message' => '文件已刪除'];break;default:throw new Exception('未知操作: ' . $action);}} catch (Exception $e) {$response = ['status' => 'error', 'message' => $e->getMessage()];
}echo json_encode($response);
?>

測試頁面

創建file_manager_test.html

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>文件管理器測試</title><style>:root {--primary: #3498db;--success: #2ecc71;--danger: #e74c3c;--dark: #34495e;--light: #f8f9fa;}* {box-sizing: border-box;margin: 0;padding: 0;font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;}body {background-color: #f5f7fa;color: #333;line-height: 1.6;padding: 20px;}.container {max-width: 1200px;margin: 0 auto;background: white;border-radius: 10px;box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);padding: 30px;}header {text-align: center;margin-bottom: 30px;padding-bottom: 20px;border-bottom: 1px solid #eee;}h1 {color: var(--dark);margin-bottom: 10px;}.subtitle {color: #7f8c8d;font-weight: 400;}.section {margin-bottom: 30px;padding: 25px;border: 1px solid #e1e4e8;border-radius: 8px;background: var(--light);transition: all 0.3s ease;}.section:hover {box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);border-color: #d1d9e0;}.section h2 {color: var(--dark);margin-top: 0;margin-bottom: 20px;padding-bottom: 10px;border-bottom: 1px dashed #ddd;display: flex;align-items: center;}.section h2 i {margin-right: 10px;color: var(--primary);}.form-group {margin-bottom: 20px;display: flex;flex-wrap: wrap;align-items: center;}label {display: inline-block;width: 150px;font-weight: 600;color: #555;}input[type="text"],input[type="file"] {width: calc(100% - 160px);padding: 12px 15px;border: 1px solid #ddd;border-radius: 4px;font-size: 16px;transition: border 0.3s;}input[type="text"]:focus,input[type="file"]:focus {border-color: var(--primary);outline: none;box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.2);}button {padding: 12px 25px;background: var(--primary);color: white;border: none;border-radius: 4px;cursor: pointer;font-size: 16px;font-weight: 600;transition: all 0.3s;margin-top: 10px;}button:hover {background: #2980b9;transform: translateY(-2px);}.delete-btn {background: var(--danger);}.delete-btn:hover {background: #c0392b;}.radio-group {display: flex;gap: 20px;margin-left: 150px;width: calc(100% - 150px);}.radio-group label {width: auto;display: flex;align-items: center;gap: 5px;font-weight: normal;}.response {margin-top: 20px;padding: 15px;border-radius: 4px;display: none;}.success {background-color: rgba(46, 204, 113, 0.1);border: 1px solid var(--success);color: #27ae60;display: block;}.error {background-color: rgba(231, 76, 60, 0.1);border: 1px solid var(--danger);color: #c0392b;display: block;}pre {background: #2d2d2d;color: #f8f8f2;padding: 15px;border-radius: 4px;max-height: 400px;overflow: auto;margin-top: 15px;font-family: 'Consolas', monospace;}@media (max-width: 768px) {.form-group {flex-direction: column;align-items: flex-start;}label {width: 100%;margin-bottom: 8px;}input[type="text"],input[type="file"] {width: 100%;}.radio-group {margin-left: 0;width: 100%;}}</style>
</head>
<body><div class="container"><header><h1>服務器文件管理器測試</h1><p class="subtitle">通過PHP與Apache實現安全的服務器端文件操作</p></header><!-- 列出目錄內容 --><div class="section"><h2><i class="fas fa-folder-open"></i> 列出目錄內容</h2><div class="form-group"><label for="listPath">目錄路徑:</label><input type="text" id="listPath" placeholder="例如: docs/images (留空顯示根目錄)"></div><button onclick="listDirectory()">列出目錄</button><div class="response"><pre id="listResult">目錄內容將顯示在這里...</pre></div></div><!-- 創建文件夾 --><div class="section"><h2><i class="fas fa-folder-plus"></i> 創建文件夾</h2><div class="form-group"><label for="createPath">父目錄路徑:</label><input type="text" id="createPath" placeholder="例如: docs"></div><div class="form-group"><label for="folderName">文件夾名稱:</label><input type="text" id="folderName" placeholder="例如: new_folder"></div><button onclick="createFolder()">創建文件夾</button><div class="response" id="createResponse"></div></div><!-- 刪除文件夾 --><div class="section"><h2><i class="fas fa-trash-alt"></i> 刪除文件夾</h2><div class="form-group"><label for="deleteFolderPath">文件夾路徑:</label><input type="text" id="deleteFolderPath" placeholder="例如: docs/old_folder"></div><button class="delete-btn" onclick="deleteFolder()">刪除文件夾</button><div class="response" id="deleteFolderResponse"></div></div><!-- 重命名文件/文件夾 --><div class="section"><h2><i class="fas fa-i-cursor"></i> 重命名項目</h2><div class="form-group"><label for="renamePath">當前路徑:</label><input type="text" id="renamePath" placeholder="例如: docs/image.jpg"></div><div class="form-group"><label for="newName">新名稱:</label><input type="text" id="newName" placeholder="例如: new_image.jpg"></div><div class="form-group"><label>類型:</label><div class="radio-group"><label><input type="radio" name="renameType" value="file" checked> 文件</label><label><input type="radio" name="renameType" value="folder"> 文件夾</label></div></div><button onclick="renameItem()">重命名</button><div class="response" id="renameResponse"></div></div><!-- 上傳文件 --><div class="section"><h2><i class="fas fa-upload"></i> 上傳文件</h2><div class="form-group"><label for="uploadPath">目標目錄:</label><input type="text" id="uploadPath" placeholder="例如: docs/uploads"></div><div class="form-group"><label for="fileInput">選擇文件:</label><input type="file" id="fileInput"></div><button onclick="uploadFile()">上傳文件</button><div class="response" id="uploadResponse"></div></div><!-- 刪除文件 --><div class="section"><h2><i class="fas fa-trash-alt"></i> 刪除文件</h2><div class="form-group"><label for="deleteFilePath">文件路徑:</label><input type="text" id="deleteFilePath" placeholder="例如: docs/file.txt"></div><button class="delete-btn" onclick="deleteFile()">刪除文件</button><div class="response" id="deleteFileResponse"></div></div></div><!-- Font Awesome 圖標 --><script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/js/all.min.js"></script><script>const API_URL = 'file_manager.php';// 顯示響應消息function showResponse(element, message, isSuccess = true) {element.textContent = message;element.className = 'response ' + (isSuccess ? 'success' : 'error');element.style.display = 'block';// 3秒后淡出setTimeout(() => {element.style.opacity = '1';let opacity = 1;const fadeOut = setInterval(() => {opacity -= 0.05;element.style.opacity = opacity;if (opacity <= 0) {clearInterval(fadeOut);element.style.display = 'none';}}, 50);}, 3000);}// 調用APIasync function callApi(data, files) {const formData = new FormData();// 添加表單數據for (const key in data) {formData.append(key, data[key]);}// 添加文件if (files) {for (const file of files) {formData.append('file', file);}}try {const response = await fetch(API_URL, {method: 'POST',body: formData});return await response.json();} catch (error) {return {status: 'error',message: '網絡錯誤: ' + error.message};}}// 列出目錄內容async function listDirectory() {const path = document.getElementById('listPath').value || '';const result = document.getElementById('listResult');result.textContent = '加載中...';const response = await callApi({action: 'list',path: path});if (response.status === 'success') {result.textContent = JSON.stringify(response.data, null, 2);} else {result.textContent = '錯誤: ' + response.message;}}// 創建文件夾async function createFolder() {const path = document.getElementById('createPath').value || '';const name = document.getElementById('folderName').value;const responseEl = document.getElementById('createResponse');if (!name) {showResponse(responseEl, '文件夾名稱不能為空', false);return;}const response = await callApi({action: 'create-folder',path: path,name: name});showResponse(responseEl, response.status === 'success' ? '? ' + response.message : '? 錯誤: ' + response.message,response.status === 'success');}// 刪除文件夾async function deleteFolder() {const path = document.getElementById('deleteFolderPath').value;const responseEl = document.getElementById('deleteFolderResponse');if (!path) {showResponse(responseEl, '文件夾路徑不能為空', false);return;}if (!confirm(`確定要刪除文件夾 "${path}" 及其所有內容嗎?`)) {return;}const response = await callApi({action: 'delete-folder',path: path});showResponse(responseEl, response.status === 'success' ? '? ' + response.message : '? 錯誤: ' + response.message,response.status === 'success');}// 重命名項目async function renameItem() {const path = document.getElementById('renamePath').value;const newName = document.getElementById('newName').value;const type = document.querySelector('input[name="renameType"]:checked').value;const responseEl = document.getElementById('renameResponse');if (!path || !newName) {showResponse(responseEl, '路徑和新名稱不能為空', false);return;}const response = await callApi({action: 'rename',path: path,newName: newName,type: type});showResponse(responseEl, response.status === 'success' ? '? ' + response.message : '? 錯誤: ' + response.message,response.status === 'success');}// 上傳文件async function uploadFile() {const path = document.getElementById('uploadPath').value || '';const fileInput = document.getElementById('fileInput');const responseEl = document.getElementById('uploadResponse');if (!fileInput.files || fileInput.files.length === 0) {showResponse(responseEl, '請選擇要上傳的文件', false);return;}const response = await callApi({action: 'upload-file',path: path}, [fileInput.files[0]]);showResponse(responseEl, response.status === 'success' ? `? ${response.message} - 文件名: ${response.filename}` : '? 錯誤: ' + response.message,response.status === 'success');}// 刪除文件async function deleteFile() {const path = document.getElementById('deleteFilePath').value;const responseEl = document.getElementById('deleteFileResponse');if (!path) {showResponse(responseEl, '文件路徑不能為空', false);return;}if (!confirm(`確定要刪除文件 "${path}" 嗎?`)) {return;}const response = await callApi({action: 'delete-file',path: path});showResponse(responseEl, response.status === 'success' ? '? ' + response.message : '? 錯誤: ' + response.message,response.status === 'success');}</script>
</body>
</html>

關鍵注意事項

  1. 安全配置

    • 生產環境中移除Access-Control-Allow-Origin: *

    • 添加身份驗證(如Basic Auth或API密鑰)

    • 限制允許的文件擴展名

    • 設置文件上傳大小限制(在php.ini中配置)

  2. 權限設置

    • Windows:為Resources目錄添加Apache用戶(如SYSTEM)的完全控制權限

    • Linux:chown -R www-data:www-data Resources && chmod -R 755 Resources

  3. 路徑說明

    • 列出Resources根目錄:輸入框留空

    • 列出子目錄:直接輸入子目錄名(如uploads

    • 不要使用前導斜杠(如/uploads

測試流程

  1. 創建Resources目錄并設置權限

  2. 上傳file_manager.phpfile_manager_test.html到Apache文檔根目錄

  3. 訪問http://localhost/file_manager_test.html

  4. 測試各項功能:

    • 列出目錄(留空)

    • 創建測試文件夾

    • 上傳文件

    • 重命名/刪除操作

補充:

由于前面的php提供的目錄樹形式過于扁平,這里提供一個返回樹形結構的目錄的json的php文件。如果要基于這個php文件進行測試,在測試文件file-manager-test.html里面 action:'list'的地方改成action:'get-tree'就可以了。

改進后的file_manager.php:

<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');// 配置安全選項
$BASE_DIR = realpath(__DIR__ . '/Resources');
$ALLOWED_EXTENSIONS = ['jpg', 'jpeg', 'png', 'gif', 'glb', 'gltf', 'fbx', 'obj', 'txt', 'md'];// 遞歸獲取目錄結構
function getDirectoryTree($path) {$realPath = realpath($path);if (!$realPath || !is_dir($realPath)) {return null;}$result = ['name' => basename($realPath),'path' => str_replace($GLOBALS['BASE_DIR'], '', $realPath) ?: '/','type' => 'directory','children' => []];$items = scandir($realPath);foreach ($items as $item) {if ($item === '.' || $item === '..') continue;$itemPath = $realPath . DIRECTORY_SEPARATOR . $item;if (is_dir($itemPath)) {$result['children'][] = getDirectoryTree($itemPath);} else {$ext = strtolower(pathinfo($itemPath, PATHINFO_EXTENSION));$result['children'][] = ['name' => $item,'path' => str_replace($GLOBALS['BASE_DIR'], '', $itemPath),'type' => 'file','size' => filesize($itemPath),'modified' => filemtime($itemPath),'extension' => $ext];}}return $result;
}// 處理請求
$response = ['status' => 'error', 'message' => 'Invalid request'];
$request = json_decode(file_get_contents('php://input'), true) ?? $_REQUEST;try {if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {exit(0);}if (!isset($request['action'])) {throw new Exception('No action specified');}$action = $request['action'];switch ($action) {case 'get-tree':$tree = getDirectoryTree($BASE_DIR);if ($tree) {$response = ['status' => 'success', 'data' => $tree];} else {throw new Exception('Failed to load directory tree');}break;case 'get-files':$path = $request['path'] ?? '/';$realPath = realpath($BASE_DIR . $path);if (!$realPath || !is_dir($realPath)) {throw new Exception('Invalid directory path');}$files = [];$items = scandir($realPath);foreach ($items as $item) {if ($item === '.' || $item === '..') continue;$itemPath = $realPath . DIRECTORY_SEPARATOR . $item;if (!is_dir($itemPath)) {$ext = strtolower(pathinfo($itemPath, PATHINFO_EXTENSION));$files[] = ['name' => $item,'path' => $path . '/' . $item,'type' => 'file','size' => filesize($itemPath),'modified' => filemtime($itemPath),'extension' => $ext];}}$response = ['status' => 'success', 'files' => $files];break;case 'create-folder':$path = $request['path'] ?? '';$name = $request['name'] ?? '';if (empty($name)) throw new Exception('Folder name is required');$realPath = validatePath($path);if (!$realPath) throw new Exception('Invalid path');$newFolder = $realPath . DIRECTORY_SEPARATOR . preg_replace('/[^a-zA-Z0-9_-]/', '', $name);if (file_exists($newFolder)) {throw new Exception('Folder already exists');}if (!mkdir($newFolder)) {throw new Exception('Failed to create folder');}$response = ['status' => 'success', 'message' => 'Folder created'];break;case 'delete-folder':$path = $request['path'] ?? '';$realPath = validatePath($path);if (!$realPath || !is_dir($realPath)) {throw new Exception('Invalid directory path');}// 安全措施:防止刪除根目錄if ($realPath === $BASE_DIR) {throw new Exception('Cannot delete base directory');}// 遞歸刪除目錄$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($realPath, FilesystemIterator::SKIP_DOTS),RecursiveIteratorIterator::CHILD_FIRST);foreach ($files as $file) {if ($file->isDir()) {rmdir($file->getRealPath());} else {unlink($file->getRealPath());}}if (!rmdir($realPath)) {throw new Exception('Failed to delete folder');}$response = ['status' => 'success', 'message' => 'Folder deleted'];break;case 'rename':$type = $request['type'] ?? ''; // 'file' or 'folder'$path = $request['path'] ?? '';$newName = $request['newName'] ?? '';if (empty($newName)) throw new Exception('New name is required');$realPath = validatePath($path);if (!$realPath) throw new Exception('Invalid path');$newPath = dirname($realPath) . DIRECTORY_SEPARATOR . preg_replace('/[^a-zA-Z0-9_.-]/', '', $newName);if (file_exists($newPath)) {throw new Exception('Target name already exists');}if (!rename($realPath, $newPath)) {throw new Exception('Rename failed');}$response = ['status' => 'success', 'message' => 'Renamed successfully'];break;case 'upload-file':$targetPath = $request['path'] ?? '';$realPath = validatePath($targetPath);if (!$realPath || !is_dir($realPath)) {throw new Exception('Invalid target directory');}if (empty($_FILES['file'])) {throw new Exception('No file uploaded');}$file = $_FILES['file'];$filename = preg_replace('/[^a-zA-Z0-9_.-]/', '', basename($file['name']));$targetFile = $realPath . DIRECTORY_SEPARATOR . $filename;$ext = strtolower(pathinfo($targetFile, PATHINFO_EXTENSION));// 驗證文件類型if (!in_array($ext, $ALLOWED_EXTENSIONS)) {throw new Exception('File type not allowed');}// 防止覆蓋現有文件if (file_exists($targetFile)) {$filename = time() . '_' . $filename;$targetFile = $realPath . DIRECTORY_SEPARATOR . $filename;}if (!move_uploaded_file($file['tmp_name'], $targetFile)) {throw new Exception('File upload failed');}$response = ['status' => 'success', 'filename' => $filename, 'message' => 'File uploaded'];break;case 'delete-file':$path = $request['path'] ?? '';$realPath = validatePath($path);if (!$realPath || !is_file($realPath)) {throw new Exception('Invalid file path');}if (!unlink($realPath)) {throw new Exception('File deletion failed');}$response = ['status' => 'success', 'message' => 'File deleted'];break;default:throw new Exception('Unknown action');}} catch (Exception $e) {$response = ['status' => 'error', 'message' => $e->getMessage()];
}echo json_encode($response);
?>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/92330.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/92330.shtml
英文地址,請注明出處:http://en.pswp.cn/web/92330.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

在Word和WPS文字中如何輸入漢字的偏旁部首

如何在Word和WPS文字中輸入偏旁部首&#xff1f;許多輸入法會把常見的偏旁部首直接放到詞庫&#xff0c;對于詞庫中沒有的可以試試這個方法&#xff1a;先輸入一個有這個偏旁部首的字&#xff0c;盡量簡單一點的&#xff0c;然后選中這個字插入-符號-其他符號。滾動到這個偏旁部…

day44 力扣1143.最長公共子序列 力扣1035.不相交的線 力扣53. 最大子序和 力扣392.判斷子序列

最長公共子序列 給定兩個字符串 text1 和 text2&#xff0c;返回這兩個字符串的最長 公共子序列 的長度。如果不存在 公共子序列 &#xff0c;返回 0 。 一個字符串的 子序列 是指這樣一個新的字符串&#xff1a;它是由原字符串在不改變字符的相對順序的情況下刪除某些字符&…

應用7:用小白量化智能體金融模塊做一個股票選股工具

應用7&#xff1a;用小白量化智能體金融模塊做一個股票選股工具 【小白量化智能體】包含有豐富的金融模塊。可以讓智能體寫各種金融量化工具。 我用讓小白量化智能體寫一個股票選股工具。 我們給【小白量化智能體】一個程序生成話術。 幫我寫一個 選股 的應用程序&#xff0c;要…

Qt Frameless Widget跨平臺無邊框窗口

Qt開發的窗口程序&#xff0c;它的標題欄樣式是無法修改的&#xff0c;這個是系統來控制&#xff0c;程序可以調整標題&#xff0c;圖標等&#xff0c;但是各個系統可能表現不一致&#xff0c;比如說標題&#xff0c;window10下在標題欄最左邊&#xff0c;而UOS則在中間&#x…

使用 IntelliJ IDEA + Spring JdbcTemplate 操作 MySQL 指南

使用 IntelliJ IDEA Spring JdbcTemplate 操作 MySQL 完全指南 一、開發環境搭建&#xff08;基于 IDEA&#xff09; 1. 創建 Spring Boot 項目 打開 IDEA → New Project → Spring Initializr選擇&#xff1a; Project SDK: Java 17依賴項&#xff1a;Spring Web, Spring…

從憤怒的小鳥來看Unity武器拖尾的特效優化

目錄 前言 素材下載 介紹 官方文檔 不添加拖尾的效果 添加拖尾 代碼控制拖尾生成 拖尾排序問題 效果 修改拖尾高度和存活時間 效果 待機時無拖尾 效果 參考 前言 在游戲開發過程中&#xff0c;我們經常需要為武器添加拖尾特效&#xff0c;效果如下所示 Unity 自…

Web開發模式 前端渲染 后端渲染 身份認證

Web 開發模式 # 目前主流的Web 開發模式 兩種 一、基于 服務器端渲染 的傳統 Web開發模式 二、基于 前后端分離 的新型 Web開發模式# 服務端渲染的優缺點# 優點&#xff1a;1. 前端耗時少因為服務端負責動態生成 HTML內容&#xff0c;瀏覽器&#xff08;包括手…

C++ WonderTrader 源碼分析之浮點數處理

介紹 在WonderTrader的文件decimal.h中封裝了一些用于浮點數&#xff08;double&#xff09;處理的工具函數&#xff0c;主要目的是解決浮點數精度誤差帶來的比較問題&#xff0c;以及進行一些常用運算&#xff08;四舍五入、比較、取模等&#xff09;。下面我們逐行詳細解釋每…

指針——練習

sizeof和strlensizeofsizeof是用來計算變量所占內存空間大小的&#xff0c;單位是字節&#xff0c;如果操作數是類型&#xff0c;計算的是使用類型創建的變量所占內存空間的大小。sizeof只關注占用內存空間的大小&#xff0c;不在乎內存中存放什么數據。我們來看一下這個代碼&a…

華為云 Flexus 部署 coze-studio

華為云 Flexus 部署 coze-studio 一、前置 主機和程序&#xff1a;云主機&#xff08;Flexus L ubuntu&#xff09; coze-studio 部署方式&#xff1a;docker&#xff08;提前裝好的&#xff09; 字節跳動開源AI智能體開發平臺Coze&#xff0c;具備極低的硬件門檻——2核CPU…

Linux系統編程Day7 -- 基于Linux系統知識的第一個程序

往期內容回顧 自動化構建工具-make/Makefile gcc/g編譯及鏈接 Vim工具的使用 Linux常用工具&#xff08;yum與vim&#xff09; ?????? Linux系統編程Day4-- Shell與權限 編寫第一個Linux程序 今天我們要利用我們所學到的Linux語言來編譯第一個Linux程序&#xff0c;在進行…

安卓264和265編碼器回調編碼數據寫入.265或者.264文件、查看編碼數據是否正確、轉換為Mp4文件、查看Mp4文件信息等方法合集

一、寫入文件 1、變量定義 private FileOutputStream m265FileOutputStream null; private File m265File null; private static final String HEVC_265_FILE_NAME "output.265"; // 或 .265 private static final String AVC_264_FILE_NAME "output.264&qu…

如何打造一支AI時代下的IT團隊,為企業戰略目標快速賦能

執行摘要 在當前AI技術迅猛發展的背景下&#xff0c;中國中小企業正面臨著前所未有的數字化轉型機遇與挑戰。據最新調研顯示&#xff0c;2025年全球AI市場規模將突破5000億美元&#xff0c;而中國AI應用占比已達35%。與此同時&#xff0c;AI領域人才缺口高達1000萬人&#xff0…

機器學習-LinearRegression

1、 關鍵數學知識點&#xff1a; 邊緣概率密度 聯合密度對非關注變量積分&#xff1a;fX(x)∫fX,Y(x,y)dyf_X(x)∫f_{X,Y}(x,y)dyfX?(x)∫fX,Y?(x,y)dy&#xff1b; 條件概率密度 切片 fX∣Y(x∣y)fX,Y(x,y)/fY(y)f_{X|Y}(x|y)f_{X,Y}(x,y)/f_Y(y)fX∣Y?(x∣y)fX,Y?(x,y)…

解決微信小程序中如何把npm構建的模塊與主包分離,構建到分包上面

1、配置分包2、復制packge.json到分包中3、在project.config.json中增加npm配置4、終端執行npm i下載模塊5、構建npm到miniprogram_npm中

自動駕駛中的傳感器技術21——Camera(12)

自動駕駛攝像頭的圖像評測 攝像頭的性能受到環境光照、天氣條件、運動模糊等因素的影響&#xff0c;因此需要通過多方面的評測來確保其在各種場景下的可靠性。 在自動駕駛領域&#xff0c;圖像質量評估不僅關注圖像的清晰度、分辨率等傳統指標&#xff0c;還需要結合目標檢測…

AI+OA原生應用 麥當秀AIPPT

麥當秀也在WAIC期間重新定義AIOA一、什么是“原生AI”&#xff1f;“原生AI”可以理解為&#xff1a;AI系統本身具備完整的辦公能力&#xff0c;不需要依賴傳統辦公軟件&#xff08;如Word、Excel、PPT&#xff09;作為載體。也就是說&#xff0c;用戶可以直接通過AI系統完成文…

K8S 入門操作

之前一直用kubectl這個命令操作&#xff0c;這些都是基于命令來操作K8S kubectl get pods kubectl get nodes kubectl get svc kubectl create deployment... kubectl expose deployment...kubectl 文檔 命令行工具 (kubectl) | Kubernetes 命令參考 Kubectl Reference Doc…

蒙文OCR識別技術難點實現及應用場景剖析

一、蒙文OCR識別核心技術難點1. 文字特性帶來的識別挑戰連寫特性&#xff1a;蒙文字符存在復雜的連寫形式&#xff08;詞首、詞中、詞尾變形&#xff09;方向特異性&#xff1a;傳統蒙文為垂直書寫&#xff08;現代也有橫排&#xff09;&#xff0c;需特殊方向處理字符相似性&a…

通過docker構建一個java鏡像

通過docker構建一個java鏡像 FROM zlyxzq/centos7:v1 VOLUME /tmp WORKDIR /app COPY /target/aa.jar /root/app/aa.jarENV TZAsia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezoneENV JAVA_HOME /usr/local/java ENV PA…