PHP SOAPServer에서 SOAP 요청의 XML 콘텐츠에서 데이터를 어떻게 포착합니까?

StackOverflow https://stackoverflow.com//questions/12692797

  •  12-12-2019
  •  | 
  •  

문제

PHP에서 SOAP 서비스를 설정하려고 합니다.서버 PHP 함수를 선언했고 내용이 내 SOAP 봉투인 SOAP 유형 http 요청으로 해당 함수를 호출할 수 있습니다.

SOAP 본문의 XML 콘텐츠는 내가 가정하는 함수의 인수이지만 내 PHP 코드에서 그 정보에 액세스하는 방법을 모르겠습니다.

함수 인수가 다음의 인스턴스라는 것을 알았습니다. stdClass 기본적으로 왜 이것이 캐스팅되지 않는지 궁금합니다. XML 또는 DOM PHP에 의한 객체 - SOAP 호출이 아닌가요?하지만 좋습니다. 이제 개체에서 정보를 가져오는 것은 나에게 달려 있습니다. 개체에 할당된 메서드가 없기 때문에 쉽지 않습니다. stdClass, 따라서 표준 PHP 함수여야 합니다.그래서 나는 노력했다 serialize, 그러나 이것은 내가 기대했던 XML 문자열이 아닌 약간의 쓰레기를 제공했습니다.

무엇을 해야 할까요?

편집하다

아래에는 내가 하려는 작업에 대한 예제 코드가 없습니다. SOAP 요청의 XML 콘텐츠에서 일부 세부 데이터를 가져옵니다. 왜냐하면 stdClass 객체에서 데이터를 가져오는 코드를 작성하는 방법을 모르기 때문입니다.

David의 요청에 따라 몇 가지 세부정보를 알려드립니다.

PHP 코드:

<?php
    function mi102($arg) {
        $txt = serialize ($arg);
        $result = new SoapVar ($txt, XSD_ANYXML);
        return($result);
    }
    ini_set( "soap.wsdl_cache_enabled", "0");
    $server = new SoapServer ("test.wsdl");
    $server -> addFunction ("mi102");
    try {
        $server -> handle();
    }
    catch (Exception $e) {
        $server -> fault ('Client', $e -> getMessage());
    }
?php>

http 요청은 내가 사용하는 애플리케이션에 의해 구성됩니다.http 헤더와 비누 봉투 + 본문은 내가 제공한 XML 주위에 생성됩니다.

SOAP 요청 본문 내용:

<mi102 xmlns="http://pse">
  <cdhead cisprik="21"/>
  <instr>
    <insid>
      <bcdt>20120930</bcdt>
    </insid>
  </instr>
</mi102>

사용된 WSDL은 다음과 같습니다.

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://pse/" xmlns:xs="http://www.w3.org/2001/XMLSchema" name="PSE" targetNamespace="http://pse/">
    <types>
        <xs:schema>
            <xs:import namespace="http://pse/" schemaLocation="PSE.xsd"/>
        </xs:schema>
    </types>
    <message name="MI102Req">
        <part name="cdhead" type="tns:cdhead_T"/>
        <part name="instr" type="tns:instr_T"/>
    </message>
    <message name="Res">
        <part name="cdhead" type="tns:cdhead_T"/>
    </message>
    <portType name="MIPortType">
        <operation name="mi102">
            <input message="tns:MI102Req"/>
            <output message="tns:Res"/>
        </operation>
    </portType>
    <binding name="MIBinding" type="tns:MIPortType">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="mi102">
            <soap:operation soapAction="http://testServerURL/test_soap.php#mi102"/>
            <input>
                <soap:body use="literal" namespace="http://pse/"/>
            </input>
            <output>
                <soap:body use="literal" namespace="http://pse/"/>
            </output>
        </operation>
    </binding>
    <service name="PSE">
        <port name="MIPortType" binding="tns:MIBinding">
            <soap:address location="http://testServerURL/test_soap.php"/>
        </port>
    </service>
</definitions>

결과 XML(역시 내가 사용하는 애플리케이션에 의해 SOAP 본문에서 추출됨)은 다음과 같습니다.

SOAP 응답:

<?xml version="1.0" encoding="UTF-8"?>
<ns1:mi102Response xmlns:ns1="http://pse/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">O:8:"stdClass":2:{s:7:"cisprik";i:21;s:7:"version";s:2:"13";}</ns1:mi102Response>

좋지 않아.

도움이 되었습니까?

해결책

나는 결국 SO의 다른 스레드에서 답을 찾았습니다. get-recieved-xml-from-php-soap-server

해결책은 다음을 사용하는 것입니다.

$inp = file_get_contents ('php://input');

메모:에서 작동할 수 있는 기능을 찾을 수 없습니다. stdClass 입력 인수를 입력하고 여기에서 XML SOAP 본문 내용을 검색할 수 있습니다.
따라서 가장 좋은 옵션은 표준 PHP 입력 변수를 사용하는 것입니다.이 구조는 다음과 같습니다. Envelope/Body/..inputXML.., 이는 서버에 게시되는 정확한 http 요청 콘텐츠입니다.

메모: http_get_request_body 작동할 수도 있지만 내 PHP 서버는 이 기능을 지원하지 않았습니다.내 생각에는 file_get_contents 일부 버전 이후의 모든 PHP 서버에서 지원됩니다.

다른 팁

이것은 완전한 대답으로 시작되지 않지만 서식을 원했습니다. 당신이 설정 한 것에 대해 자세히 설명하십시오. 일반적으로 웹 서비스로 노출 할 정규 인수 (XML 아님)가있는 PHP 메소드가 있습니다. 이를 수행하는 방법에 대한 기본 예제는 다음과 같습니다.

http : //www.phpeveryday. com / articles / web-services-wsdl-createst-soap-server-p484.html

SOAP 본문의 XML 함량은

를 가정하는 함수의 인수입니다.

아니오, SOAP 본체의 XML 함량은 인수와 함께 방법의 표현 이지만, 귀하의 논쟁은 원하는대로 무엇이든간에 있습니다. PHP의 Soapserver 및 SoapClient로 설정하면 XML을 수동으로 처리 할 필요가 없습니다.

편집 : SOAP 요청의 본문의 간단한 PHP 배열 표현이며,이를 직렬화하고 응답으로 다시 보내십시오 (관찰하는 것인지). 이것이 당신이하고 싶은 것입니까? 요청 데이터로 뭔가를하고 싶지 않습니까? 또한 WSDL에서 가져온 스키마를 게시 할 수 있습니까?

직렬화를 반환하기 때문에 객체의 "멋진"표현이 없으므로 (직렬화는 객체와 그 상태를 문자열 표현으로 변환합니다). 반환 된 객체의 XML 표현을 원한다면 함수의 리턴 매개 변수 유형을 개체로 변경해야합니다. 이제 문자열을 반환하기 때문에

zend_soap_server 및 zend_soap_autodiscover 구성 요소의 Zend Framework의 zend_soap_autodiscover 구성 요소를 사용하는 것이 좋습니다.

zend_soap_autodiscover를 사용하면 기능의 DocBlocks를 작성하여 웹 서비스 정의 (WSDL)를 동적으로 생성 할 수 있습니다. zend_soap_server도 꽤 멋지다.

해당 구성 요소를 사용하고 유형과 함수를 문서화하면 특정 유형을 직렬화하지 않고 반환 한 다음 WSDL 정의에 따라 XML 대표를 수신 할 것입니다. 또한 작성한 각 유형은 Zend_SOAP_AUTODISCOVER에 의해 생성 된 WSDL 생성 된 WSDL의 COMPLEXTYPE로 자동 변환됩니다.

샘플 :

 public class Person{
         public $id;
         public $name;
    }

    public class MyService {
     /**
     *
     * @param integer $UserID
     * @return Person
     */
    function mi102($UserID) {

         $output = new Person();
         $output->id = 2;
         $output->name = 'Peter';        

        return $output;
    }
}


// Generate WSDL relevant to code
if (isset($_GET['wsdl'])){

    $autodiscover = new Zend_Soap_AutoDiscover();
    $autodiscover->setClass('MyService');
    $autodiscover->handle();

} else {

    $server = new Zend_Soap_Server($serviceURL . "?wsdl");
    $server->setClass('MyService');
    $server->setObject(new MyService());
    $server->handle();

}
.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top