Сериализация объекта PHP SOAPClient - PullRequest
4 голосов
/ 23 марта 2011

Я пишу PHP-приложение, которое использует несколько веб-сервисов SOAP для сбора данных.

Я получаю значительные накладные расходы на создание экземпляров всех этих объектов: в некоторых случаях одна строка кода $object = new SoapClient($wsdl); может занять более трех секунд.Очевидно, что для того, чтобы веб-страница выглядела очень медленно, требуется всего несколько.

Чтобы немного ускорить процесс, я решил, что сериализую объекты и сохраню их в сеансе (или где-то похожем)поэтому я написал следующую функцию:

function soap_client($name,$wsdl) {
    if (!isset($_SESSION['soapobjects'][$name])) {
        $client = new SoapClient($wsdl, array('trace' => 1));
            $_SESSION['soapobjects'][$name]=serialize($client);
        } else {
            $client = unserialize($_SESSION['soapobjects'][$name]);
        }
    return $client;
}

Это, безусловно, похоже на способ, которым PHP рекомендует сделать это .

... и затем вызвать его так...

$client = soap_client('servicename',$wsdl);
$client->MethodName($parameters);

Однако, похоже, это не сработает.

При первом запуске он работает (т. Е. Объект создается и создается сериализованная копия,и вызов метода работает нормально).Однако во второй раз, когда вы запускаете его, он не работает.

Объект появляется для правильной сериализации и десериализации, но при попытке выполнить вызов SOAP для десериализованного объекта,он выдает следующую ошибку:

Fatal error: Uncaught SoapFault exception: [Client] Error finding "uri" property

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

МожетКто-нибудь объяснить, почему я получаю эту ошибку?Можете ли вы предложить способ заставить его работать или альтернативную стратегию, которую я мог бы убедить?

Спасибо.

ps - я пытался обойти проблему, но не радости.

Я попытался указать URI в параметре параметров (как указано в руководстве PHP SOAP Client ), но это не имело никакого значения.Но это не должно быть необходимо, так как я использую WSDL.

Я также пытался просто скопировать объект в $_SESSION, без использования serialize() и deserialize(), но это имеетточно такой же эффект.

Ответы [ 2 ]

3 голосов
/ 23 марта 2011

Встроенное расширение SOAP - это неразрушаемый двоичный код ужасов. Весьма вероятно, что он не был построен с учетом сериализации. Например, он может содержать внутренний дескриптор файла, который не выдержит процесс сериализации / десериализации. Я призываю вас использовать другой клиент SOAP, например:

  • Zend_Soap , часть Zend Framework. Вам не нужно использовать Framework в любой другой области вашего кода, и, вероятно, вы можете удалить большинство других компонентов. Тем не менее, похоже, что он использует существующее расширение SOAP под прикрытием, поэтому он, вероятно, не является хорошим кандидатом для сериализации.
  • PEAR SOAP часто упоминается, хотя он немного староват.
  • NuSOAP недавно был возвращен из мертвых, хотя вся онлайн-документация, похоже, исчезла в zip-файлах.

Если ни один из них не подходит, рассмотрите возможность кэширования файла WSDL локально, так как я как-то ожидаю, что отсюда и задержка.

2 голосов
/ 25 апреля 2011

Согласно вашим комментариям к предыдущему ответу, лучшим вариантом будет использование Zend Framework только для мыла, как было предложено ранее, это позволит вам продолжать использовать php и при этом иметь лучшую функциональность с Zend. Также вы можете использовать другие функции Zend, если ваши требования возрастают.

Этот пример может вам помочь http://blog.fedecarg.com/2009/02/15/building-a-web-service-client-using-the-zend-framework/

...