如何通过PHP向自有服务器请求HTML内容实现Tao测试预览?
解决Tao测试评估的测试预览/打印功能问题
先说说你遇到的file_get_contents返回false的问题,以及实现测试合并预览的可行方案:
一、排查file_get_contents失效的原因
- URL参数或权限问题:你请求的单题预览URL在浏览器能打开,但PHP脚本执行时可能没带必要的参数(比如登录Cookie、题目ID),或者服务器有CSRF/登录校验,导致请求被拒。可以把@去掉,打印错误信息定位问题:
$url = "你的单题预览地址"; $content = file_get_contents($url); if ($content === false) { var_dump(error_get_last()); // 查看具体错误原因 }
- 服务器限制:哪怕
allow_url_fopen开了,服务器防火墙、安全插件可能拦截PHP发起的内部请求,或者你的URL写得有问题(比如用了相对路径,file_get_contents无法识别)。
二、PHP合并HTML的可行写法
如果要继续用HTTP请求的方式,换成cURL更靠谱,能自定义请求头、携带Cookie,避免权限校验问题:
// 测试包含的题目ID列表 $questionIds = [1, 2, 3]; $testHtml = '<div class="test-wrap">'; foreach ($questionIds as $id) { $url = "http://你的域名/preview-question.php?id={$id}"; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 带上当前用户的Cookie,解决登录校验问题 $cookieStr = ''; foreach ($_COOKIE as $k => $v) { $cookieStr .= "{$k}={$v}; "; } curl_setopt($ch, CURLOPT_COOKIE, $cookieStr); $questionHtml = curl_exec($ch); curl_close($ch); if ($questionHtml) { // 过滤掉单题页面里的导航、页脚这些无关内容 $questionHtml = preg_replace('/<header.*?<\/header>|<footer.*?<\/footer>/si', '', $questionHtml); $testHtml .= "<div class='question-item'>{$questionHtml}</div>"; } } $testHtml .= '</div>'; echo $testHtml;
三、更高效的方案:直接调用内部代码
既然是自己的项目,没必要绕HTTP请求,直接调用生成单题HTML的函数/类就行,速度快还没权限问题:
// 假设项目里有生成单题HTML的类 require_once 'QuestionPreview.php'; $questionIds = [1, 2, 3]; $testHtml = '<div class="test-wrap">'; foreach ($questionIds as $id) { $preview = new QuestionPreview(); $questionHtml = $preview->getHtml($id); // 直接调用内部方法生成HTML if ($questionHtml) { $testHtml .= "<div class='question-item'>{$questionHtml}</div>"; } } $testHtml .= '</div>'; echo $testHtml;
四、前端优化方案
如果PHP合并麻烦,换前端方式试试:
- 用AJAX拉取每个题目的HTML片段,插入到同一个页面:
const questionIds = [1,2,3]; const container = document.getElementById('test-container'); questionIds.forEach(id => { fetch(`/api/get-question-html?id=${id}`) .then(res => res.text()) .then(html => { const div = document.createElement('div'); div.className = 'question-item'; div.innerHTML = html; container.appendChild(div); }); });
- 打印时用CSS隐藏无关元素,只保留测试内容:
@media print { header, footer, .nav { display: none !important; } .test-wrap { width: 100%; margin: 0; } }
单题预览效果:

现有多题查看方式:

内容的提问来源于stack exchange,提问作者Filip Cacic
相关产品推荐
相关产品推荐

