13

我是 Magento 的新手,我想创建一个自己的 API v2 方法。我已经建立了一个简单的项目......

Mycompany
    Mymodule
        etc
            api.xml
            config.xml
            wsdl.xml
        Model
            Api
                V2.php
            Api.php


这些是主要文件...
(1) api.xml

<config>
    <api>
        <resources>
            <mymodule translate="title" module="mymodule">
                <title>mymodule</title>
                <model>mymodule/api</model>
                <methods>                    
                    <myapimethod translate="title" module="mymodule">
                        <title>myapimethod</title>
                        <acl>mymodule/myapimethod</acl>
                    </myapimethod>
                </methods>
            </mymodule>
        </resources>
        <v2>
            <resources_function_prefix>
                <mymodule>mymodule</mymodule>
            </resources_function_prefix>
        </v2>
        <acl>
            <resources>
                <mymodule translate="title" module="mymodule">
                    <title>Mymodule</title>
                    <sort_order>2000</sort_order>                    
                    <myapimethod translate="title" module="mymodule">
                        <title>myapimethod</title>
                    </myapimethod>  
                </mymodule>
            </resources>
        </acl>
    </api>
</config>

(2)wsdl.xml

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
    name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
    <types>
        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
            <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
        </schema>
    </types>
    <message name="myapimethodRequest">
        <part name="sessionId" type="xsd:string"/>
        <part name="message" type="xsd:string" />
    </message>
    <message name="myapimethodResponse">
        <part name="result" type="xsd:string" />
    </message>
    <portType name="{{var wsdl.handler}}PortType">
        <operation name="myapimethod">
            <documentation>this is an example of api method...</documentation>
            <input message="typens:myapimethodRequest" />
            <output message="typens:myapimethodResponse" />
        </operation>
    </portType>
    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
        <operation name="myapimethod">
            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
            <input>
                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
            </input>
            <output>
                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
            </output>
        </operation>
    </binding>
    <service name="{{var wsdl.name}}Service">
        <port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
            <soap:address location="{{var wsdl.url}}" />
        </port>
    </service>
</definitions>

(3) api.php

<?php
class Mycompany_Mymodule_Model_Api extends Mage_Api_Model_Resource_Abstract
{        
        public function myapimethod($sessionId, $message)
        {
            return "This is the message : ".$message;
        }
}

(4) V2.php

<?php
class Mycompany_Mymodule_Model_Api_V2 extends Mycompany_Mymodule_Model_Api
{        

}

(5)test.php

<?php
try {
    define("SOAP_WSDL",'http://localhost:8080/magento/index.php/api/?wsdl');
    define("SOAP_WSDL2",'http://localhost:8080/magento/index.php/api/v2_soap?wsdl=1');
    define("SOAP_USER","dtsSoapUser");
    define("SOAP_PASS","casares");

    if($_GET['ver'] == '2') {
        $client = new SoapClient(SOAP_WSDL2, array('trace' => 1,'cache_wsdl' => 0));
        echo "<br>version 2 <br>";
    }
    else {
        $client = new SoapClient(SOAP_WSDL,array('trace' => 1,'cache_wsdl' => 0));

        echo "<br>version 1 <br>";
    }
    $session = $client->login(SOAP_USER, SOAP_PASS);
    $result = array();

    try {
        if($_GET['ver'] == '2') {
             $result = $client->Myapimethod($session, "My message....");
             var_dump ( $result);        
        } else {            
            $result= $client->call($session, 'mymodule.myapimethod', array($session, "My message ...."));
            var_dump($result);
        }
    } catch (SoapFault $exception) {
        echo 'EXCEPTION='.$exception;
    }

    echo "<br>end test<br>";
} catch (Exception $e){
    echo var_dump($e);
    throw $e;
}   
?>

使用以下网址,结果是:

.../test.php/?ver=1

version 1
string 'This is the message : My message ....' (length=37)
end test

就是说:使用 Soap v1,该方法有效!

但是如果我使用soap v2调用......

.../test.php/?ver=2 结果是:

version 2
EXCEPTION=SoapFault exception: [3] Invalid api path. in C:\wamp\www\PruebasPHP\test.php:22 Stack trace: #0 C:\wamp\www\PruebasPHP\test.php(22): SoapClient->__call('Myapimethod', Array) #1 C:\wamp\www\PruebasPHP\test.php(22): SoapClient->Myapimethod('b9e1e8d15a61398...', 'My message....') #2 {main}
end test


该角色可以访问所有 api 资源...

我不知道出了什么问题?谁能帮我解决这个问题?可以与acl相关吗?提前致谢!!!

4

2 回答 2

7

是路径的问题。
我已经解决了以下问题......
我的项目的文件夹结构是:

Mycompany->
    Mymodule->
        etc->
            api.xml
            config.xml
            wsdl.xml
            wsi.xml
        Model->
            Folder->
                Api.php
                Api->
                    V2.ph

(1) api.xml

<?xml version="1.0"?>
<config>
    <api>
        <resources>
            <mymodule_folder translate="title" module="mymodule">
                <title>mymodule</title>
                <!-- acl>mymodule/api</acl>-->
                <model>mymodule/folder_api</model>
                <acl>mymodule/folder</acl>
                <methods>                    
                    <myapimethod translate="title" module="mymodule">
                        <title>myapimethod</title>
                        <acl>mymodule/folder/myapimethod</acl>
                    </myapimethod> 
                </methods>
            </mymodule_folder>
        </resources>
        <resources_alias>
            <folder>mymodule_folder</folder>
         </resources_alias>

        <v2>
            <resources_function_prefix>
                <folder>folder</folder>
            </resources_function_prefix>
        </v2>
        <acl>
            <resources>
                <mymodule translate="title" module="mymodule">
                    <title>mymodule</title>
                    <sort_order>1</sort_order>
                    <folder translate="title" module="mymodule">
                        <title>Folder</title>
                        <sort_order>2000</sort_order>                    
                <myapimethod translate="title" module="mymodule">
                            <title>myapimethod</title>
                        </myapimethod>  
                    </folder>
             </mymodule>
            </resources>
        </acl>
    </api>
</config>

注意 api 方法的名称"myapimethod"和文件夹"Model\Folder"

(2)wsdl.xml

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
    name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
    <types>
        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
            <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
        </schema>
    </types>
    <message name="folderMyapimethodRequest">
        <part name="sessionId" type="xsd:string"/>
        <part name="message" type="xsd:string" />
    </message>
    <message name="folderMyapimethodResponse">
        <part name="result" type="xsd:string" />
    </message>
    <portType name="{{var wsdl.handler}}PortType">
        <operation name="folderMyapimethod">
            <documentation>this is an example of api method...</documentation>
            <input message="typens:folderMyapimethodRequest" />
            <output message="typens:folderMyapimethodResponse" />
        </operation>
    </portType>
    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
        <operation name="folderMyapimethod">
            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
            <input>
                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
            </input>
            <output>
                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
            </output>
        </operation>
    </binding>
    <service name="{{var wsdl.name}}Service">
        <port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
            <soap:address location="{{var wsdl.url}}" />
        </port>
    </service>
</definitions> 

api方法的名称必须是:folderMethodname”,其中“folder”是声明api方法的“Model”下的文件夹的名称..,在我们的例子中:“folderMyapimethod”
(3)api.php

<?php
class Mycompany_Mymodule_Model_Folder_Api extends Mage_Api_Model_Resource_Abstract
{        
        public function myapimethod( $message)
        {
            return "This is the message: ".$message;
        }
}

(4) V2.php

<?php
class Mycompany_Mymodule_Model_Folder_Api_V2 extends Mycompany_Mymodule_Model_Folder_Api
{   
     //empty     
}


(5)test.php

$result = $client->folderMyapimethod($session,$message);

此行显示如何调用我的 api 方法...

有用!

于 2012-09-04T07:32:34.870 回答
1

你的代码很棒!没有错误

据我所知(根据我的经验)。显示该异常是因为您在 api.xml 上的标记位置与您调用的函数不匹配。


检查文件

core\Mage\Catalog\Model\Product\Api.php

core\Mage\Catalog\Model\Product\Api\V2.php

两个类都有一个名为items的函数。

也许您必须在 api_v2 类的 api_v1 上添加代码,如下所示:

<?php
class Mycompany_Mymodule_Model_Api_V2 extends Mycompany_Mymodule_Model_Api
{        
    public function myapimethod($sessionId, $message)
    {
        return "This is the message : ".$message;
    }
}

或者

也许是缓存

缓存很强大,因为它是 API V2。尝试清除缓存:

  1. 管理员 -> 系统 -> 缓存管理 -> 清除 magento 缓存。
  2. 尝试清除 /tmp/wsdl.xml 上的 wsdl.xml 缓存(隐藏在您的服务器上)尝试grep它。
  3. 删除 var/log/* 上的所有文件
于 2012-08-30T17:17:43.820 回答