默认类方法有时会失败,有时,即使传递给方法的参数相同,通常只需要几分之一秒。
超过30秒的最大执行时间 script_path 在线 script_line_number
在那一行中:
$result = $DOMDocument -> schemaValidate($schemaPath);
$ DOMDocument总是一样的。它只引用具有ID atrtibutes的相同XML的部分。除了Algorith和xmlns之外,它没有任何类似属性的URL,它本质上不会从任何地方调用任何资源,我们讨论的是PHP的DOMDocument类和XML starndards。
$schemaPath
始终是相同的,它指向服务器本地XSD文件,它始终存在,在验证尝试之前和之后,它是否成功。架构仅指向位于同一文件夹中的其他本地xsd文件,即<xs:include schemaLocation="schema2.xsd"/>
我能想到的唯一可能的答案是XSD文件是由方法定位的,但由于某种原因无法读取,因为光盘正忙。
导致执行该方法的原因需要这么长时间?
除了增加PHP的最大执行时间限制外,应采取哪些措施来防止错误发生?
XML和XSD文件非常小,实际上完全相同的XML和XSD通常需要不到~0.1秒的时间来验证,但是很少次(1000次中的~1次)执行时间超过30秒。
修改
我隔离了问题所以我发布了一个样本。
Schema.xsd:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema targetNamespace="http://www.foo.bar/Car" xmlns:SiiDte="http://www.foo.bar/Car" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:include schemaLocation="schema2.xsd"/>
<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsignature_v10.xsd"/><!-- just the standar signature schema -->
<xs:element name="ROOT" type="SiiDte:ROOTDefType"/>
<xs:complexType name="ROOTDefType">
<xs:sequence>
<xs:element name="Element"></xs:element>
<xs:element ref="ds:Signature">
<xs:annotation>
<xs:documentation>Firma Digital sobre Documento</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:attribute name="version" type="xs:decimal" use="required" fixed="1.0"/>
</xs:complexType>
</xs:schema>
Schema2.xsd:
<xs:schema targetNamespace="http://www.foo.bar/Car" xmlns:ns1="http://www.foo.bar/Car" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:simpleType name="MOOType">
<xs:restriction base="xs:positiveInteger">
<xs:enumeration value="1"/>
<xs:enumeration value="2"/>
<xs:enumeration value="3"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
代码:
// ... a bunch of ther code...
$XML =
'<?xml version="1.0"?>
<ROOT xmlns="http://www.foo.bar/Car" version="1.0">
<Element ID="A1">hello</Element>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#A1">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>base64string</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>base64string</SignatureValue>
<KeyInfo>
<KeyValue>
<RSAKeyValue>
<Modulus>base64string</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
<X509Data>
<X509Certificate>base64string</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
</ROOT>'
;
$DD = new DOMDocument();
$DD -> loadXML($XML);
$i = 0;
while ($i < 100) {
// ... a bunch of other code...
libxml_use_internal_errors(true);
$old_libxml_disable_entity_loader = libxml_disable_entity_loader(false); $result = $DD -> schemaValidate(__DIR__ . '/schema.xsd');
libxml_disable_entity_loader($old_libxml_disable_entity_loader); // Se desactiva nuevamente carga de entidades para descartar entidades maliciosas
$i++;
echo str_pad($i, 5) . ($result ? 'true' : 'false') . '<br>';
// ... a bunch of other code...
}
答案 0 :(得分:-1)
问题是整个脚本达到30秒标记,而不是单独执行DOMDocument :: schemaValidate()。
执行时间对应于完整的脚本执行,包括所有包含和迭代,以防万一。
考虑执行时间不计算在脚本之外花费的任何时间,例如流操作,数据库查询等。因此,例如,脚本可能看起来需要1分钟,而实际上它只需要15或30。请参阅http://php.net/manual/en/function.set-time-limit.php说明:
注意:set_time_limit()函数和配置指令 max_execution_time仅影响脚本的执行时间 本身。花在执行之外的活动上的任何时间 使用system(),流操作等系统调用的脚本 确定最大值时不包括数据库查询等 脚本运行的时间。在Windows上不是这样 测量时间是真实的。
这不是:: schemaValidate(),它需要30秒才能执行,它是完整的脚本。那么为什么一旦脚本达到30秒,错误就会落在schemaValidate()里面?因为altought :: schemaValidate()它是一个相对快速的执行方法,它必须是迭代中最复杂的代码,因此最大的机会是当执行schemaValidate时,错误在N次重复之后下降(在实际情况下N必须很多)。
所以答案是:: schemaValidate()消耗了大部分执行时间,因此错误总是在:: schemaValidate()执行时发生。