Сложности с навигацией по SOAP-клиенту WSDL с функциями PHP.

Я экспериментирую с общедоступным API-интерфейсом SOAP в рамках подготовки к тестированию внутреннего API-интерфейса SOAP, над которым мы работаем на работе. Я сталкиваюсь с проблемами, связанными с автоматическим связыванием имен методов с именами параметров.

В частности, я тестирую http://www.webservicex.net/stockquote.asmx?WSDL и что я пытаюсь сделать, так это написать функцию, которую я могу использовать в Behat, чтобы наши QA люди могли легко создавать новые сценарии, определяющие новые функции (по мере их создания), без того, чтобы я каждый раз писал новую функцию.

Для этого я создал обёртку функции для SoapClient::__soapCall(). Мне удалось получить вызовы определенных функций для работы, например:

<?php
public function iGetAQuoteFor($symbol) {
    $response = $this->client->GetQuote(array('symbol' => $symbol));
    $quote = simplexml_load_string($response->GetQuoteResult)->Stock;
    echo "Quote:\n" . print_r($quote, true) . "\n";
}
?>

Поэтому, очевидно, мне нужно определить параметр, который я отправляю в службу SOAP, чтобы он был эффективным. Но для этого мне нужно иметь возможность сопоставить имя функции с именами параметров. Я попытался обработать WSDL с помощью SimpleXML, но мне трудно ориентироваться в результатах этого. Я испробовал множество различных методов и добился определенного прогресса, когда использовал функцию SimpleXML «дочерние элементы» и указал пространство имен «wsdl». Но то, что я получаю ниже, ничем не лучше.

Вот моя функция вызова мыла (написанная как контекст Behat):

/**
 * Calls a specific SOAP function (defined in the WSDL).
 *
 * @param string $functionName
 * @param string $options (optional, no implemented yet)
 *
 * @Given /^I make a SOAP call to "([^"]*)" with "([^"]*)"$/
 * @Given /^I make a SOAP call to "([^"]*)"$/
 */
public function iMakeASOAPCallTo($functionName, $passedOptions = NULL) {
    //Deal with the options
    $options = array($passedOptions);

    if (stristr($passedOptions, ',')) {
        $options = explode(',', $passedOptions);
    }
    else if (empty($passedOptions)) {
        $options = array();
    }

    //Also should try to figure out how to match the function call to the option wrapper
    #Function placeholder

    //Attempt to make the call
    try {
        $result = $this->client->__soapCall($functionName, $options);
    }
    catch (\Exception $e) {
        throw new Exception("Failed to call SOAP function.");
    }

    //Process the result
    if (!empty($result)) {
        $result = $this->decodeSOAPResult($functionName, $result);

        if (!empty($result)) {
            echo "        It returns:\n" . print_r($result, true) . "\n";
        }
        else {
            throw new Exception("Invalid result from function call.");
        }
    }
    else {
        throw new Exception("Failed result or exception from function call.");
    }
}

И это моя функция, которая пытается получить детали схемы после установления соединения с сервисом мыла.

private function buildSchemaDetails() {
    $xml = simplexml_load_file($this->soapURL);
    echo "\n" . print_r($xml, true) . "\n";

    echo "For the ns:\n";
    $element = $xml->getDocNamespaces();
    echo "\n" . print_r($element, true) . "\n";

    $element = $xml->children('wsdl', true)->types->children();
    echo "\n" . print_r($element, true) . "\n";

    die();
}

Как видите, у меня есть код для тестирования. Сейчас это некрасиво, но мне нужно понять, как это обработать. Если кто-нибудь знает инструмент, который делает все это для меня заранее, это было бы здорово.

По сути, я хочу иметь возможность определить параметры функции, прежде чем пытаться ее вызвать. Если функция имеет только один параметр, я хотел бы просто сопоставить введенную переменную с одним именем параметра на основе вызываемой функции, а затем вызвать ее.

Это полезно в Behat при написании функций и сценариев, потому что тогда я могу написать строку в стиле корнишона, такую ​​как «Затем я делаю SOAP-вызов «GetQuote» с «GOOG»», и мне не нужно беспокоиться об указании имени параметр. В случае с этим WSDL мне показалось немного нелепым, что нельзя просто передать одну переменную и покончить с ней. Я видел другую службу SOAP, где мне не нужно было указывать имя параметра.

Таким образом, способность понять структуру вызовов является ключом к упрощению всего этого.


person Patrick    schedule 19.06.2013    source источник
comment
Вас беспокоят индексированные или именованные параметры здесь или и то, и другое? (Почему порядок параметров SOAP имеет значение в PHP SOAP и как это исправить? ). Тогда при быстром сканировании ваша проблема может быть связана с пространствами имен XML. Из вашего вопроса мне не совсем понятно, к чему должна привести эта обработка. Возможно, вы захотите немного отредактировать вопрос и добавить пример, показывающий, чего вы пытаетесь достичь с помощью buildSchemaDetails.   -  person hakre    schedule 20.06.2013
comment
Вот также снимок XML на случай изменения URI: gist.github.com/hakre/5821049   -  person hakre    schedule 20.06.2013
comment
Интересно, будет ли использование classmap служить вам лучше. Вы исследовали этот вариант?   -  person denormalizer    schedule 21.06.2013
comment
Я не знаком с classmap. Я посмотрю на это.   -  person Patrick    schedule 21.06.2013