关于soap的一些小知识

1. soap编码问题

soap采用utf-8编码作为传输的字符集编码,至少php的soap的实现是写死成utf-8字符编码的,如果server端或client端使用的是非utf-8的字符编码时,可能存在转码问题,导致转码错误; 一个不太正规的做法是: 在server端和client端都对字符做url编码(或别的编码),是的传输的字符都转换成了单字节的ascii字符,这样就不会出现转码问题了。 但是,如果访问量很大,会存在流量和效率方面的问题,如果访问量很小,还是可以使用的

2. 让多个类提供服务的方法,如:

3. 错误处理

server端的错误如何告知client呢?通过 $server->fault() 来实现,如:

client 端实现:

1) 根据 ext/soap/soap.c 中关于$server->handle() 的实现来看,如果使用的是ZEND_ENGINE_2 ,则在执行的函数中 throw new SoapFault(…) 也会有和上述相同的效果的,如:

可以通过:

# php -i | grep -i engine

来确认使用的Zend Engine 的版本

2) 虽然soapclient可以识别一些http的状态码,但是soapserver:fault 产生错误时,http状态码统一为500,注意,当user-agent 为 Shockwave Flash 时,依然使用200 的状态码返回,大概是对于flash实现soap时特殊情况的兼容吧。参看php: ext/soap/soap.c 中 函数: soap_server_fault_ex(…) 的实现,php的soapclient可以通过如下方式设置user-agent:

 

4. 对象的持久化

对象的持久化就是在session中保存类或对象的一些数据信息;要知道连接句柄等和进程相关的资源信息是无法有效地保存的

 

5. 数据的传递

如果你执行的server端的函数为 echo “hello world”; 那么client将得不到该信息,参看php的soap扩展中soap.c 有相关代码如下:

 

6. 什么叫classmap?

在使用SoapClient时,允许通过如下方式设置classmap,如:

因为在server端,如果return一个server端的对象,则被转换为一个Struct的类型,内部含有该对象的一些数据信息,当然,对象的方法信息都是没有的; 该类在client端可能就是不存在的,这时候就可以map到client端定义的一个类,而且可以通过该类的方法来访问对象内部的一些信息。

但是,有一点需要注意,client端不要定义和server端的类相同的属性信息,如果定义了,则该属性将成为一个数组,包含client端和server端的信息。不知道为什么这么设计

 

7. 什么叫typemap?

 

 

8. 关于soap的测试,单个脚本实现的SoapServer和SoapClient:

脚本来自: http://us1.php.net/manual/en/soapclient.dorequest.php

9. 关于数据类型

函数的参数和返回值是涉及到数据类型的,如果仅仅使用string、int、array,则基本是没有问题的,如果使用到了对象,就需要注意了,可能需要用到classmap、typemap了,还有SoapParam、SoapVar; 稍后再研究

10. 关于location和uri

在new SoapClient和new SoapServer时都需要uri,而且这两个uri也是可以不一样的,其实程序根本不会去访问这个uri,这个uri只是xml中的一个名字空间的名字; 而new SoapClient时的那个location却是真正要访问的soapserver的url地址;但是,需要注意的是: uri 最好不要带参数,带一个参数还好,如果要带多个,必然出现 ‘&’,而uri是要写到请求的xml中的,xml中出现 ‘&’,会被解释为实体,然而却不是一个合法的实体,所以就会出现 400 错误,然后就是调试半天,百思不得姐。

 

 

 

 

 

 

留下评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据