首页后端开发PHPPHP调用webservice失败如何解决?浅谈webservice的使用

PHP调用webservice失败如何解决?浅谈webservice的使用

时间2024-03-25 10:08:03发布访客分类PHP浏览1218
导读:这篇文章给大家分享的是PHP调用webservice的相关内容。下文简单介绍了浅谈webservice的使用及PHP调用webservice失败的解决方法,文中的介绍很详细,有需要的朋友可以参考,接下来就跟随小编一起了解看看吧。 本文操作...

这篇文章给大家分享的是PHP调用webservice的相关内容。下文简单介绍了浅谈webservice的使用及PHP调用webservice失败的解决方法,文中的介绍很详细,有需要的朋友可以参考,接下来就跟随小编一起了解看看吧。

本文操作环境:windows7系统、PHP7.1版、DELL G3电脑

php调用webservice失败怎么办?

php编写webservice案例、webservice调用失败

作为开发者来讲,要想写webservice接口或者调用别人的webservice接口,首先需要了解什么是webservice。

简单说, WebService就是一些站点开放一些服务出来, 也可以是你自己开发的Service, 也就是一些方法, 通过URL,指定某一个方法名,发出请求,站点里的这个服务(方法),接到你的请求,根据传过来的参数,做一些处理,然后把处理后的结果以XML形式返回来给你,你的程序就解析这些XML数据,然后显示出来或做其它操作。

在开始编写之前需要对php环境做一些配置:

打开php安装目录下的php.ini文件

找到 ; extension=php_soap.dll ,去掉前面的分号,保存,然后重启apache。

配置好环境就可以编写php了,先创建creatService.php文件,复制下面代码:

?php
class ServiceTest{

	public function firstHandle($name){
    
		return "你的名字是:".$name;

    }

    
    public function dbInsert($text){
    
        $db=new mysqli("localhost","root","","test");

		if(mysqli_connect_error()){
    
		    return '数据库连接失败。';
    
		    exit;

		}
    
        $result=$db->
    query("insert into test_soap (text) values('".$text."')");

        
		if($result){
    
			return $result;

		}
else{
    
			return "插入失败";

		}

    }

}


if(file_exists('ServiceTest.wsdl')){
     //只有当ServiceTest.wsdl文件存在时才进行注册类
    $objSoapServer = new SoapServer("ServiceTest.wsdl");
    
    //注册ServiceTest类的所有方法 
    $objSoapServer->
    setClass("ServiceTest");
    
    //处理请求 
    $objSoapServer->
    handle();

}
    

require_once "SoapDiscovery.class.php";
    
$dis=new SoapDiscovery("ServiceTest","WebService");
     //第一个参数为类名也是生成wsdl的文件名
$dis->
    getWSDL();
    



?>
    

第一次运行creatService.php文件时要创建wsdl文件,创建WSDL文件需要用到一个辅助类SoapDiscovery.class.php。在文章末尾可以得到。

创建完成之后便是测试调用,创建client.php文件,复制以下代码:

ini_set('soap.wsdl_cache_enabled','0');
    //关闭缓存

$x = new SoapClient("http://localhost/webServiceTest/ServiceTest.wsdl");
 //这里的链接换成你自己的访问链接

try {
    
    echo $x->
    firstHandle('qweqrwergwe');
    

    echo ('pre>
    ');
    
    var_dump ( $x->
    __getFunctions () );
    //获取服务器上提供的方法
    echo ('/pre>
    ');
    

    echo ('pre>
    ');
    
    var_dump ( $x->
    __getTypes () );
    //获取服务器上数据类型
    echo ('/pre>
    ');

}
catch (SoapFault $f){

    echo "Error Message: {
    $f->
getMessage()}
    ";

}
    

注意! ini_set('soap.wsdl_cache_enabled','0'); //关闭WSDL缓存

如果不关闭缓存,会造成测试无效,缓存数据会扰乱测试准确性。

注意!如果是在thinkphp5中使用SoapClient函数应当如下使用:

$client = new \SoapClient ('http://www.baidu.com/ids/terminal/terminalWs.wsdl');

重要点:

使用https访问webservice的话会出现访问异常,博主就遇到这个问题的,本地创建和调用webservice都通过了,但是一放到线上就无法调用了,然后各种google、baidu。最后才发现线上的环境是http强制转了https。

我的解决办法是取消了http强制转换https的功能:

找到httpd-vhost.conf,注释掉一下代码:

##    RewriteEngine on
##    RewriteCond   %{
HTTPS}
 !=on
##    RewriteRule   ^(.*)  https://%{
SERVER_NAME}
$1 [L,R]

注释掉上面的代码后我发现我的网站不是https了,呜呜呜~,真的是拆了东墙补西墙啊,赶紧想办法,因为网站必须使用https才行,还好我使用的是thinkphp框架,找到了一个方法,在入口文件index.php最下面加入下面的代码就行了:

if (empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === "off") {
    
    $location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    
    header('HTTP/1.1 301 Moved Permanently');
    
    header('Location: ' . $location);
    
    exit;

}
    

SoapDiscovery.class.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$
 * @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$
 * @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\" ?>
    \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."\">
    \ndocumentation />
    \n
port name=\"".$this->
    service_name.'Port" binding="tns:'.$this->
    service_name."Binding\">
    
soap:address location=\"http://".$_SERVER['SERVER_NAME'].':'.$_SERVER['SERVER_PORT'].$_SERVER['PHP_SELF']."\" />
    \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>
    \noutput>
    \nsoap: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>
    ');
    
	    $fso = fopen($this->
    class_name . ".wsdl" , "w");
     
        fwrite($fso, sprintf('%s%s%s%s%s%s', $headerWSDL, $portTypeWSDL, $bindingWSDL, $serviceWSDL, $messageWSDL, '/definitions>
    '));
     
        exit;
 
	}

	
	/**
	 * SoapDiscovery::getDiscovery() Returns discovery of WSDL.
	 * 
	 * @return string
	 **/
	public function getDiscovery() {
    
		return "?xml version=\"1.0\" ?>
    \ndisco: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>
    ";

	}

}
    
 
?>
    

以上就是PHP调用webservice失败的解决方法介绍啦,需要的朋友可以参考上述步骤操作,希望对大家有帮助,想要了解更多PHP调用webservice,可以继续浏览网络其他相关的文章。

文本转载自PHP中文网

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: PHP调用webservice失败如何解决?浅谈webservice的使用
本文地址: https://pptw.com/jishu/652709.html
HTML5自定义属性什么用,语法怎样写 PHP中怎么更改数据库的数据,方法是啥?

游客 回复需填写必要信息