提问人:Guzinek 提问时间:8/7/2023 最后编辑:ADysonGuzinek 更新时间:8/7/2023 访问量:54
更改代码导致未捕获错误:调用成员函数 getElementsByTagName()
Change code cause Uncaught Error: Call to a member function getElementsByTagName()
问:
我有一个问题,因为网站的设计可能已经改变,我的股票不起作用。 问题是
致命错误:未捕获错误:在 C:\xampik\htdocs\łamaki\open-triangle.php:177 中调用成员函数 getElementsByTagName() 上空 堆栈跟踪:#0 {main} 在 C:\xampik\htdocs\łamaki\open-triangle.php 中抛出 177
在脚本中,这是: 脚本中的行
$tmp = explode('-', $current);
$url = $siteURL.'/next/soccer/?year='.$tmp[0].'&month='.$tmp[1].'&day='.$tmp[2];
$dom = new DOMDocument();
$dom->loadHTML(execCURL($url));
$table = $dom->getElementsByTagName('table')->item(0);
foreach ($table->getElementsByTagName('tr') as $tr){
############################
$isVisible = $tr->getAttribute('data-def');
if($isVisible == 1){
$meetingDate = trim($tr->getAttribute('data-dt'));
$meetingDate = explode(',', $meetingDate);
$meetingTime = $meetingDate[3].':'.$meetingDate[4];
$meetingDate = $meetingDate[0].'.'.$meetingDate[1].'.'.$meetingDate[2];
我应该改变什么?有什么解决的问题吗? 我对此完全是绿色的 问候
我尝试更改路径链接
答:
您的脚本通常缺少错误处理和数据完整性检查。
然后,当某个地方出现最轻微的问题时,它可能会在一个非常不相关的不同地方崩溃((更近)距离的幽灵动作,这至少看起来像一个直截了当的脚本)。
一些小技巧:
$tmp = explode('-', $current);
心爱的强大 explode(),它有一个限制(第三个参数),你可以提供默认值:
#- three default values, we take null
#
$tmp = explode('-', $current, 3) + [null, null, null];
#
#-- three array entries max
现在使用这些值,你应该说出它们是什么,特别是当你把它们放到一个 URL 中时(你不希望它不惜一切代价中断),URL 需要始终是正确的。
最好使用 sprintf(),这里我假设您使用的是正数:
$url = sprintf(
'%s/next/soccer/?year=%d&month=%d&day=%d',
$siteURL, $tmp[0], $tmp[1], $tmp[2]
);
http_build_query() 有更好的选择来构建 URI 的查询信息部分(我上次在这个答案中使用了它),以防万一只是您需要正确编码它。更好的作品可能看起来像:
$date = array_combine(['year', 'month', 'day'], explode('-', $current));
这已经显示了名称 + 错误处理(警告 PHP < 8,从 PHP 8 开始出现 ValueError)。因此,使用当前的PHP更加安全,这里不再需要explode()的限制参数!
$date = array_map(intval(...), $date);
现在每个日期项都是整数。使用时,您可能需要也可能不需要它
$date = array_combine(['year', 'month', 'day'], explode('-', $current));
$url = "{$siteUrl}/next/soccer/?" . http_build_query($date);
甜?但是,如果您不使用 http_build_query(),则需要 intval() 调用,否则 URL 可能会中断。
现在 URL 准备就这么多。让我们检查一下使用地点:
$dom = new DOMDocument();
$dom->loadHTML(execCURL($url))
|| throw new Error('HTML load error from: execCURL($url)');
检查 function/mehtod 返回,如果出现错误,这里 loadHtml() 返回 false。您想在继续之前处理它。至少你想早点知道它,因此有 (PHP 8.0+) 直接抛出 or “||” 条件。您可以使用此模式快速集成它。最好抛出一个错误,然后无休止地调试以后的错误。
这样做还会告诉你,错误消息是没有用的,这将使你在正确的位置自动改进代码。
在这里,execCURL() 可能没有返回有效的 HTML(哦,现在是 hakre,这很聪明!),甚至可能不是字符串(!)。因此,我们可能有两类错误,这些 curl 已经能够检测、通信(甚至可能处理),然后是 HTML 文本(文档)本身被破坏的问题。
不是你的情况。在您的情况下,错误出在其他地方,但是如果以后的事情出乎意料,您可能希望能够在某个时候检查 HTML。
现在到你遇到错误的地方,至少我们越来越近了:
$table = $dom->getElementsByTagName('table')->item(0);
foreach ($table->getElementsByTagName('tr') as $tr) {
# ...
这是另一个问题,没有正确理解或更好地完全照顾 .$dom->getElementsByTagName('table')->item(0);
这是新闻快讯:两次:
- $dom->getElementsByTagName('table') 可能会返回 null
- ->item(0) 可能返回 null
这两个方法的返回值都是绝对正确的。在当前的PHP中如何处理?好吧,让 null 通过(null 安全运算符“?”):
$table = $dom->getElementsByTagName('table')?->item(0);
#
#- le magique question mark
对于 item() 返回的潜在第二个 null?我看看:
foreach ($dom->getElementsByTagName('table')
?->item(0)
?->getElementsByTagName('tr') ?? [] as $tr) {
# ...
结合 null 合并运算符 “??”,如果以 null 安全方式访问 tr 元素导致 null,则 foreach 为空数组(不要 foreach),否则 tr 元素的快乐路径。
现在,三个部分之后,这里有几个技巧,也许是新的东西,但都围绕着处理返回值和输入值。尊重他们,并在传递他们时也尊重他们,例如以指向不同服务的 URL 的形式。你永远不知道这些小错误在你身边或别人的电脑上潜入哪里。
以故障安全的方式编写代码,尽早出错。
(到目前为止,此答案中的代码尚未经过测试,仅供示例使用。PHP 8 .0+ 语言水平。
评论
$table
$dom->getElementsByTagName('table')->item(0)
返回 null。