<?php
/**
* @title MBTI-16型人格测试
* @description MBTI人格类型测试工具
* @tag 心理,MBTI,人格测试
*/
session_start();
// 初始化MBTI测试数据
if (!isset($_SESSION['mbti_version'])) {
$_SESSION['mbti_version'] = '1'; // 默认基础版
$_SESSION['mbti_current_num'] = 1;
$_SESSION['mbti_answers'] = [];
$_SESSION['mbti_result'] = null;
}
// 处理开始测试请求
if (isset($_GET['action']) && $_GET['action'] === 'start_test') {
$version = in_array($_GET['version'], ['1', '2', '3']) ? $_GET['version'] : '1';
$_SESSION['mbti_version'] = $version;
$_SESSION['mbti_current_num'] = 1;
$_SESSION['mbti_answers'] = [];
$_SESSION['mbti_result'] = null;
echo json_encode(['success' => true, 'version' => $version]);
exit;
}
// 处理获取题目请求
if (isset($_GET['action']) && $_GET['action'] === 'get_question') {
$version = $_SESSION['mbti_version'] ?? '1';
$num = $_SESSION['mbti_current_num'] ?? 1;
$url = "https://cn.apihz.cn/api/mingli/mbti.php?id=88888888&key=88888888&type=1&version={$version}&num={$num}";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
if ($data && $data['code'] === 200) {
echo json_encode([
'question' => $data['q'],
'optionA' => $data['a'],
'optionB' => $data['b'],
'current_num' => $num,
'max_questions' => getVersionMaxQuestions($version)
]);
} else {
echo json_encode([
'error' => $data['msg'] ?? '获取题目失败,请重试',
'original_response' => $data
]);
}
exit;
}
// 处理保存答案请求
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'save_answer') {
$answer = $_POST['answer'] ?? '';
$num = $_SESSION['mbti_current_num'] ?? 1;
$version = $_SESSION['mbti_version'] ?? '1';
if ($answer === 'A' || $answer === 'B') {
$_SESSION['mbti_answers'][$num] = $answer;
$_SESSION['mbti_current_num'] = $num + 1;
$max_questions = getVersionMaxQuestions($version);
$is_last_question = ($num >= $max_questions);
echo json_encode([
'success' => true,
'next_num' => $num + 1,
'is_last_question' => $is_last_question,
'max_questions' => $max_questions
]);
} else {
echo json_encode(['success' => false, 'error' => '无效答案']);
}
exit;
}
// 处理提交测试请求
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'submit_test') {
$version = $_SESSION['mbti_version'] ?? '1';
$answers = $_SESSION['mbti_answers'] ?? [];
$max_questions = getVersionMaxQuestions($version);
// 验证答案数量
if (count($answers) < $max_questions) {
echo json_encode(['success' => false, 'error' => "请完成所有{$max_questions}道题目再提交"]);
exit;
}
// 按题号顺序拼接答案
ksort($answers);
$answer_str = implode(',', array_values($answers));
$url = "https://cn.apihz.cn/api/mingli/mbti.php?id=10000657&key=1e5e70b823b4849b6106405699910260&type=2&version={$version}&qcan=" . urlencode($answer_str);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
if ($data && $data['code'] === 200) {
$_SESSION['mbti_result'] = [
'type' => $data['mbti'] ?? '未知类型',
'description' => formatMBTIDescription($data['mbtimsg'] ?? '')
];
echo json_encode([
'success' => true,
'mbti_type' => $data['mbti'] ?? '未知类型',
'description' => formatMBTIDescription($data['mbtimsg'] ?? '')
]);
} else {
echo json_encode([
'success' => false,
'error' => $data['msg'] ?? '提交失败,请重试',
'original_response' => $data
]);
}
exit;
}
// 处理重置测试
if (isset($_GET['action']) && $_GET['action'] === 'reset_test') {
unset($_SESSION['mbti_version']);
unset($_SESSION['mbti_current_num']);
unset($_SESSION['mbti_answers']);
unset($_SESSION['mbti_result']);
echo json_encode(['success' => true]);
exit;
}
// 获取版本对应的最大题数
function getVersionMaxQuestions($version) {
$versions = [
'1' => 48, // 基础版
'2' => 93, // 专业版
'3' => 200 // 完整版
];
return $versions[$version] ?? 48;
}
// 格式化MBTI描述(添加HTML格式)
function formatMBTIDescription($text) {
// 将**加粗**转换为HTML
$text = preg_replace('/\*\*(.*?)\*\*/', '<strong>$1</strong>', $text);
// 将\n\n转换为段落
$text = preg_replace('/\n\s*\n/', '</p><p>', $text);
// 将\n转换为<br>
$text = nl2br($text);
// 确保以<p>标签开始和结束
if (!preg_match('/^<p>/', $text)) {
$text = '<p>' . $text;
}
if (!preg_match('/<\/p>$/', $text)) {
$text .= '</p>';
}
return $text;
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🧠 MBTI-16型人格测试</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: #f7fafc;
padding: 2rem;
max-width: 800px;
margin: 0 auto;
}
.tool-container {
background: white;
padding: 2rem;
border-radius: 12px;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}
h1 {
color: #4a5568;
margin-bottom: 1.5rem;
text-align: center;
font-size: 1.8rem;
}
.version-selector {
display: flex;
justify-content: center;
gap: 15px;
margin: 1.5rem 0 1.8rem;
padding-bottom: 12px;
border-bottom: 1px solid #edf2f7;
}
.version-btn {
background: #e2e8f0;
color: #4a5568;
border: none;
padding: 0.65rem 1.2rem;
border-radius: 10px;
cursor: pointer;
font-size: 0.95rem;
font-weight: 500;
transition: all 0.3s;
position: relative;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.version-btn:hover {
background: #cbd5e0;
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
.version-btn.active {
background: #667eea;
color: white;
font-weight: 600;
box-shadow: 0 4px 10px rgba(102, 126, 234, 0.35);
}
.question-container {
margin-bottom: 1.8rem;
padding: 1.4rem;
background: #f8fafc;
border-radius: 10px;
border: 1px solid #edf2f7;
box-shadow: 0 2px 6px rgba(0,0,0,0.03);
}
.question-text {
font-size: 1.15rem;
margin-bottom: 1.2rem;
line-height: 1.6;
font-weight: 500;
color: #2d3748;
}
.progress-info {
text-align: center;
font-size: 0.95rem;
color: #4a5568;
margin-bottom: 1rem;
font-weight: 500;
}
.options-container {
display: grid;
grid-template-columns: 1fr;
gap: 0.9rem;
margin-top: 0.5rem;
}
.option-btn {
background: white;
border: 2px solid #cbd5e0;
border-radius: 8px;
padding: 1rem;
text-align: left;
cursor: pointer;
transition: all 0.25s;
font-size: 1.02rem;
font-weight: 500;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.option-btn:hover {
border-color: #667eea;
background: #ebf4ff;
transform: translateX(3px);
box-shadow: 0 2px 6px rgba(102, 126, 234, 0.15);
}
.option-btn.selected {
background: #667eea;
color: white;
border-color: #667eea;
font-weight: 600;
box-shadow: 0 3px 8px rgba(102, 126, 234, 0.3);
}
.controls {
display: flex;
justify-content: center;
gap: 15px;
margin: 1.8rem 0;
}
button {
background: #667eea;
color: white;
border: none;
padding: 0.85rem 1.8rem;
border-radius: 10px;
cursor: pointer;
font-size: 1.05rem;
font-weight: 500;
transition: all 0.3s;
box-shadow: 0 3px 6px rgba(102, 126, 234, 0.3);
}
button:hover {
background: #5a67d8;
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(102, 126, 234, 0.4);
}
button:disabled {
background: #a0aec0;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
#submit-btn {
background: #38b2ac;
box-shadow: 0 3px 6px rgba(56, 178, 172, 0.3);
}
#submit-btn:hover {
background: #319795;
box-shadow: 0 4px 8px rgba(56, 178, 172, 0.4);
}
#start-btn {
background: #4299e1;
box-shadow: 0 3px 6px rgba(66, 153, 225, 0.3);
}
#start-btn:hover {
background: #3182ce;
box-shadow: 0 4px 8px rgba(66, 153, 225, 0.4);
}
.result-container {
margin-top: 1.5rem;
padding: 1.8rem;
border-radius: 10px;
display: none;
animation: fadeIn 0.4s ease;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.mbti-type {
font-size: 3.5rem;
font-weight: 800;
text-align: center;
margin: 1rem 0;
background: linear-gradient(135deg, #667eea 0%, #4299e1 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-shadow: 0 2px 10px rgba(102, 126, 234, 0.2);
}
.mbti-description {
line-height: 1.8;
color: #2d3748;
font-size: 1.05rem;
margin-top: 1.5rem;
}
.mbti-description p {
margin-bottom: 1rem;
padding-left: 1rem;
border-left: 3px solid #667eea;
}
.mbti-description strong {
color: #4a5568;
}
.reset-section {
text-align: center;
margin-top: 1.8rem;
padding-top: 1.5rem;
border-top: 1px dashed #e2e8f0;
}
.reset-btn {
background: #ed8936;
color: white;
border: none;
padding: 0.65rem 1.6rem;
border-radius: 8px;
cursor: pointer;
font-size: 0.95rem;
font-weight: 500;
transition: all 0.3s;
box-shadow: 0 2px 5px rgba(237, 137, 54, 0.3);
}
.reset-btn:hover {
background: #dd6b20;
transform: scale(1.03);
box-shadow: 0 3px 7px rgba(237, 137, 54, 0.4);
}
.back-home {
display: inline-block;
margin-top: 1.2rem;
color: #667eea;
text-decoration: none;
font-weight: 500;
padding: 0.4rem 0.8rem;
border-radius: 6px;
transition: all 0.3s;
}
.back-home:hover {
background: #f0f4ff;
text-decoration: underline;
}
.loading {
text-align: center;
padding: 2rem;
color: #718096;
font-style: italic;
font-size: 1.1rem;
}
.error {
color: #e53e3e;
text-align: center;
padding: 1.5rem;
background: #fff5f5;
border-radius: 8px;
margin: 1rem 0;
font-weight: 500;
}
.start-container {
text-align: center;
padding: 2rem;
}
.version-desc {
display: flex;
justify-content: space-around;
margin-top: 1rem;
text-align: center;
font-size: 0.9rem;
color: #4a5568;
}
.version-desc div {
padding: 0.5rem;
min-width: 100px;
}
@media (max-width: 600px) {
.options-container {
grid-template-columns: 1fr;
}
.controls {
flex-direction: column;
align-items: center;
}
button {
width: 100%;
max-width: 320px;
padding: 1rem;
}
.mbti-type {
font-size: 2.8rem;
}
}
</style>
</head>
<body>
<div class="tool-container">
<h1>🧠 MBTI-16型人格测试</h1>
<div class="version-selector">
<button class="version-btn active" data-version="1">基础版<br><small>48题</small></button>
<button class="version-btn" data-version="2">专业版<br><small>93题</small></button>
<button class="version-btn" data-version="3">完整版<br><small>200题</small></button>
</div>
<div class="start-container" id="start-container">
<p>选择测试版本后点击开始测试</p>
<button id="start-btn">🚀 开始测试</button>
<div class="version-desc">
<div><strong>基础版 (48题)</strong><br>快速了解人格类型</div>
<div><strong>专业版 (93题)</strong><br>更精准的类型分析</div>
<div><strong>完整版 (200题)</strong><br>深度全面的人格剖析</div>
</div>
</div>
<div class="question-container" id="question-container" style="display:none">
<div class="progress-info" id="progress-info">第 1 题 / 共 48 题</div>
<div class="question-text" id="question-text">正在加载题目...</div>
<div class="options-container">
<div class="option-btn" data-value="A" id="option-a">选项A</div>
<div class="option-btn" data-value="B" id="option-b">选项B</div>
</div>
</div>
<div class="controls">
<button id="next-btn" disabled>✅ 选择答案</button>
<button id="submit-all-btn" style="display:none">📤 提交测试</button>
</div>
<div class="result-container" id="result-container">
<h2 style="text-align:center; margin-bottom:0.5rem">您的MBTI人格类型</h2>
<div class="mbti-type" id="mbti-type">ESTP</div>
<div class="mbti-description" id="mbti-description">
<p><strong>ESTP - 企业家/实践者</strong> (外向-实感-思考-知觉)</p>
<p><strong>人群占比</strong>: 约4.3%(女性2.3%,男性6.4%),行动冒险型</p>
<p><strong>性格特点</strong>:</p>
<p>- <strong>行动导向</strong>: 注重行动和结果<br>- <strong>活在当下</strong>: 享受此时此地体验<br>- <strong>适应力强</strong>: 善于应对变化<br>- <strong>冒险精神</strong>: 喜欢刺激和挑战<br>- <strong>务实灵活</strong>: 注重实际,讨厌理论</p>
<p><strong>著名人物</strong>: 唐纳德·特朗普、麦当娜、欧内斯特·海明威</p>
</div>
</div>
<div class="reset-section">
<button class="reset-btn" id="reset-btn">🔄 重新测试</button>
<a href="../index.php" class="back-home">← 返回工具首页</a>
</div>
</div>
<script>
let currentVersion = '1';
let currentNum = 1;
let maxQuestions = 48;
let selectedAnswer = null;
let testStarted = false;
document.addEventListener('DOMContentLoaded', function() {
// 版本选择
document.querySelectorAll('.version-btn').forEach(btn => {
btn.addEventListener('click', function() {
if (testStarted) return;
document.querySelectorAll('.version-btn').forEach(b => b.classList.remove('active'));
this.classList.add('active');
currentVersion = this.getAttribute('data-version');
// 更新最大题数
maxQuestions = getVersionMaxQuestions(currentVersion);
document.getElementById('progress-info').textContent = `第 1 题 / 共 ${maxQuestions} 题`;
});
});
// 开始测试
document.getElementById('start-btn').addEventListener('click', startTest);
// 选项选择
document.querySelectorAll('.option-btn').forEach(btn => {
btn.addEventListener('click', function() {
document.querySelectorAll('.option-btn').forEach(b => b.classList.remove('selected'));
this.classList.add('selected');
selectedAnswer = this.getAttribute('data-value');
document.getElementById('next-btn').disabled = false;
});
});
// 下一题
document.getElementById('next-btn').addEventListener('click', saveAnswer);
// 提交全部
document.getElementById('submit-all-btn').addEventListener('click', submitAllAnswers);
// 重置测试
document.getElementById('reset-btn').addEventListener('click', resetTest);
// 检查是否有未完成的测试
checkExistingTest();
});
// 检查是否有未完成的测试
function checkExistingTest() {
// 这里可以添加检查session中是否有未完成测试的逻辑
// 为简化,我们每次加载页面都从初始状态开始
}
// 开始测试
function startTest() {
if (!currentVersion) {
alert('请选择测试版本');
return;
}
fetch(`?action=start_test&version=${currentVersion}`)
.then(response => response.json())
.then(data => {
if (data.success) {
testStarted = true;
document.getElementById('start-container').style.display = 'none';
document.getElementById('question-container').style.display = 'block';
currentNum = 1;
maxQuestions = getVersionMaxQuestions(currentVersion);
updateProgress();
loadQuestion();
} else {
alert('开始测试失败: ' + (data.error || '未知错误'));
}
})
.catch(error => {
console.error('开始测试失败:', error);
alert('开始测试失败: 网络错误');
});
}
// 加载题目
function loadQuestion() {
document.getElementById('question-text').textContent = '💡 正在加载题目...';
document.getElementById('option-a').textContent = '加载中...';
document.getElementById('option-b').textContent = '加载中...';
document.getElementById('next-btn').disabled = true;
document.querySelectorAll('.option-btn').forEach(btn => btn.classList.remove('selected'));
fetch(`?action=get_question`)
.then(response => response.json())
.then(data => {
if (data.error) {
document.getElementById('question-text').innerHTML = `<div class="error">❌ ${data.error}</div>`;
return;
}
document.getElementById('question-text').textContent = data.question;
document.getElementById('option-a').textContent = data.optionA;
document.getElementById('option-b').textContent = data.optionB;
updateProgress();
})
.catch(error => {
document.getElementById('question-text').innerHTML =
`<div class="error">❌ 加载题目失败: ${error.message || '网络错误'}</div>`;
});
}
// 更新进度显示
function updateProgress() {
document.getElementById('progress-info').textContent = `第 ${currentNum} 题 / 共 ${maxQuestions} 题`;
// 更新按钮状态
document.getElementById('submit-all-btn').style.display = (currentNum >= maxQuestions) ? 'inline-block' : 'none';
document.getElementById('next-btn').style.display = (currentNum < maxQuestions) ? 'inline-block' : 'none';
document.getElementById('next-btn').textContent = (currentNum < maxQuestions) ? '✅ 选择答案' : '✅ 选择答案';
}
// 保存答案
function saveAnswer() {
if (!selectedAnswer) {
alert('请选择一个答案');
return;
}
fetch('', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `action=save_answer&answer=${selectedAnswer}`
})
.then(response => response.json())
.then(data => {
if (data.success) {
if (data.is_last_question) {
// 最后一题,显示提交按钮
document.getElementById('submit-all-btn').style.display = 'inline-block';
document.getElementById('next-btn').style.display = 'none';
} else {
// 加载下一题
currentNum = data.next_num;
selectedAnswer = null;
document.getElementById('next-btn').disabled = true;
document.querySelectorAll('.option-btn').forEach(btn => btn.classList.remove('selected'));
loadQuestion();
}
} else {
alert('保存答案失败: ' + (data.error || '未知错误'));
}
})
.catch(error => {
console.error('保存答案失败:', error);
alert('保存答案失败: 网络错误');
});
}
// 提交所有答案
function submitAllAnswers() {
if (!selectedAnswer) {
alert('请选择最后一题的答案');
return;
}
// 先保存最后一题的答案
fetch('', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `action=save_answer&answer=${selectedAnswer}`
})
.then(response => response.json())
.then(saveData => {
if (!saveData.success) {
throw new Error(saveData.error || '保存最后一题失败');
}
// 然后提交全部测试
return fetch('', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `action=submit_test`
});
})
.then(response => response.json())
.then(result => {
if (result.success) {
showResult(result.mbti_type, result.description);
} else {
throw new Error(result.error || '提交测试失败');
}
})
.catch(error => {
console.error('提交测试失败:', error);
alert('提交测试失败: ' + error.message);
});
}
// 显示结果
function showResult(mbtiType, description) {
document.getElementById('mbti-type').textContent = mbtiType;
document.getElementById('mbti-description').innerHTML = description;
document.getElementById('question-container').style.display = 'none';
document.getElementById('result-container').style.display = 'block';
}
// 重置测试
function resetTest() {
fetch('?action=reset_test')
.then(response => response.json())
.then(data => {
if (data.success) {
// 重置UI状态
testStarted = false;
currentNum = 1;
selectedAnswer = null;
// 显示开始界面
document.getElementById('start-container').style.display = 'block';
document.getElementById('question-container').style.display = 'none';
document.getElementById('result-container').style.display = 'none';
// 重置版本选择
document.querySelectorAll('.version-btn').forEach(btn => btn.classList.remove('active'));
document.querySelector(`.version-btn[data-version="${currentVersion}"]`).classList.add('active');
// 重置进度
maxQuestions = getVersionMaxQuestions(currentVersion);
document.getElementById('progress-info').textContent = `第 1 题 / 共 ${maxQuestions} 题`;
alert('测试已重置,您可以重新开始');
} else {
alert('重置失败: ' + (data.error || '未知错误'));
}
})
.catch(error => {
console.error('重置测试失败:', error);
alert('重置测试失败: 网络错误');
});
}
// 获取版本对应的最大题数
function getVersionMaxQuestions(version) {
const versions = {
'1': 48,
'2': 93,
'3': 200
};
return versions[version] || 48;
}
</script>
</body>
</html>
版权属于:So_Lua
作品采用《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权
评论 (0)