我无法通过以下代码捕获异常。任何人都可以帮我解决这个问题吗?
try
{
$xml_emp_name = $xpath->evaluate("//EMPLOYEES[ID='" . $emp_id . "']/EMP-NAME/text()")->item(0)->nodeValue;
}
catch(Exception $e)
{
echo "Error: " . $e->getMessage();
}
答案 0 :(得分:2)
DOMXPath :: evaulate不会抛出异常。 domxpath evaluate
如果表达式格式错误或contextnode无效,则DOMXPath :: evaluate()返回FALSE。
尝试
$xml_emp_name = $xpath->evaluate("//EMPLOYEES[ID='" . $emp_id . "']/EMP-NAME/text()");
if(!$xml_emp_name){
echo 'Error';
}else{
$name = $xml_emp_name->item(0)->nodeValue;
}
如果evaulate失败并且返回false
,则尝试访问非对象上的属性。
答案 1 :(得分:0)
->evaluate
由于某种原因不会抛出任何异常,所以我建议检查结果是否为假,然后抛出异常:
if (($xml_emp_name = $xpath->evaluate("//EMPLOYEES[ID='" . $emp_id . "']/EMP-NAME/text()") ) !== false) {
$xml_emp_name = $xml_emp_name->item(0)->nodeValue;
}
else {
// Throw Exception
}
答案 2 :(得分:0)
您的代码很容易注入xpath。先解决这个问题。然后错误自动消失(因为xpath不能在语法上无效)。您还需要检查/验证返回值。
因此,您缺少输入验证和返回值验证的基本原则。你需要做的就是多加小心。
输入验证:
直接将变量$emp_id
注入xpath字符串中以进行替换:
"//EMPLOYEES[ID='" . $emp_id . "']/EMP-NAME/text()"
然而,在那个地方你不能在该字符串中有一个单引号。而是检查输入值(验证)或过滤/简化它(清理)。例如,验证它不包含单引号或清理数值。这是第二个:
$expression = sprintf('//EMPLOYEES[ID="%d"]/EMP-NAME/text()', $emp_id);
$result = $xpath->evaluate($expression);
对sprintf()
的这个小调用需要注意只使用数字整数值。它们从不包含引号,因此表达式始终有效。无数值的无效值将变为0
。因为从不分配ID 0
是一般原则,这通常不会在设计良好的系统中引起任何问题。如果您想更精细地进行过滤,请参阅Data Filtering in the PHP manual。
返回值验证
在你的代码中,你只需要很少的检查(实际上没有检查)来接管结果的返回值。那是错的。对于您使用的每个方法或函数,您需要在PHP手册中查找它,并检查所有可能的返回值的文档。此方法为DOMXpath::evaluate()
,点击该链接并找到 返回值 部分。您可以在PHP手册中找到每个方法和函数。
当您阅读文档时,还要确定方法使用哪种错误处理方法。是抛出异常(如果是,是哪些?)或它是否显示错误条件及其返回值(如您的情况)?需要此信息来决定是否像您一样执行try / catch(哪个是错误的,因为它不会抛出异常)或者您需要检查返回值:
$expression = sprintf('//EMPLOYEES[ID="%d"]/EMP-NAME/text()', $emp_id);
$result = $xpath->evaluate($expression);
if (!$result) {
throw new Exception(
sprintf('No such employee (id: %s)', var_export($emp_id, true))
);
}
此示例将 falsy 返回值转换为具有单个异常消息的异常。您可能还想考虑另一个例外,SPL offers some pre-defined exceptions。
我希望这个答案可以帮助您解决这个问题以及即将发生的问题。