关闭

使用php程序编写webservice程序

标签: phpwebservicesoapsoapdiscovery.phpsoap协议
542人阅读 评论(0) 收藏 举报
分类:

php生成webservice程序的步骤:

1.首先生成一个test.php类文件,类名是大写,其中的public方法后续都会作为接口方法

2.需要使用开源的soapdiscovery.php类针对test.php类来创建一个wsdl文件

3.在服务器上开启服务

4.客户端需要知道服务器上的wsdl文件访问路径,然后通过soapclient类来请求,构造参数请求webservice中的类方法


首先是一个test.php类,具体代码:

<?php
class Test {
    /**
     *
     * @param string $name
     * @param int $age
     * @return string
     */
    public function add($name,$age)
    {
        $result = array('REV'=>false);
        $result['REV'] = true;
        $result['DATA'] = 1;
        $result['name'] = $name;
        $result['age'] = $age;
        return json_encode($result);
    }
    
    public function say()
    {
        return 'I am speaking!<br/>';
    }
    /**
     * delete the object
     * @param int $id
     * @return boolean
     */
    public function del($id)
    {
        $result = false;
        return $result;
    }
    /**
     *
     * @param int $type
     * @return string
     */
    public function getlist($type)
    {
        $result = array(
            array('name'=>'张三','age'=>18),
            array('name'=>'李四','age'=>20),
            array('name'=>'jms','age'=>10),
            array('name'=>'jk陈','age'=>8),
        );
        return json_encode($result);
        
    }
    
    public function receiveCompanies($xmlContent)
    {
        $arr_receive = $this->simplest_xml_to_array($xmlContent);
        
        return
        '<?xml version="1.0" encoding="UTF-8"?>\n<response>\n<status>1</status>\n<version>'.count($arr_receive).'</version>\n</response>';
    }
    
    /** * 最简单的XML转数组 * @param string $xmlstring XML字符串 * @return array XML数组*/
    
    private function simplest_xml_to_array($xmlstring)
    {
        $str_source = array('\\x00','\\x01','\\x02','\\x03','\\x04','\\x05','\\x06','\\x07','\\x08',
        '\\x0b','\\x0c','\\x0e','\\x0f','\\x10','\\x11','\\x12','\\x13','\\x14','\\x15','\\x16','\\x17','\\x18','\\x19','\\x1a','\\x1b','\\x1c','\\x1d','\\x1e','\\x1f');
        $xmlstring = str_replace($str_source,'',$xmlstring);
        $str_source = array('&',"'");//,'<','>','"',"'"
        $str_target = array('&',''');//,'<','>','"','''
        $xmlstring = str_replace($str_source,$str_target,$xmlstring);
        
        return json_decode(json_encode((array)simplexml_load_string($xmlstring)),true);
    }
    
}

?>



soapdiscovery.php类代码如下:

<?php

/**
 * Copyright (c) 2005, Braulio Jos?Solano Rojas
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are
 * permitted provided that the following conditions are met:
 *
 *     Redistributions of source code must retain the above copyright notice, this list of
 *     conditions and the following disclaimer.
 *     Redistributions in binary form must reproduce the above copyright notice, this list of
 *     conditions and the following disclaimer in the documentation and/or other materials
 *     provided with the distribution.
 *     Neither the name of the Solsoft de Costa Rica S.A. nor the names of its contributors may
 *     be used to endorse or promote products derived from this software without specific
 *     prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * @version $Id: SoapDiscovery.class.php 66 2013-04-10 07:12:21Z ideaa $
 * @copyright 2005
 */

/**
 * SoapDiscovery Class that provides Web Service Definition Language (WSDL).
 *
 * @package SoapDiscovery
 * @author Braulio Jos?Solano Rojas
 * @copyright Copyright (c) 2005 Braulio Jos?Solano Rojas
 * @version $Id: SoapDiscovery.class.php 66 2013-04-10 07:12:21Z ideaa $
 * @access public
 * */
class SoapDiscovery {

    private $class_name = '';
    private $service_name = '';

    /**
     * SoapDiscovery::__construct() SoapDiscovery class Constructor.
     *
     * @param string $class_name
     * @param string $service_name
     * */
    public function __construct($class_name = '', $service_name = '') {
        $this->class_name = $class_name;
        $this->service_name = $service_name;
    }

    /**
     * SoapDiscovery::getWSDL() Returns the WSDL of a class if the class is instantiable.
     *
     * @return string
     * */
    public function getWSDL() {
        if (empty($this->service_name)) {
            throw new Exception('No service name.');
        }
        $headerWSDL = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
        $headerWSDL.= "<definitions name=\"$this->service_name\" targetNamespace=\"urn:$this->service_name\" xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:tns=\"urn:$this->service_name\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\n";
        $headerWSDL.= "<types xmlns=\"http://schemas.xmlsoap.org/wsdl/\" />\n";

        if (empty($this->class_name)) {
            throw new Exception('No class name.');
        }

        $class = new ReflectionClass($this->class_name);

        if (!$class->isInstantiable()) {
            throw new Exception('Class is not instantiable.');
        }

        $methods = $class->getMethods();

        $portTypeWSDL = '<portType name="' . $this->service_name . 'Port">';
        $bindingWSDL = '<binding name="' . $this->service_name . 'Binding" type="tns:' . $this->service_name . "Port\">\n<soap:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\" />\n";
        $serviceWSDL = '<service name="' . $this->service_name . "\">\n<documentation />\n<port name=\"" . $this->service_name . 'Port" binding="tns:' . $this->service_name . "Binding\"><soap:address location=\"http://" . $_SERVER['HTTP_HOST'] . ($_SERVER['SERVER_PORT']=='80'?'':(':'.$_SERVER['SERVER_PORT'])). $_SERVER['PHP_SELF'].'?service='. strtolower($this->class_name) . "\" />\n</port>\n</service>\n";
        $messageWSDL = '';
        foreach ($methods as $method) {
            if ($method->isPublic() && !$method->isConstructor()) {
                $portTypeWSDL.= '<operation name="' . $method->getName() . "\">\n" . '<input message="tns:' . $method->getName() . "Request\" />\n<output message=\"tns:" . $method->getName() . "Response\" />\n</operation>\n";
                $bindingWSDL.= '<operation name="' . $method->getName() . "\">\n" . '<soap:operation soapAction="urn:' . $this->service_name . '#' . $this->class_name . '#' . $method->getName() . "\" />\n<input><soap:body use=\"encoded\" namespace=\"urn:$this->service_name\" encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" />\n</input>\n<output>\n<soap:body use=\"encoded\" namespace=\"urn:$this->service_name\" encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" />\n</output>\n</operation>\n";
                $messageWSDL.= '<message name="' . $method->getName() . "Request\">\n";
                $parameters = $method->getParameters();
                foreach ($parameters as $parameter) {
                    $messageWSDL.= '<part name="' . $parameter->getName() . "\" type=\"xsd:string\" />\n";
                }
                $messageWSDL.= "</message>\n";
                $messageWSDL.= '<message name="' . $method->getName() . "Response\">\n";
                $messageWSDL.= '<part name="' . $method->getName() . "\" type=\"xsd:string\" />\n";
                $messageWSDL.= "</message>\n";
            }
        }
        $portTypeWSDL.= "</portType>\n";
        $bindingWSDL.= "</binding>\n";
        //return sprintf('%s%s%s%s%s%s', $headerWSDL, $portTypeWSDL, $bindingWSDL, $serviceWSDL, $messageWSDL, '</definitions>');
        //生成wsdl文件,将上面的return注释
        
        $fso = fopen(strtolower($this->class_name) . ".wsdl", "w");
        fwrite($fso, sprintf('%s%s%s%s%s%s', $headerWSDL, $portTypeWSDL, $bindingWSDL, $serviceWSDL, $messageWSDL, '</definitions>'));
        fclose($fso);
    }
    
    

    /**
     * SoapDiscovery::getDiscovery() Returns discovery of WSDL.
     *
     * @return string
     * */
    public function getDiscovery() {
        return "<?xml version=\"1.0\" ?>\n<disco:discovery xmlns:disco=\"http://schemas.xmlsoap.org/disco/\" xmlns:scl=\"http://schemas.xmlsoap.org/disco/scl/\">\n<scl:contractRef ref=\"http://" . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['PHP_SELF'] . "?wsdl\" />\n</disco:discovery>";
    }

}

?>



server.php类代码如下:

<?php
    ini_set("soap.wsdl_cache_enabled",0);
    if(empty($_GET['service'])) {
        echo "参数非法,请传入service";
        return;
    }
    /**
     **根据类名生成一个wsdl文件
     **/
    function generateWsdl($serviceClass,$isRemake=FALSE)
    {
        include("soapdiscovery.php");
        if ( ! file_exists(strtolower($serviceClass).'.wsdl') || $isRemake)
        {
            $discovery = new SoapDiscovery($serviceClass,$serviceClass.'service');
            $discovery->getWSDL();
        }
    }
   $serviceName = strtolower(htmlentities(trim($_GET['service'])));
   if(isset($_GET['action'])) {
       $action = strtolower(htmlentities(trim($_GET['action'])));
   }
   
   
   include($serviceName.'.php');//与当前文件同名的目录下有一个提供webservice接口功能的类文件
   if(!file_exists($serviceName.'.php')) {
       echo $serviceName.'.php不存在';
       return;
   }        
   $isRemake = TRUE;//类文件方法修改时要重新生成一遍wsdl文件
   generateWsdl(ucfirst($serviceName),$isRemake);
   $path = $serviceName.'.wsdl';
   // if(is_writable($path)) {//要确保文件是可以写入的
       // echo "$path is writable<br/>";
   // }else {
       // echo "$path is not writable<br/>";
   // }
   
   if (isset($action) && $action == 'wsdl') {//这些语句可以查看当前webservice提供的接口方法描述
        header('Content-type:text/xml');
        $document = file_get_contents($path);
        echo $document;
        exit;
    }
    
   libxml_disable_entity_loader(false);//这一句可以提高webservice服务的可靠性
   $server = new SoapServer($path);
   $class = ucfirst($serviceName);
   $obj = new $class();
   $server->setObject($obj);
   $server->setClass($class);
   $server->handle();
?>



以上三个类是放在服务器上的,假定server.php是放在192.168.100.198服务器上,那么具体的查看该服务器上的wsdl文件的url地址为:http://192.168.100.198/server.php?service=test&action=wsdl,如果只想重新生成wsdl文件则访问http://192.168.100.198/server.php?service=test 即可


最后在客户端机器上放入client.php程序,具体代码如下:

<?php
    ini_set("soap.wsdl_cache_enabled",0);
    
    libxml_disable_entity_loader(false);//这一句可以提高webservice服务的可靠性
    $url = "http://192.168.100.198/test.wsdl";
    $client = new SoapClient($url);
    echo "arrive here111,<hr/>";
    $params = array('name'=>'wangxiaoruo','age'=>'33');
    $res = $client->__soapCall('add',$params);
    var_dump($res);
    echo "<hr/>";
    
    $params = array();
    $res = $client->__soapCall('say',$params);
    var_dump($res);
    echo "<hr/>";
    
    $params = array('type'=>1);
    $res = $client->__soapCall('getlist',$params);
    var_dump($res);
    return;

?>


可以看到访问后的结果为:

arrive here111,


string(53) "{"REV":true,"DATA":1,"name":"wangxiaoruo","age":"33"}"
string(19) "I am speaking!
"
string(119) "[{"name":"\u5f20\u4e09","age":18},{"name":"\u674e\u56db","age":20},{"name":"jms","age":10},{"name":"jk\u9648","age":8}]"

0
0

猜你在找
【直播】计算机视觉原理及实战—屈教授
【套餐】深度学习入门视频课程—唐宇迪
【套餐】Hadoop生态系统零基础入门--侯勇蛟
【套餐】嵌入式Linux C编程基础--朱有鹏
【套餐】2017软考系统集成项目——任铄
【套餐】Android 5.x顶级视频课程——李宁
【直播】广义线性模型及其应用——李科
【直播】从0到1 区块链的概念到实践
【直播】机器学习之凸优化——马博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:62964次
    • 积分:1417
    • 等级:
    • 排名:千里之外
    • 原创:82篇
    • 转载:5篇
    • 译文:1篇
    • 评论:2条
    最新评论