蛋糕和nusoap - 函数(“my_function”)不是此服务的有效方法

时间:2012-10-30 11:32:47

标签: php cakephp soap nusoap

我接管了以前的开发人员的应用程序,并且有一些代码使用Nusoap完成了一半,我收到了错误:

Call to register_donation() web service failed due to an exception: 
Function ("register_donation") is not a valid method for this service   

该应用程序建立在:CakePHP 1.2.10&使用nuSoap 0.9.5

我已经ini_set('soap.wsdl_cache_enabled', 0);(这没有帮助。)

我的代码如下(为了便于阅读,我将其缩短了),我是否正确处理了此响应? (代码由我自己以前的开发人员接管。)

Pastebin(完整代码)在这里:PasteBin Link

下面是缩短版本的一览,完整版本在上面的pastebin链接中。

<?php
ini_set('soap.wsdl_cache_enabled', 0);

class ServicesController extends AppController
{
var $uses = array("Donation");
var $components = array( "Email", "MatchingEvents" );

function registerDonation($donation = null){
    $this->log('hit registerDonation', 'donation');
    $this->autoRender = false;
    App::import('Vendor','nusoap');
    Configure::write('debug',0);
    Configure::write('Session.start', false);

    //init soap server
    $server = new soap_server();

    $endpoint = 'http://new.mysite.com/services/registerDonation';

    //initialize WSDL support
    $server->configureWSDL('donations', 'urn:donations', $endpoint);

    //setup service type
    $server->wsdl->addComplexType(
        'DonationResult',
        'complexType',
        'struct',
        'all',
        '',
        array(
            'success' => array('name' => 'success', 'type' => 'xsd:boolean'),
            'msg' => array('name' => 'msg', 'type' => 'xsd:string'),
            'error_number' => array('name' => 'error_number', 'type' => 'xsd:string')
        )
    );

    //register the method to expose
    $server->register('register_donation',
        array('ct_number' => 'xsd:string', 'project_id' => 'xsd:int', 'donation_amount' => 'xsd:decimal',
            // Stripped all other params
        ),
        array(
            'result' => 'tns:DonationResult'
        ),
        'urn:donations',
        'urn:donations#register_donation',
        'rpc',
        'encoded',
        'Accepts the results of a donation to a charity or project on the  site'
    );

    //This inner function is registered and then called (keep within outer function!)
    function register_donation(
        // Pass in all the params (Stripped for readability)
        $ct_number = null, $project_id = null, $donation_amount = null
    ){
        // This function is never hit!.. its not registered, why?
        $this->log('hit #3-register_donation called!', 'donation');
        $return = $this->Donation->add(array(
            'unique_id' => $unique_id,
            'ct_number' => $ct_number,
            'project_id' => $project_id,
            'donation_amount' => $donation_amount,
            // Pass in all other params, (Stripped for readability)
        ));

        // Process that request
        $log = $this->Donation->log . 'Result: ' . $return['msg'] . "\n";
        $this->log( $log, 'donation' );
        if ( isset($this->Donation->matching['events']) )
        {
            //Reserved donations should already have had their events handled
            $this->MatchingEvents->handle($this->Donation->matching, !$this->Donation->matching['reserved']);
        }
        if ( !empty($this->Donation->cacheSaved) )
            $this->_sendDonationEmails($this->Donation->cacheSaved);
        return $return;
    }

    $HTTP_RAW_POST_DATA = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : '';
    $server->service($HTTP_RAW_POST_DATA);
}

function _sendDonationEmails($donation)
{
    // Send the emails
}
}

?>

如果我能提供更多信息,请告诉我。

总结:如何处理来自外部来源的nusoap响应。
 任何调试思路,提示&amp;提示或解决方案将得到奖励(+1!)。

1 个答案:

答案 0 :(得分:4)

在发布的代码中,名为registerDonation的控制器中有一个名为ServicesController的函数。在该函数内部还有另一个名为register_donation的函数(这显然没有意义[旧代码])。

register_donation方法中删除名为registerDonation的函数,并将其作为方法放在ServicesContoller中。

然后更改以下行(注册要公开的函数)。

来自:$server->register('register_donation',
到:$server->register('ServicesController.register_donation',

所以你调用class.method而不是方法(这可以在PHP4过程编程中工作,但在OOP中,你需要在公开函数时指定controller.method


还有其他问题吗?

问:CakePHP&amp; nuSOAP没有达到我的控制器/方法,而是重定向到app / webroot A:使用CakePHP 1.2,我发现它没有服务模型(因为它不是 技术上要求),请求没有命中控制器。因此,如果您遇到此问题,请为您的控制器创建一个模型,即使您没有使用它。供您参考,这里有一个模态示例:

<?php // You may not need this modal, but cakephp requires it to be there.
class Services extends AppModel {
   public $name = 'Services';
   public $useTable = false;
}
?>

问:我应该收到哪些网址? 答:您设置的响应网址必须包含?wsdl 所以..例如:你有一个名为SOAPController的控制器和名为process的方法 在CakePHP中,您的网址如下所示:mydomain.com/SOAP/process 因此,WSDL位于mydomain.com/SOAP/process?wsdl。确保您的回调网址设置为此(包括wsdl)。

问:如何使用CakePHP调试SOAP请求/响应?
A: CakePHP具有日志记录功能,在调试SOAP时证明非常有用。在您的控制器(或模态)中,您可以使用:

$this->log('your message or variable', 'name_of_file_to_save_to);

您可以通过SOAP请求或响应来使用此功能,以查看正在命中/调用的部分以及调试变量(例如:$HTTP_RAW_POST_DATA)。

问:当我访问SOAP页面时,我的WSDL位置显示为`domain.com / app / webroot`。

答:我认为这是导致所有问题的问题,查看源代码Nusoap使用PHP_SELF获取当前脚本(在cakePHP中为{ {1}}),不要担心这一点,您可以通过使用app/webroot/index.php附加网址来访问wsdl,这会显示您生成的?wsdl文件,但您不会需要担心解决这个问题。它不会干扰您的WSDL请求,只是为了您的方便。

问:我的SOAP地址位置显示为'domain.com / app / webroot / index.php`

答:这是我通过在SOAP中加入$endpoint来修复的问题。

configureWSDL()