كيف يمكنني التقاط البيانات من محتوى XML لطلب SOAP في php SOAPServer؟

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

  •  12-12-2019
  •  | 
  •  

سؤال

أحاول إعداد خدمة SOAP في لغة php.لقد أعلنت عن وظيفة PHP للخادم وأنا قادر على استدعاء هذه الوظيفة باستخدام طلب http من نوع SOAP حيث يكون المحتوى هو مغلف SOAP الخاص بي.

محتوى XML لنص SOAP هو وسيطة الوظيفة التي أفترضها، لكنني لا أعرف كيفية الوصول إلى المعلومات الموجودة فيها في كود php الخاص بي.

لقد لاحظت أن وسيطة الوظيفة هي مثال لـ stdClass بشكل افتراضي، وأنا في الواقع أتساءل لماذا لم يتم طرحه على XML أو DOM كائن بواسطة php - إنه استدعاء SOAP، أليس كذلك؟لكن حسنًا، الأمر متروك لي الآن للحصول على المعلومات من الكائن، وهو أمر ليس بالسهل لأنه لا توجد طرق مخصصة لذلك stdClass, ، لذلك يجب أن تكون وظائف php قياسية.لذلك حاولت serialize, ، ولكن هذا أعطاني بعض الهراء، وليس سلسلة XML التي كنت أتوقعها.

ما يجب القيام به؟

يحرر

لاحظ أنه لا يوجد أدناه رمز مثال لما أرغب في القيام به - احصل على بعض البيانات التفصيلية من محتوى XML لطلب SOAP - لأنني لا أعرف كيفية ترميز الحصول عليه من كائن stdClass

بناء على طلب ديفيد، وهنا بعض التفاصيل.

كود 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 بواسطة التطبيق الذي أستخدمه)، هو

استجابة الصابون:

<?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، مثل الحصول على-XML-من-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 بدءًا من بعض الإصدارات فصاعدًا.

نصائح أخرى

لن يبدأ هذا كإجابة كاملة، لكنني أردت التنسيق.يرجى توضيح ما قمت بإعداده.بشكل عام، سيكون لديك طريقة PHP مع وسيطات عادية (وليس XML) تريد كشفها كخدمة ويب.يوجد مثال أساسي حول كيفية القيام بذلك هنا:

http://www.phpeveryday.com/articles/Web-Services-WSDL-Creating-SOAP-Server-P484.html

محتوى XML لنص SOAP هو وسيطة الوظيفة التي أفترضها

لا، محتوى XML لنص SOAP هو التمثيل من الطريقة مع حججك، ولكن حججك هي ما تريد.لا ينبغي عليك التعامل مع XML يدويًا إذا قمت بإعداده باستخدام SoapServer وSoapClient الخاصين بـ PHP.

يحرر:أنت تأخذ حجتك، وهي عبارة عن تمثيل بسيط لمصفوفة PHP لنص طلب SOAP الخاص بك، وتقوم بتسلسلها وإرسالها مرة أخرى كرد (وهو ما تلاحظه).هل هذا ما تريد أن تفعل؟ألا تريد أن تفعل شيئًا ببيانات الطلب؟هل يمكنك أيضًا نشر المخطط الذي تم استيراده من WSDL؟

لديك هذا التمثيل "غير اللطيف" لكائن ما لأنك تعيد الكائن المتسلسل (التسلسل هو تحويل الكائن وحالته إلى تمثيل سلسلة).إذا كنت تريد الحصول على تمثيل xml للكائن الذي تم إرجاعه، فيجب عليك تغيير نوع معلمة الإرجاع الخاصة بوظيفتك إلى كائن.لأن الآن يعود سلسلة.

أنصحك باستخدام مكونات Zend_Soap_Server وZend_Soap_Autodiscover لإطار عمل zend.

باستخدام Zend_Soap_Autodiscover، يمكنك إنشاء تعريف خدمة الويب (wsdl) ديناميكيًا، فقط عن طريق كتابة كتل المستندات الخاصة بوظائفك.وZend_Soap_Server رائع جدًا أيضًا.

إذا استخدمت هذه المكونات وقمت بتوثيق أنواعك ووظيفتك لإرجاع نوع معين دون إجراء تسلسل له، فستتلقى تمثيل XML وفقًا لتعريف wsdl.كما يتم أيضًا تحويل كل نوع تقوم بإنشائه تلقائيًا بواسطة Zend_Soap_Autodiscover إلى ComplexType في wsdl الذي تم إنشاؤه.

عينة:

 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