douwei8096 2012-04-20 13:31
浏览 226
已采纳

如何在Yii中创建Web服务SOAP 1.2

The Problem:

I can't figure out how Yii expects me to change the soap version. I'm following this tutorial. The web service works, but it isn't SOAP 1.2

The Class:

<?php
class ABFolioController extends CController
{
    public function actions()
    {
        return array(
            'folio'=>array(
                'class'=>'CWebServiceAction',
                'serviceOptions'=>array('soapVersion'=>'1.2')
            ),
        );

    }

    /**
     * @param  string folioId
     * @param  string cNumber
     * @param  string oDRS
     * @param  string dlr
     * @param  string feeAmount
     * @param  string transactionStatus
     * @param  string captureId
     * @param  datetime captureTimestamp
     * @param  string prefix
     * @param  string oDEFRS
     * @return string the statement
     * @soap
     */
    public function sendFolio($folioId, $cNumber, $oDRS, $dlr,
            $feeAmount, $transactionStatus, $captureId, $captureTimestamp, 
            $prefix, $oDEFRS)
    {
    //

      $model = new Dlfolio();
      $model->folioId = $folioId;
      $model->cNumber = $cNumber;
      $model->oDRS = $oDRS;
      $model->dlr = $dlr;
      $model->feeAmount = $feeAmount;
      $model->transactionStatus = $transactionStatus;
      $model->captureId = $captureId;
      $model->captureTimestamp = $captureTimestamp;
      $model->prefix = $prefix;
      $model->oDEFRS = $oDEFRS;
      $yesno = $model->save();

      if ($yesno=TRUE)
      {
          //on success
          return 'Record Saved';
      }
      else
      {
          //on failure
          return $yesno;
      }

    }   
}
  • 写回答

1条回答 默认 最新

  • dsq2015 2012-04-24 10:14
    关注

    when i set up client to be v1.2 i always receive v1.2 response from server, and when i set up client to be v1.1 i always receive v1.1 response from server, maybe it auto-detects client version and overrides server version with it?

    $client=new SoapClient('http://hys.local/ABFolio/folio',array('soap_version'=>SOAP_1_2,'trace'=>true));
    var_dump($client);
    echo $client->sendFolio();
    echo $client->__getLastRequest();
    echo $client->__getLastResponse();
    

    response is 1.2

    <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"
    

    and with 1.1 which default for client

    $client=new SoapClient('http://hys.local/ABFolio/folio',array('soap_version'=>SOAP_1_1,'trace'=>true));
    

    response is 1.1

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    

    EDIT:

    lets look inside yii framework\web\services\CWebService.php

    /**
     * @return array options for creating SoapServer instance
     * @see http://www.php.net/manual/en/function.soap-soapserver-construct.php
     */
    protected function getOptions()
    {
        $options=array();
        if($this->soapVersion==='1.1')
            $options['soap_version']=SOAP_1_1;
        else if($this->soapVersion==='1.2')
            $options['soap_version']=SOAP_1_2;
        if($this->actor!==null)
            $options['actor']=$this->actor;
        $options['encoding']=$this->encoding;
        foreach($this->classMap as $type=>$className)
        {
            $className=Yii::import($className,true);
            if(is_int($type))
                $type=$className;
            $options['classmap'][$type]=$className;
        }
        return $options;
    }
    

    i don't see any error in your code if i check this code

    EDIT:

    ok, how about this than? framework\web\services\CWsdlGenerator.php

    /*
     * @param DOMDocument $dom Represents an entire HTML or XML document; serves as the root of the document tree
     */
    private function addBindings($dom)
    {
        $binding=$dom->createElement('wsdl:binding');
        $binding->setAttribute('name',$this->serviceName.'Binding');
        $binding->setAttribute('type','tns:'.$this->serviceName.'PortType');
    
        $soapBinding=$dom->createElement('soap:binding');
        $soapBinding->setAttribute('style','rpc');
        $soapBinding->setAttribute('transport','http://schemas.xmlsoap.org/soap/http');
        $binding->appendChild($soapBinding);
    
        $dom->documentElement->appendChild($binding);
    
        foreach($this->_operations as $name=>$doc)
            $binding->appendChild($this->createOperationElement($dom,$name));
    }
    

    as i can see transport is predefined (you can check and replace it to 12)

    my wsdl becomes this after adding 12

    <wsdl:binding name="ABFolioControllerBinding" type="tns:ABFolioControllerPortType">    
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap12/http"/>
    </wsdl:binding>
    

    maybe it's bug in yii - go ahead and report it then

    but as from http://msdn.microsoft.com/en-us/library/ms995800.aspx i was checking not a transport but namespace

    SOAP versioning is based on XML namespaces. SOAP 1.1 is identified by the http://schemas.xmlsoap.org/soap/envelope/ namespace while SOAP 1.2 is identified by the http://www.w3.org/2002/12/soap-envelope namespace (although this will change when it becomes a Recommendation). 
    

    that's why i thought all is correct

    EDIT:

    here's decesion, you need to have

    xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" 
    

    inside <definitions in your xml in addition to

    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    

    and instead of this:

    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    

    you must place

    <soap12:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    

    now soapUI detects my wsdl as soap 1.2

    <?xml version="1.0" encoding="UTF-8"?>
    <definitions 
    xmlns="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:tns="urn:ABFolioControllerwsdl" 
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" 
    name="ABFolioController" 
    targetNamespace="urn:ABFolioControllerwsdl">
        <wsdl:portType name="ABFolioControllerPortType"/>
        <wsdl:binding name="ABFolioControllerBinding" type="tns:ABFolioControllerPortType">
            <soap12:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
        </wsdl:binding>
        <wsdl:service name="ABFolioControllerService">
            <wsdl:port name="ABFolioControllerPort" binding="tns:ABFolioControllerBinding">
                <soap:address location="http://hys.local/uk/aBFolio/folio?ws=1"/>
            </wsdl:port>
        </wsdl:service>
    </definitions>
    

    all replacement you can do in same files in yii in addBindings and buildDOM functions

    also i think it much harder, i.e. you must have both soap and soap12 bindings if you want to support both, but at least it already recognized as soap12

    EDIT:

    yii hardcoded soap1.1 if you don't provide your own wsdl (you can provide it via $wsdlUrl as in run method of CWebService). it seems legit - becouse default soap version in php soap server is 1.1 too, if you changing your version to 1.2 you must provide your own wsdl for 1.2

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 delta降尺度方法,未来数据怎么降尺度
  • ¥15 c# 使用NPOI快速将datatable数据导入excel中指定sheet,要求快速高效
  • ¥15 再不同版本的系统上,TCP传输速度不一致
  • ¥15 高德地图点聚合中Marker的位置无法实时更新
  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程