为什么__soapCall抛出“ Forbidden”,而__doRequest抛出?

时间:2019-07-02 08:20:58

标签: php soap

让我们考虑下面的以下SOAP客户端示例。它基本上扩展了PHP本机语言(请注意我们处于wsdl模式):

use SoapClient;
use SoapFault;

abstract class AbstractClient extends SoapClient
{
    abstract protected function getHeaders(): array;

    private function call(string $functionName, array $arguments)
    {
        $this->__setSoapHeaders(
            $this->getHeaders()
        );

        try {
            return $this->__soapCall($functionName, [$arguments]);
        } catch (SoapFault $soapFault) {
            // ... 
        }
    }

    public function sendRequest(string $functionName, array $arguments)
    {
        return $this->call($functionName, $arguments);
    }
}

使用__soapCall请求SOAP服务器会不断抛出SoapFault

faultstring: Forbidden
faultcode: HTTP

我尝试了不同的配置,更改了缓存,SOAP版本,SSL流上下文等,但仍然无济于事。

现在,想象一下使用__doRequest请求相同的端点,传递由先前实现生成的XML请求(XML是从$this->__getLastRequest()中的catch部分转储的),然后它可以正常工作并且我们得到了预期服务器的响应。

从那里,我覆盖了客户端中的__doRequest(PHP较低级别调用__doRequest来执行__soapCall)以查看有什么区别:

public function __doRequest($request, $location, $action, $version, $one_way = 0)
{
    // Output $request, $location, $action, $version and $one_way

    parent::__doRequest($request, $location, $action, $version, $one_way);
}

事实证明,唯一的原因是缺少参数$action,该参数为空。因此,我对其进行了硬编码,但仍然无济于事:再次抛出了禁止的异常。

有人对这里发生的事情有任何想法吗?

编辑

经过更多测试之后,我现在可以说对XML请求进行格式化(不是将其格式化为一行,而是对其进行“美化”了)。也许我缺少某种编码/格式配置,但是不幸的是,PHP文档在该主题上不是很准确...

1 个答案:

答案 0 :(得分:0)

我终于想出了一个肮脏的解决方案。覆盖import java.io.File; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Vector; public class FileTest { public FileTest() { super(); } public static void main(final String[] args) { final Map<MyFile, List<MyFile>> duplicates = new HashMap<>(); FileTest.handleDirectory(duplicates, new File("[path to base directory]")); final Iterator<Entry<MyFile, List<MyFile>>> iterator = duplicates.entrySet().iterator(); while (iterator.hasNext()) { final Entry<MyFile, List<MyFile>> next = iterator.next(); if (next.getValue().size() == 0) { iterator.remove(); } else { System.out.println(next.getKey().getName() + " - " + next.getKey().getAbsolutePath()); for (final MyFile file : next.getValue()) { System.out.println(" ->" + file.getName() + " - " + file.getAbsolutePath()); } } } } private static void handleDirectory(final Map<MyFile, List<MyFile>> duplicates, final File directory) { final File dir = directory; if (dir.isDirectory()) { final File[] files = dir.listFiles(); for (final File file : files) { if (file.isDirectory()) { FileTest.handleDirectory(duplicates, file); continue; } final MyFile myFile = new MyFile(file.getAbsolutePath()); if (!duplicates.containsKey(myFile)) { duplicates.put(myFile, new Vector<>()); } else { duplicates.get(myFile).add(myFile); } } } } } 并用__doRequest格式化请求可以达到目的:

DOMDocument

有人知道如何配置PHP SOAP扩展来正确实现吗?