Вход всего запроса Мыла и ответов в PHP

Я думаю, что это действительно зависит от языка. На некоторых языках, Lisp, например, рекурсия часто является естественным ответом на проблему (и часто с языками, где дело обстоит так, компилятор оптимизирован для контакта с рекурсией).

общий шаблон в Lisp выполнения операции на первом элементе списка и затем вызывания функции на остальной части списка для или накопления значения или нового списка является довольно изящным и самым естественным способом сделать много вещей на том языке. В Java, не так.

10
задан ChrisR 13 November 2009 в 13:57
поделиться

3 ответа

Я повторяю предложение Александера и Стефанса, но не буду создавать подкласс SoapClient. Вместо этого я бы обернул обычный SoapClient в декоратор, потому что ведение журнала не является прямой проблемой SoapClient. Кроме того, слабая связь позволяет вам легко заменить SoapClient на макет в ваших модульных тестах, так что вы можете сосредоточиться на тестировании функциональности ведения журнала. Если вы хотите регистрировать только определенные вызовы, вы можете добавить некоторую логику, которая фильтрует запросы и ответы по $ action или тому, что вы считаете нужным.

Изменить , поскольку Стефан предложил добавить какой-то код, декоратор, вероятно, будет выглядеть примерно так этот, хотя я не уверен насчет метода __call () (см. комментарии Стефанса)

class SoapClientLogger
{
    protected $soapClient;

    // wrapping the SoapClient instance with the decorator
    public function __construct(SoapClient $client)
    {
        $this->soapClient = $client;
    }

    // Overloading __doRequest with your logging code
    function __doRequest($request, $location, $action, $version, $one_way = 0) 
    {
         $this->log($request, $location, $action, $version);

         $response = $this->soapClient->__doRequest($request, $location, 
                                                    $action, $version, 
                                                    $one_way);

         $this->log($response, $location, $action, $version);
         return $response;
    }

    public function log($request, $location, $action, $version)
    {
        // here you could add filterings to log only items, e.g.
        if($action === 'foo') {
            // code to log item
        }
    }

    // route all other method calls directly to soapClient
    public function __call($method, $args)
    {
        // you could also add method_exists check here
        return call_user_func_array(array($this->soapClient, $method), $args);
    }
}
18
ответ дан 3 December 2019 в 14:18
поделиться

Я думаю, что лучший способ - переопределить SoapClient :: __ doRequest () (а не SoapClient :: __ soapCall () ), поскольку у вас будет прямой доступ как к запросу, так и к XML-ответу. Но общий подход к подклассу SoapClient должен быть правильным.

class My_LoggingSoapClient extends SoapClient
{
    // logging methods

    function __doRequest($request, $location, $action, $version, $one_way = 0) 
    {
        $this->_logRequest($location, $action, $version, $request);
        $response = parent::__doRequest($request, $location, $action, $version, $one_way);
        $this->_logResponse($location, $action, $version, $response);
        return $response;
    }
}

РЕДАКТИРОВАТЬ

Из ООП-дизайна / паттерна проектирования точки зрения Декоратор , очевидно, лучший способ справиться с подобными проблемами - см. ответ Гордона . Но это немного сложнее реализовать.

7
ответ дан 3 December 2019 в 14:18
поделиться

Что-нибудь вроде этого сработает?

class MySoapClient extends SoapClient
{
    function __soapCall($function_name, $arguments, $options = null, $input_headers = null, &$output_headers = null) 
    {
        $out = parent::__soapCall($function_name, $arguments, $options, $input_headers, $output_headers);

        // log request here...
        // log response here...

        return $out;
    }
}

Поскольку SoapClient уже отправляет все запросы через __soapCall, вы можете перехватывать их, создав подкласс SoapClient и переопределив его. Конечно, чтобы он заработал, вам нужно также заменить каждый новый SoapClient (...) в вашем коде на новый MySoapClient (...) , но это выглядит довольно неплохо. удобный поиск и замена задачи.

1
ответ дан 3 December 2019 в 14:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: