141 lines
4.5 KiB
PHP
141 lines
4.5 KiB
PHP
|
<?php
|
|||
|
session_start();
|
|||
|
|
|||
|
function listServerFiles() {
|
|||
|
$files = glob(__DIR__ . '/conf/conf.d/*.conf');
|
|||
|
$servers = [];
|
|||
|
foreach ($files as $file) {
|
|||
|
$port = basename($file, '.conf');
|
|||
|
$servers[] = [
|
|||
|
'port' => $port,
|
|||
|
'file' => $file,
|
|||
|
'content' => file_get_contents($file)
|
|||
|
];
|
|||
|
}
|
|||
|
return $servers;
|
|||
|
}
|
|||
|
|
|||
|
$servers = listServerFiles();
|
|||
|
|
|||
|
$reservedPorts = [80, 8080];
|
|||
|
|
|||
|
// 合併所有已使用 port 與保留 port
|
|||
|
$usedPorts = array_unique(array_merge(
|
|||
|
$reservedPorts,
|
|||
|
array_map('intval', array_column($servers, 'port'))
|
|||
|
));
|
|||
|
|
|||
|
function findRandomAvailablePort($start = 3000, $end = 9000, $usedPorts = []) {
|
|||
|
$candidates = range($start, $end);
|
|||
|
shuffle($candidates);
|
|||
|
foreach ($candidates as $port) {
|
|||
|
if (!in_array($port, $usedPorts)) {
|
|||
|
return $port;
|
|||
|
}
|
|||
|
}
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
$autoPort = findRandomAvailablePort(3000, 9000, $usedPorts);
|
|||
|
|
|||
|
$resultMsg = '';
|
|||
|
if (isset($_SESSION['resultMsg'])) {
|
|||
|
$resultMsg = $_SESSION['resultMsg'];
|
|||
|
unset($_SESSION['resultMsg']);
|
|||
|
}
|
|||
|
?>
|
|||
|
<!DOCTYPE html>
|
|||
|
<html>
|
|||
|
<head>
|
|||
|
<meta charset="UTF-8" />
|
|||
|
<title>NGINX 動態 Server 管理</title>
|
|||
|
<link rel="icon" href="/favicon.png" data-rh="true">
|
|||
|
<style>
|
|||
|
body { font-family: sans-serif; padding: 20px; }
|
|||
|
pre { background: #f0f0f0; padding: 10px; overflow-x: auto; }
|
|||
|
.message { padding: 10px; margin-bottom: 20px; border-radius: 4px; }
|
|||
|
.success { background-color: #d4edda; color: #155724; }
|
|||
|
.error { background-color: #f8d7da; color: #721c24; }
|
|||
|
input[type="number"] { width: 80px; }
|
|||
|
</style>
|
|||
|
</head>
|
|||
|
<body>
|
|||
|
<?php if ($resultMsg): ?>
|
|||
|
<div class="message <?= strpos($resultMsg, '成功') !== false ? 'success' : 'error' ?>">
|
|||
|
<?= nl2br(htmlspecialchars($resultMsg)) ?>
|
|||
|
</div>
|
|||
|
<?php endif; ?>
|
|||
|
|
|||
|
<h2>📡 現有 Servers</h2>
|
|||
|
<ul>
|
|||
|
<?php foreach ($servers as $s): ?>
|
|||
|
<?php
|
|||
|
// 從 content 透過正規表達式取 root 路徑
|
|||
|
preg_match('/root\s+([^\s;]+);/', $s['content'], $matches);
|
|||
|
$rootPath = $matches[1] ?? '未知';
|
|||
|
|
|||
|
// 排除顯示 /Users/catantech/Desktop/
|
|||
|
$displayPath = str_replace('/Users/catantech/Desktop/', '', $rootPath);
|
|||
|
?>
|
|||
|
<li>
|
|||
|
<strong>Port <?= htmlspecialchars($s['port']) ?></strong><br>
|
|||
|
<strong>Root 路徑: <?= htmlspecialchars($displayPath) ?></strong><br>
|
|||
|
<form method="post" action="servers.php" style="display:inline; margin-right: 10px;">
|
|||
|
<input type="hidden" name="action" value="delete" />
|
|||
|
<input type="hidden" name="port" value="<?= htmlspecialchars($s['port']) ?>" />
|
|||
|
<button type="submit">刪除</button>
|
|||
|
</form>
|
|||
|
<a href="http://192.168.5.45:<?= htmlspecialchars($s['port']) ?>" target="_blank" style="color: blue; text-decoration: underline;">
|
|||
|
連結到此 Server
|
|||
|
</a>
|
|||
|
</li>
|
|||
|
<br>
|
|||
|
<?php endforeach; ?>
|
|||
|
</ul>
|
|||
|
|
|||
|
<hr>
|
|||
|
<h2>➕ 新增 Server</h2>
|
|||
|
<form method="post" action="servers.php" id="addServerForm">
|
|||
|
<input type="hidden" name="action" value="add" />
|
|||
|
<label for="portInput">🎲 Port:</label>
|
|||
|
<input type="number" id="portInput" name="port" min="3000" max="9000" required value="<?= $autoPort ?>" />
|
|||
|
<br />
|
|||
|
<label for="rootInput">Root 目錄:</label>
|
|||
|
<input type="text" id="rootInput" name="root" required style="width:400px;" value="Project/Line_Project_1/Official/out-dev" />
|
|||
|
<br />
|
|||
|
<button type="submit">新增</button>
|
|||
|
</form>
|
|||
|
|
|||
|
<script>
|
|||
|
(() => {
|
|||
|
const reservedPorts = [80, 8080];
|
|||
|
const usedPorts = <?= json_encode($usedPorts) ?>;
|
|||
|
|
|||
|
const portInput = document.getElementById('portInput');
|
|||
|
const form = document.getElementById('addServerForm');
|
|||
|
|
|||
|
form.addEventListener('submit', e => {
|
|||
|
const portVal = Number(portInput.value);
|
|||
|
|
|||
|
if (isNaN(portVal) || portVal < 3000 || portVal > 9000) {
|
|||
|
alert('❌ Port 必須是 3000 到 9000 之間的數字');
|
|||
|
e.preventDefault();
|
|||
|
return;
|
|||
|
}
|
|||
|
if (reservedPorts.includes(portVal)) {
|
|||
|
alert(`❌ Port ${portVal} 是保留端口,請選擇其他 Port`);
|
|||
|
e.preventDefault();
|
|||
|
return;
|
|||
|
}
|
|||
|
if (usedPorts.includes(portVal)) {
|
|||
|
alert(`❌ Port ${portVal} 已被使用,請選擇其他 Port`);
|
|||
|
e.preventDefault();
|
|||
|
return;
|
|||
|
}
|
|||
|
});
|
|||
|
})();
|
|||
|
</script>
|
|||
|
|
|||
|
</body>
|
|||
|
</html>
|