首先,设计一个完整的系统架构:
前端界面 (HTML/CSS/JS)
↓
API接口 (PHP)
↓
代码执行器 (Docker容器)
↓
结果返回
1. 前端界面 (index.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>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/theme/monokai.min.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1400px;
margin: 0 auto;
background: white;
border-radius: 15px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
overflow: hidden;
}
header {
background: #2c3e50;
color: white;
padding: 20px 30px;
text-align: center;
}
h1 {
font-size: 2.5rem;
margin-bottom: 10px;
}
.subtitle {
opacity: 0.8;
font-size: 1.1rem;
}
.controls {
background: #34495e;
padding: 15px 30px;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 15px;
}
.language-selector, .theme-selector {
display: flex;
align-items: center;
gap: 10px;
}
select, button {
padding: 10px 15px;
border: none;
border-radius: 5px;
font-size: 14px;
cursor: pointer;
}
select {
background: white;
min-width: 150px;
}
button {
background: #e74c3c;
color: white;
transition: background 0.3s;
font-weight: bold;
}
button:hover {
background: #c0392b;
}
.btn-run {
background: #27ae60;
}
.btn-run:hover {
background: #219653;
}
.editor-container {
display: grid;
grid-template-columns: 1fr 1fr;
height: 600px;
}
@media (max-width: 768px) {
.editor-container {
grid-template-columns: 1fr;
height: 800px;
}
}
.code-editor, .output-panel {
border: 1px solid #ddd;
}
.output-panel {
background: #1e1e1e;
color: #00ff00;
padding: 15px;
overflow-y: auto;
font-family: 'Courier New', monospace;
font-size: 14px;
}
.output-header {
background: #2d2d2d;
padding: 10px 15px;
color: #fff;
font-weight: bold;
border-bottom: 1px solid #444;
}
.code-templates {
background: #f8f9fa;
padding: 20px 30px;
border-top: 1px solid #ddd;
}
.template-buttons {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-top: 10px;
}
.template-btn {
background: #3498db;
padding: 8px 15px;
border: none;
border-radius: 20px;
color: white;
cursor: pointer;
font-size: 12px;
transition: background 0.3s;
}
.template-btn:hover {
background: #2980b9;
}
.loader {
display: none;
text-align: center;
padding: 20px;
}
.spinner {
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
margin: 0 auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.error {
color: #e74c3c;
}
.success {
color: #27ae60;
}
footer {
text-align: center;
padding: 20px;
background: #ecf0f1;
color: #7f8c8d;
font-size: 14px;
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>在线代码运行工具</h1>
<p class="subtitle">支持 PHP, Python, JavaScript, Java, C++, Go 等多种编程语言</p>
</header>
<div class="controls">
<div class="language-selector">
<label for="language">编程语言:</label>
<select id="language">
<option value="php">PHP</option>
<option value="python">Python</option>
<option value="javascript">JavaScript (Node.js)</option>
<option value="java">Java</option>
<option value="cpp">C++</option>
<option value="go">Go</option>
<option value="rust">Rust</option>
<option value="ruby">Ruby</option>
</select>
</div>
<div class="theme-selector">
<label for="theme">编辑器主题:</label>
<select id="theme">
<option value="default">默认</option>
<option value="monokai">Monokai</option>
<option value="solarized">Solarized</option>
</select>
</div>
<div class="action-buttons">
<button id="run-btn" class="btn-run">▶ 运行代码</button>
<button id="clear-btn">🗑️ 清空</button>
<button id="format-btn">🔧 格式化</button>
</div>
</div>
<div class="editor-container">
<div class="code-editor">
<textarea id="code-editor" placeholder="在这里输入您的代码..."></textarea>
</div>
<div class="output-panel">
<div class="output-header">运行结果</div>
<div id="output-content">
<p>代码运行结果将显示在这里...</p>
</div>
</div>
</div>
<div class="code-templates">
<h3>代码模板</h3>
<div class="template-buttons">
<button class="template-btn" data-lang="php" data-template="hello">PHP Hello World</button>
<button class="template-btn" data-lang="python" data-template="hello">Python Hello World</button>
<button class="template-btn" data-lang="javascript" data-template="hello">JavaScript Hello World</button>
<button class="template-btn" data-lang="java" data-template="hello">Java Hello World</button>
<button class="template-btn" data-lang="cpp" data-template="hello">C++ Hello World</button>
<button class="template-btn" data-lang="php" data-template="fibonacci">PHP 斐波那契数列</button>
<button class="template-btn" data-lang="python" data-template="fibonacci">Python 斐波那契数列</button>
</div>
</div>
<div class="loader" id="loader">
<div class="spinner"></div>
<p>正在执行代码,请稍候...</p>
</div>
<footer>
<p>© 2023 在线代码运行工具 | 安全可靠的代码执行环境</p>
</footer>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/clike/clike.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/php/php.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/python/python.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/javascript/javascript.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/go/go.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/rust/rust.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/ruby/ruby.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/format/formatting.js"></script>
<script>
// 代码模板
const codeTemplates = {
php: {
hello: `<?php
// PHP Hello World 示例
echo "Hello, World!\\\\n";
// 当前PHP版本
echo "PHP版本: " . PHP_VERSION . "\\\\n";
// 简单的计算示例
$a = 10;
$b = 20;
echo "计算结果: " . ($a + $b) . "\\\\n";
// 数组示例
$fruits = ['苹果', '香蕉', '橙子'];
echo "水果列表: " . implode(', ', $fruits) . "\\\\n";
?>`,
fibonacci: `<?php
// 斐波那契数列示例
function fibonacci($n) {
if ($n <= 1) return $n;
return fibonacci($n - 1) + fibonacci($n - 2);
}
echo "斐波那契数列前10项: \\\\n";
for ($i = 0; $i < 10; $i++) {
echo fibonacci($i) . " ";
}
echo "\\\\n";
?>`
},
python: {
hello: `# Python Hello World 示例
print("Hello, World!")
# 当前Python版本
import sys
print(f"Python版本: {sys.version}")
# 简单的计算示例
a = 10
b = 20
print(f"计算结果: {a + b}")
# 列表示例
fruits = ['苹果', '香蕉', '橙子']
print(f"水果列表: {', '.join(fruits)}")
# 类示例
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
return f"我叫{self.name},今年{self.age}岁"
p = Person("小明", 25)
print(p.introduce())`,
fibonacci: `# 斐波那契数列示例
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
print("斐波那契数列前10项:")
for i in range(10):
print(fibonacci(i), end=" ")
print()`
},
javascript: {
hello: `// JavaScript Hello World 示例
console.log("Hello, World!");
// 当前Node.js版本
console.log("Node.js版本:", process.version);
// 简单的计算示例
const a = 10;
const b = 20;
console.log("计算结果:", a + b);
// 数组示例
const fruits = ['苹果', '香蕉', '橙子'];
console.log("水果列表:", fruits.join(', '));
// 函数示例
function greet(name) {
return \`Hello, \${name}!\`;
}
console.log(greet("World"));
// 异步示例
async function asyncDemo() {
const result = await Promise.resolve("异步操作完成");
console.log(result);
}
asyncDemo();`
},
java: {
hello: `// Java Hello World 示例
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
// 简单的计算示例
int a = 10;
int b = 20;
System.out.println("计算结果: " + (a + b));
// 数组示例
String[] fruits = {"苹果", "香蕉", "橙子"};
System.out.println("水果列表: " + String.join(", ", fruits));
// 类示例
Person person = new Person("小明", 25);
System.out.println(person.introduce());
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String introduce() {
return "我叫" + name + ",今年" + age + "岁";
}
}`
},
cpp: {
hello: `// C++ Hello World 示例
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
cout << "Hello, World!" << endl;
// 简单的计算示例
int a = 10;
int b = 20;
cout << "计算结果: " << a + b << endl;
// 向量示例
vector<string> fruits = {"苹果", "香蕉", "橙子"};
cout << "水果列表: ";
for (size_t i = 0; i < fruits.size(); ++i) {
cout << fruits[i];
if (i != fruits.size() - 1) cout << ", ";
}
cout << endl;
return 0;
}`
}
};
// 初始化代码编辑器
const editor = CodeMirror.fromTextArea(document.getElementById('code-editor'), {
mode: 'text/x-php',
theme: 'default',
lineNumbers: true,
indentUnit: 4,
smartIndent: true,
electricChars: true,
matchBrackets: true,
autoCloseBrackets: true,
styleActiveLine: true,
lineWrapping: true,
viewportMargin: Infinity
});
// 设置初始代码
editor.setValue(codeTemplates.php.hello);
// 语言切换
document.getElementById('language').addEventListener('change', function() {
const lang = this.value;
let mode;
switch(lang) {
case 'php': mode = 'text/x-php'; break;
case 'python': mode = 'text/x-python'; break;
case 'javascript': mode = 'text/javascript'; break;
case 'java': mode = 'text/x-java'; break;
case 'cpp': mode = 'text/x-c++src'; break;
case 'go': mode = 'text/x-go'; break;
case 'rust': mode = 'text/x-rustsrc'; break;
case 'ruby': mode = 'text/x-ruby'; break;
default: mode = 'text/x-php';
}
editor.setOption('mode', mode);
// 切换到该语言的Hello World模板
if (codeTemplates[lang] && codeTemplates[lang].hello) {
editor.setValue(codeTemplates[lang].hello);
}
});
// 主题切换
document.getElementById('theme').addEventListener('change', function() {
editor.setOption('theme', this.value);
});
// 运行代码
document.getElementById('run-btn').addEventListener('click', function() {
runCode();
});
// 清空代码
document.getElementById('clear-btn').addEventListener('click', function() {
if (confirm('确定要清空代码吗?')) {
editor.setValue('');
}
});
// 格式化代码(简单实现)
document.getElementById('format-btn').addEventListener('click', function() {
const lang = document.getElementById('language').value;
alert('格式化功能需要更复杂的实现,这里仅作演示');
});
// 模板按钮
document.querySelectorAll('.template-btn').forEach(btn => {
btn.addEventListener('click', function() {
const lang = this.getAttribute('data-lang');
const template = this.getAttribute('data-template');
if (codeTemplates[lang] && codeTemplates[lang][template]) {
// 切换语言
document.getElementById('language').value = lang;
const event = new Event('change');
document.getElementById('language').dispatchEvent(event);
// 设置模板代码
editor.setValue(codeTemplates[lang][template]);
}
});
});
// 运行代码函数
function runCode() {
const code = editor.getValue();
const language = document.getElementById('language').value;
if (!code.trim()) {
alert('请输入代码!');
return;
}
// 显示加载动画
const loader = document.getElementById('loader');
const output = document.getElementById('output-content');
loader.style.display = 'block';
output.innerHTML = '<p>代码执行中...</p>';
// 发送请求到后端
fetch('code-runner.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `code=${encodeURIComponent(code)}&language=${language}`
})
.then(response => response.json())
.then(data => {
loader.style.display = 'none';
if (data.success) {
output.innerHTML = `<pre class="success">${data.output}</pre>`;
} else {
output.innerHTML = `<pre class="error">错误: ${data.error}</pre>`;
}
})
.catch(error => {
loader.style.display = 'none';
output.innerHTML = `<pre class="error">请求失败: ${error.message}</pre>`;
});
}
// 快捷键支持
editor.setOption('extraKeys', {
'Ctrl-Enter': function(cm) {
runCode();
},
'Cmd-Enter': function(cm) {
runCode();
}
});
</script>
</body>
</html>
2. 后端API (code-runner.php)
<?php
// code-runner.php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Content-Type');
// 错误处理
error_reporting(0);
ini_set('display_errors', 0);
// 安全配置
$allowed_languages = ['php', 'python', 'javascript', 'java', 'cpp', 'go', 'rust', 'ruby'];
$max_code_length = 10000; // 最大代码长度
$max_execution_time = 10; // 最大执行时间(秒)
// 获取POST数据
$code = $_POST['code'] ?? '';
$language = $_POST['language'] ?? '';
// 验证输入
if (empty($code)) {
echo json_encode(['success' => false, 'error' => '代码不能为空']);
exit;
}
if (!in_array($language, $allowed_languages)) {
echo json_encode(['success' => false, 'error' => '不支持的语言']);
exit;
}
if (strlen($code) > $max_code_length) {
echo json_encode(['success' => false, 'error' => '代码过长']);
exit;
}
// 安全检查:禁止危险函数和操作
if (containsDangerousCode($code, $language)) {
echo json_encode(['success' => false, 'error' => '代码包含不安全内容']);
exit;
}
try {
// 执行代码
$result = executeCode($code, $language);
echo json_encode(['success' => true, 'output' => $result]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
/**
* 安全检查函数
*/
function containsDangerousCode($code, $language) {
$dangerous_patterns = [
'system\s*\(', 'exec\s*\(', 'shell_exec\s*\(', 'passthru\s*\(',
'proc_open\s*\(', 'popen\s*\(', 'eval\s*\(', 'assert\s*\(',
'`.*`', // 反引号执行
'file_put_contents', 'fopen', 'fwrite', // 文件操作
'curl_', 'fsockopen', // 网络操作
'chmod', 'chown', // 系统操作
];
// 语言特定的危险模式
$language_specific = [];
switch ($language) {
case 'python':
$language_specific = ['import os', 'import sys', 'subprocess', 'open\s*\(', '__import__'];
break;
case 'javascript':
$language_specific = ['require\(', 'process\.', 'child_process', 'fs\.', 'eval\('];
break;
case 'java':
$language_specific = ['Runtime\.', 'ProcessBuilder', 'FileWriter', 'Socket'];
break;
case 'cpp':
$language_specific = ['system\(', 'fopen', 'popen'];
break;
}
$all_patterns = array_merge($dangerous_patterns, $language_specific);
foreach ($all_patterns as $pattern) {
if (preg_match('/' . $pattern . '/i', $code)) {
return true;
}
}
return false;
}
/**
* 执行代码函数
*/
function executeCode($code, $language) {
$output = '';
switch ($language) {
case 'php':
$output = executePHP($code);
break;
case 'python':
$output = executePython($code);
break;
case 'javascript':
$output = executeJavaScript($code);
break;
case 'java':
$output = executeJava($code);
break;
case 'cpp':
$output = executeCpp($code);
break;
case 'go':
$output = executeGo($code);
break;
default:
throw new Exception('暂不支持该语言');
}
return $output;
}
/**
* 执行PHP代码
*/
function executePHP($code) {
// 使用输出缓冲捕获输出
ob_start();
// 临时修改错误报告
$old_error_reporting = error_reporting(E_ALL);
$old_display_errors = ini_set('display_errors', '1');
try {
// 使用eval执行PHP代码(在生产环境中应该使用更安全的方式)
eval($code);
} catch (Exception $e) {
echo "PHP错误: " . $e->getMessage();
} catch (ParseError $e) {
echo "语法错误: " . $e->getMessage();
}
$output = ob_get_clean();
// 恢复原始设置
error_reporting($old_error_reporting);
ini_set('display_errors', $old_display_errors);
return $output;
}
/**
* 执行Python代码
*/
function executePython($code) {
// 创建临时文件
$temp_file = tempnam(sys_get_temp_dir(), 'python_');
file_put_contents($temp_file, $code);
// 执行Python代码
$command = "python3 " . escapeshellarg($temp_file) . " 2>&1";
$output = shell_exec($command);
// 清理临时文件
unlink($temp_file);
return $output ?: '无输出';
}
/**
* 执行JavaScript代码 (Node.js)
*/
function executeJavaScript($code) {
// 创建临时文件
$temp_file = tempnam(sys_get_temp_dir(), 'js_');
file_put_contents($temp_file, $code);
// 执行Node.js代码
$command = "node " . escapeshellarg($temp_file) . " 2>&1";
$output = shell_exec($command);
// 清理临时文件
unlink($temp_file);
return $output ?: '无输出';
}
/**
* 执行Java代码
*/
function executeJava($code) {
// 提取类名
if (!preg_match('/class\s+(\w+)/', $code, $matches)) {
return "错误:找不到类定义";
}
$class_name = $matches[1];
$temp_dir = sys_get_temp_dir();
$java_file = $temp_dir . '/' . $class_name . '.java';
file_put_contents($java_file, $code);
// 编译Java代码
$compile_command = "javac " . escapeshellarg($java_file) . " 2>&1";
$compile_output = shell_exec($compile_command);
if ($compile_output) {
unlink($java_file);
return "编译错误: " . $compile_output;
}
// 执行Java代码
$run_command = "cd " . escapeshellarg($temp_dir) . " && java " . $class_name . " 2>&1";
$output = shell_exec($run_command);
// 清理文件
unlink($java_file);
$class_file = $temp_dir . '/' . $class_name . '.class';
if (file_exists($class_file)) {
unlink($class_file);
}
return $output ?: '无输出';
}
/**
* 执行C++代码
*/
function executeCpp($code) {
$temp_dir = sys_get_temp_dir();
$cpp_file = $temp_dir . '/program.cpp';
$exec_file = $temp_dir . '/program';
file_put_contents($cpp_file, $code);
// 编译C++代码
$compile_command = "g++ " . escapeshellarg($cpp_file) . " -o " . escapeshellarg($exec_file) . " 2>&1";
$compile_output = shell_exec($compile_command);
if ($compile_output) {
unlink($cpp_file);
return "编译错误: " . $compile_output;
}
// 执行C++程序
$output = shell_exec(escapeshellarg($exec_file) . " 2>&1");
// 清理文件
unlink($cpp_file);
unlink($exec_file);
return $output ?: '无输出';
}
/**
* 执行Go代码
*/
function executeGo($code) {
$temp_dir = sys_get_temp_dir();
$go_file = $temp_dir . '/program.go';
$exec_file = $temp_dir . '/program';
file_put_contents($go_file, $code);
// 编译Go代码
$compile_command = "go build -o " . escapeshellarg($exec_file) . " " . escapeshellarg($go_file) . " 2>&1";
$compile_output = shell_exec($compile_command);
if ($compile_output) {
unlink($go_file);
return "编译错误: " . $compile_output;
}
// 执行Go程序
$output = shell_exec(escapeshellarg($exec_file) . " 2>&1");
// 清理文件
unlink($go_file);
unlink($exec_file);
return $output ?: '无输出';
}
?>
3. 安全配置文件 (.htaccess)
# 安全配置
RewriteEngine On
# 禁止直接访问某些文件
<Files "code-runner.php">
Order Allow,Deny
Allow from all
</Files>
# 设置安全头
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options DENY
Header always set X-XSS-Protection "1; mode=block"
# 限制文件上传大小
LimitRequestBody 10485760
# 防止代码注入
SetEnvIfNoCase Request_URI "\.(php|py|js|java|cpp|go)$" block_attacks
Deny from env=block_attacks
系统要求
安装步骤
将文件上传到服务器
index.html- 前端界面
code-runner.php- 后端API
.htaccess- 安全配置
配置服务器环境
# 安装必要的软件包
sudo apt update
sudo apt install php python3 nodejs default-jdk g++ golang
设置权限
chmod 755 code-runner.php
chmod 644 index.html
安全配置
这个系统提供了一个完整、安全的在线代码运行环境,可以根据需要进一步扩展和定制。

