두 번째로 Aleksanders와 Stefans는 제안하지만 SoapClient를 하위 클래스로 분류하지는 않습니다. 로깅은 SoapClient의 직접적인 관심사가 아니기 때문에 대신 데코레이터에 일반 SoapClient를 래핑합니다. 또한 느슨한 결합을 사용하면 UnitTests의 모의 객체로 SoapClient를 쉽게 대체 할 수 있으므로 로깅 기능 테스트에 집중할 수 있습니다. 특정 호출 만 기록하려는 경우 $ action 또는 적합하다고 판단되는 항목으로 요청 및 응답을 필터링하는 논리를 추가 할 수 있습니다. 스테판 이후
편집는
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);
}
}
데코레이터를 사용하는 것이 좋습니다. 사실 나는 같은 문제를 해결해야만한다면 데코레이터 솔루션으로 직접 갈 것입니다. 하지만 서브 클래 싱 솔루션은 좀 더 이해하기 쉽습니다. –
아마도 코드 샘플을 추가하면 OP가 도움이 될 것입니다. –
그리고 꾸미기 중 하나 또는 꾸미기 클래스에서 method-overloading-feature'__call()'을 사용한다면 데코레이터의 * stacking *을 허용하지 않는 PHP 문제가 있습니다 ('SoapClient' in this 케이스). –