Est-ce que quelqu'un sait comment enregistrer toutes les demandes et les réponses avec le savacclient intégré dans PHP? Je pourrais en fait manuellement connecter manuellement tout avec Remarque: J'utilise le mode WSDL, donc en utilisant une méthode que tunnels all au tout à SOAPCLIENT :: __ getlastrequest () code> et
SOAPCLIENT :: __ getLasResponse () code> Mais nous avons ce beaucoup de demandes de savon dans notre système que je cherche Autres possibilités. P>
SOAPCLIENT :: __ SOAPCALL () code> n'est pas une option p>
7 Réponses :
Est-ce que quelque chose comme ça fonctionne?
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; } }
Cela ne fonctionne pas ... Avez-vous un aperçu de la raison pour laquelle __soapCall ne peut plus être remplacé?
Je pense que la meilleure façon est de remplacer SOAPCLIENT :: __ dorequest () code> (et pas
SOAPCLIENT :: __ SOAPCALL () CODE>) Comme vous aurez un accès direct à la Demande - ainsi que sur la réponse-XML. Mais l'approche générale de la sous-classe
SOAPCLIENT code> devrait être la voie à suivre.
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;
}
}
Je suppose que c'est une solution préférable au-dessus de la décorateur. En tant que SOAPCLIENT CODE> pas vraiment OOP-AISH, et il n'applique aucune interface, il n'est vraiment aucun moyen de rendre le décorateur compatible avec celui-ci du point de vue linguistique, si la dépendance du client de savon était de type Apparuré avec
\ soapclient code>. Si vous écrivez une bibliothèque qui utilise ce client vous-même, bien sûr, mieux pour l'envelopper et implémenter une interface. Mais si vous souhaitez remplacer l'objet dans une bibliothèque déjà existante, qui s'attend à un objet de type
SOAPCLIENT code>, les décorateurs ne le feront pas (mais encore une fois, s'il n'y a pas de conseils de type, vous pouvez y aller) .
@sevavietl c'est vrai. Mise en œuvre d'un décorateur compatible avec un indice de type code> SOAPCCLIENT code> Peut être problématique (en raison de l'interface manquante et de la nature dynamique du SOAPCLIENT code> API). Jamais essayé que moi-même, je ne peux pas juger s'il est possible en général ou non.
C'était la seule façon de travailler pour moi, en utilisant les méthodes dynamiques de WSDL.
I Deuxième suggestion Aleksanders et Stefans mais ne sousclureait pas SavapClient. Au lieu de cela, je serrais le savacclient régulier dans un décorateur, car la journalisation n'est pas une préoccupation directe du savacclient. De plus, le couplage lâche vous permet de remplacer facilement le savacclient avec une mocke dans vos instances. Vous pouvez donc vous concentrer sur le test de la fonctionnalité de journalisation. Si vous souhaitez uniquement enregistrer des appels spécifiques, vous pouvez ajouter une certaine logique qui filtre les demandes et les réponses de dollars par $ ou tout ce que vous voyez en forme.
EDIT STRUT> Comme Stefan a suggéré d'ajouter du code, le décorateur serait Probablement regarder quelque chose comme ça, bien que je ne suis pas sûr de la méthode __Call () (voir Stefans Commentaires) P> 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);
}
}
L'utilisation d'un décorateur est une très bonne idée. En fait, j'irais avec une solution de décorateur moi-même si je devais travailler sur le même problème. Mais je pense, la solution de sous-classement est un peu plus compréhensible.
Et puis il y a un problème de PHP qui désactive le empilement i> de décorateurs si vous utilisez la méthode-Overloading-Feature __ appel () code> dans l'un de vos décorateurs ou dans la classe être décoré (
savacclient code> dans ce cas).
Je ne savais pas qu'il y avait un problème avec __Call (). Avez-vous un lien où je peux lire à ce sujet? Ce serait bien de savoir. Oh, et j'ai ajouté le code ci-dessus.
Ce que je voulais dire, c'est que vous ne pouvez pas déterminer si une méthode est appelable lors de l'utilisation de __ appel () code>, appelera donc une méthode non existante augmentera toujours une erreur fatale. En cas de décoration du
SOAPCLIENT CODE>, vous pouvez vérifier
is_callable (tableau ($ ceci-> SOAPCLIENT, méthode $)) code> et
in_array ($ méthode, $ this-> SOAPCLIENT-> __GETHONCTIONS ()) CODE>. Mais cela ne permettra pas de pile des décorateurs.
Oubliez ma remarque sur le problème (et l'empilement des décorateurs) ... il est possible de faire les chèques que j'ai montrés ci-dessus et pourrons toujours empiler vos décorateurs. Désolé pour tout le chaos g i>
J'ai essayé cette solution, mais la méthode du journal n'est pas appelée, l'appel est transféré droit à Soapclient
Désolé de revoir un tel ancien poste, mais j'ai rencontré des défis avec la mise en œuvre de la réponse acceptée d'un décorateur qui est responsable de la journalisation des demandes de savon et que je voulais partager au cas où quelqu'un d'autre se déroule.
Imaginez Vous configurez votre instance comme ci-après, à l'aide de la classe SOAPClientlogger décrite dans la réponse acceptée. P>
$mySoapClient->AddMember($parameters); // AddMember is defined in the WSDL
Adressant le problème soulevé dans https://stackoverflow.com/a/3939077/861788 Je suis venu avec ce qui suit Solution ( Source complète ):
use Lc5\Toolbox\LoggingSoapClient\LoggingSoapClient; use Lc5\Toolbox\LoggingSoapClient\TraceableSoapClient; use Lc5\Toolbox\LoggingSoapClient\MessageXmlFormatter; use Monolog\Handler\StreamHandler; use Monolog\Logger; $handler = new StreamHandler('path/to/your.log'); $handler->setFormatter(new MessageXmlFormatter()); $logger = new Logger('soap'); $logger->pushHandler($handler); $soapClient = new LoggingSoapClient(new TraceableSoapClient('http://example.com'), $logger);
J'ai vérifié les demandes et les réponses avec Wireshark. P>
Je sais que c'est une question très ancienne, mais je vois des morceaux et des morceaux et il est difficile de le faire tout ensemble.
en expansinant sur Stefan Gehrig Réponse , j'ai fini par avoir à étendre SoapClient afin de pouvoir utiliser les méthodes dynamiques de la WSDL. Aussi, hors de commodité, cette classe ajoute l'option de traçage directement dans la construction. P> espère que cela aide à fournir une clarté sur les solutions possibles. P> P>