PHP是否提前发送SOAP响应?
这是一个我一直在处理的老问题,仍然没有解决方案,所以尝试一种新的方法 如何提前(在脚本执行结束之前)发送SOAP响应 当ACK文件未在30秒之前发送时,会出现这些问题,因为完成此过程的时间比分配的时间长 flush()不工作,出现以下错误: org.xml.sax.SAXParseException:xml文档结构必须在同一实体中开始和结束 如果没有冲水,我会得到这个 org.xml.sax.SAXParseException:文件过早结束 脚本过程可能需要180秒才能完成,而等待响应的服务器在超时之前只需等待大约30秒(这会导致上述错误) 我该怎么解决这个问题呢 下面是一些代码:这是我如何接受和发送imcoming SOAP请求的ACK文件PHP是否提前发送SOAP响应?,php,xml,soap,salesforce,flush,Php,Xml,Soap,Salesforce,Flush,这是一个我一直在处理的老问题,仍然没有解决方案,所以尝试一种新的方法 如何提前(在脚本执行结束之前)发送SOAP响应 当ACK文件未在30秒之前发送时,会出现这些问题,因为完成此过程的时间比分配的时间长 flush()不工作,出现以下错误: org.xml.sax.SAXParseException:xml文档结构必须在同一实体中开始和结束 如果没有冲水,我会得到这个 org.xml.sax.SAXParseException:文件过早结束 脚本过程可能需要180秒才能完成,而等待响应的服务器在
$data = 'php://input';
$content = file_get_contents($data);
if($content) {
respond('true');
} else {
respond('false');
}
响应函数
function respond($tf) {
$ACK = <<<ACK
<?xml version = "1.0" encoding = "utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<notifications xmlns="http://soap.sforce.com/2005/09/outbound">
<Ack>$tf</Ack>
</notifications>
</soapenv:Body>
</soapenv:Envelope>
ACK;
print trim($ACK);
}
函数响应($tf){
$ACK=a)(可选)您可以使用set_time_limit()来增加执行时间的时间限制
b) 必须增加到wsdl客户端对象的时间,例如:
$clientwsdl->setOpt('timeout', 300); // if you are using PEAR:SOAP.
大多数wsdl类都允许定义超时
c) 而且,您不能使用SOAP提前响应,至少不能使用一个调用。请考虑SOAP返回XML,因此部分XML通常无效(它缺少结束标记)
d) 或者,您可以使用SOAP以外的其他方法,例如读取url:
$fp=fopen("http://www.mysite.com/url.php","r");
其中url.php返回列(或不使用xml的某种值):
30|50|70|80|20
30|50|70|80|20
30|50|70|80|20
据我所知,我们不能对30秒的限制做任何事情,并且在脚本完成之前输出不会被刷新。你能尝试将处理逻辑分成两部分吗
“侦听器”脚本,它接受消息,记录要完成的作业,并立即发送ACK,然后退出
您这边的实际处理可能需要更长的时间
“要完成的工作”可以是一个新生成的进程(查看函数的注释,但它们对我来说不太有希望),也可以是某种将数据存储在文件或数据库中并定期使用另一个脚本处理数据的方法,例如,计划每5分钟运行一次
如果60秒可以节省您的时间,您可以将出站消息重写为Apex的调用。基本上,您可以编写自己的SOAP信封并将其发送到任何http地址。您可以将其放入触发器中。不过,请参阅此方法的限制
其他咆哮:
我不认为你的ACK对salesforce真的“重要”。出站消息只是通知。你在应用程序的其他地方依赖ACK=true/false吗?如果不依赖,盲目发送ACK=true并安排工作的侦听器可能真的是一种方法;)
从另一个问题中,我了解到您基本上只需要在数据库中存储更新。您意识到您不应该将OM用于审计目的,对吗?(,搜索“审计”)
让PHP成为活动端不是更简单吗?让它查询Salesforce的[SELECT Id,Name FROM Account WHERE LastModifiedDate>:lastTimeYouQueried]?这样你就可以花所有时间来处理结果:)
感谢您的输入,在设置setOpt()时遇到了麻烦,至于另一个fopen方法,我无法从XML更改