x = 10; * $addRequest->y = 20; * * This object does not match the signature of the server-side * MyCalculatorService and lead to failure. * * Also the response object in this case is supposed to be an array * or object with a property "addResult": * * $addResponse = new \stdClass; * $addResponse->addResult = 30; * * To keep your service object code free from this implementation detail * of SOAP this wrapper service handles the parsing between the formats. * * @example * * $service = new MyCalculatorService(); * $soap = new \Zend\Soap\Server($wsdlFile); * $soap->setObject(new \Zend\Soap\Server\DocumentLiteralWrapper($service)); * $soap->handle(); * */ class DocumentLiteralWrapper { /** * @var object */ protected $object; /** * @var ReflectionObject */ protected $reflection; /** * Pass Service object to the constructor * * @param object $object */ public function __construct($object) { $this->object = $object; $this->reflection = new ReflectionObject($this->object); } /** * Proxy method that does the heavy document/literal decomposing. * * @param string $method * @param array $args * @return mixed */ public function __call($method, $args) { $this->_assertOnlyOneArgument($args); $this->_assertServiceDelegateHasMethod($method); $delegateArgs = $this->_parseArguments($method, $args[0]); $ret = call_user_func_array(array($this->object, $method), $delegateArgs); return $this->_getResultMessage($method, $ret); } /** * Parse the document/literal wrapper into arguments to call the real * service. * * @param string $method * @param object $document * @return array * @throws Exception\UnexpectedValueException */ protected function _parseArguments($method, $document) { $reflMethod = $this->reflection->getMethod($method); $params = array(); foreach ($reflMethod->getParameters() as $param) { $params[$param->getName()] = $param; } $delegateArgs = array(); foreach (get_object_vars($document) as $argName => $argValue) { if (!isset($params[$argName])) { throw new Exception\UnexpectedValueException(sprintf( "Received unknown argument %s which is not an argument to %s::%s", $argName, get_class($this->object), $method )); } $delegateArgs[$params[$argName]->getPosition()] = $argValue; } return $delegateArgs; } /** * Returns result message content * * @param string $method * @param mixed $ret * @return array */ protected function _getResultMessage($method, $ret) { return array($method . 'Result' => $ret); } /** * @param string $method * @throws Exception\BadMethodCallException */ protected function _assertServiceDelegateHasMethod($method) { if (!$this->reflection->hasMethod($method)) { throw new Exception\BadMethodCallException(sprintf( "Method %s does not exist on delegate object %s", $method, get_class($this->object) )); } } /** * @param array $args * @throws Exception\UnexpectedValueException */ protected function _assertOnlyOneArgument(array $args) { if (count($args) != 1) { throw new Exception\UnexpectedValueException(sprintf( "Expecting exactly one argument that is the document/literal wrapper, got %d", count($args) )); } } }