手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表2024年09月的文章

关于SOAP的几篇文章

PHP操作soap我总觉得是一件非常痛苦的事情,但没有办法,现在很多功能都是基于WebService的,比如那个amazon的,但其实很多公司都也还是提供了restful之类的接口,使得PHP与其他系统的数据交换比较方便。但让人痛苦的,有时候,你PHP不得不充当soapServer,这时候,怎么做呢?zendstudio可以根据你的函数和类,帮你生成wsdl,但大多数情况下,你没有直接生成的手段,怎么办?官方的soapServer功能也太少了一点。你是否还准备用nuSoap来充当server呢?

搜集了一些资料,用来方便的协助你生成soap接口。如果只是自己的内部调用,可以尝试用phprpc或者它的升级版hprose进行尝试。

1、利用NuSOAP发布wsdl。这是PHP5之前的做法了,因为在PHP5之后,直接有soap库支持,如何发布wsdl,请看:http://hi.baidu.com/arlon/blog/item/d8267d1e6ca4adf01ad576cc.html,然而这个网址打开是白屏的,内容可以稍看这里:

PHP代码
  1. 2.4.1 创建支持 WSDL 的 WEB 服务  
  2. 为了实现 WEB 服务程序对 WSDL 的支持,需要使用 soap_server 的 configureWSDL 方法,并且在调用 soap_server 的 register 方法注册 WEB 服务程序时,需要提供更详细的参数。看下面的代码,代码的文件名是 “/nusoap/nusoap_server3.php”。  
  3.   
  4. <?php  
  5. require_once("lib/nusoap.php");  
  6.   
  7. function concatenate($str1,$str2) {  
  8.       if (is_string($str1) && is_string($str2))  
  9.           return $str1 . $str2;  
  10.       else  
  11.           return new soap_fault(' 客户端 ','','concatenate 函数的参数应该是两个字符串 ');  
  12. }  
  13.   
  14. $soap = new soap_server;  
  15. $soap->configureWSDL('concatenate'); // 初始化对 WSDL 的支持  
  16.   
  17. // 注册服务  
  18. $soap->register('concatenate',  
  19. array("str1"=>"xsd:string","str2"=>"xsd:string"), // 输入参数的定义  
  20. array("return"=>"xsd:string"// 返回参数的定义  
  21. );  
  22.   
  23. $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';  
  24. $soap->service($HTTP_RAW_POST_DATA);  
  25. ?>  
  26. 现在打开浏览器,访问刚才建立的文件,http://127.0.0.1/nusoap/nusoap_server3.php,结果如下:   
  27.   
  28. concatenate  
  29. View the WSDL for the service. Click on an operation name to view it's details.  
  30.   
  31. concatenate   
  32. 点击函数名称concatenate,可以看到对函数的描述。点击"WSDL",或者访问WEB服务文件,并在后面加上查询字符串"?wsdl"(http://127.0.0.1/nusoap/nusoap_server3.php?wsdl),可以得到WEB服务的WSDL内容。  
  33.   
  34. 2.4.2 通过 WSDL 调用 WEB 服务  
  35. 通过 WSDL 调用 WEB 服务,与不通过 WSDL 调用 WEB 服务,程序的结构大体相同。区别在于,通过 WSDL 调用 WEB 服务,初始化 soapclient 类时,传入两个参数到 soapclient 的构造函数,第一个参数是 WSDL 文件的地址,第二个参数指定是否使用 WSDL ,指定为 true 即可。看下面的代码,代码的文件名是 “ /nusoap/nusoap_client3.php ”  
  36.   
  37. <?php  
  38. require_once("lib/nusoap.php");  
  39.   
  40. $client = new soapclient('http://127.0.0.1/nusoap/nusoap_server3.php?wsdl',true);  
  41. $parameters=array(' 字符串 1',' 字符串 2');  
  42.   
  43. $str=$client->call('concatenate',$parameters);  
  44. if (!$err=$client->getError()) {  
  45.       echo " 程序返回 :",$str;  
  46. else {  
  47.       echo " 错误 :",$err;  
  48. }  
  49. ?>  
  50. 2.4.3 代理的使用  
  51. NuSOAP 提供代理的方法调用远程 WEB 服务。这种方法,在客户端程序里面创建一个远程服务的代理对象,通过代理直接调用远程的 WEB 服务,而不需要通过 soalclient 类的 call 方法。看下面的代码。  
  52.   
  53. <?php  
  54. require_once("lib/nusoap.php");  
  55.   
  56. $client = new soapclient('http://127.0.0.1/nusoap/nusoap_server3.php?wsdl',true);  
  57. $proxy=$client -> getProxy(); // 创建代理对象 (soap_proxy 类 )  
  58.   
  59. $str=$proxy->concatenate(" 参数 1"," 参数 2"); // 直接调用 WEB 服务  
  60. if (!$err=$proxy->getError()) {   
  61.       echo " 程序返回 :",$str;  
  62. else {  
  63.       echo " 错误 :",$err;  
  64. }  
  65. ?>  

 

2、利用PHP5自带的soapServer,在手册上,关于如何创建,写了很多例子,就象:

PHP代码
  1. <?php  
  2. $server = new SoapServer("some.wsdl");  
  3. $server = new SoapServer("some.wsdl"array('soap_version' => SOAP_1_2));  
  4. $server = new SoapServer("some.wsdl"array('actor' => "http://example.org/ts-tests/C"));  
  5. $server = new SoapServer("some.wsdl"array('encoding'=>'ISO-8859-1'));  
  6. $server = new SoapServer(null, array('uri' => "http://test-uri/"));  
  7.   
  8. class MyBook {  
  9.     public $title;  
  10.     public $author;  
  11. }  
  12.   
  13. $server = new SoapServer("books.wsdl"array('classmap' => array('book' => "MyBook")));  
  14. ?>   

 

反正,我是觉得很痛苦,不过所幸现在的IDE都支持了直接发布wsdl文件,netbeans可以,zendstudio也可以。所以,也就方便了开发

3、利用开源组件,比如:webservice helper,http://www.jool.nl/new/1,webservice_helper.html,虽然它也是其于soapServer,但是集成的一些代码可以让你少走很多弯路。

比如,它默认就自带了一个contactManager的发布,具体的一些配置,可以看config.php,当然你也可以参考它的一些类,也充实你自己的类库(本来官网有教程的,可能是因为时间太久远了,该教程已经跳到ipublisher的教程上去了)

4、利用框架实现webService。在这里,估计又有很多分支了,比如zend framework,比如xxx和xxxx等,我由于最近在用yii,所以就看了yii的一个小小的实现

介绍页在这里:http://www.yiiframework.com/doc/guide/1.0/zh_cn/topics.webservice

看它的实现是非常简单,在Controller里增加一个转换wsdl的Action,然后,在要提供的方法上面用phpdoc来进行注释。定义传入参数的数据类型等

  • str/string: 对应 xsd:string;
  • int/integer: 对应 xsd:int;
  • float/double: 对应 xsd:float;
  • bool/boolean: 对应 xsd:boolean;
  • date: 对应 xsd:date;
  • time: 对应 xsd:time;
  • datetime: 对应 xsd:dateTime;
  • array: 对应 xsd:string;
  • object: 对应 xsd:struct;
  • mixed: 对应 xsd:anyType.

不过我也确实没有过多的细看,没仔细看它对于AUTH验证支持怎么样(第三点里介绍的工具是有验证的,而且就设在config.php里,非常方便)

好了,我就针对现在的soap server的建立,介绍了四种方法,事实上,我到现在为止是一种都没有用过,nusoap也就用过客户端,那也是几年前的事情了,soapClient也是,在构建soapHeader的时候也走过很多弯路。第三步介绍的工具,我也只是下载了看看源码,第四步我是看了看手册。只是先集中一下,以后总会用到而已。
虽然说,PHPRPC和hprose 在andot他们介绍来说,开发速度和处理上,都有较为明显的提高,但如果想做一个公用的web service,那还是用大家都能接受的方法吧。
如果是自己的项目,那可能就会用phprpc或者hprose来了。hprose测试版用过,感觉还是不错的。phprpc,我也做了一个sae平台的移植版,目前也能够正常的使用。。在这里也有个简单的测试:http://nsblog.sinaapp.com/。有兴趣的朋友也可以去看看的。

Tags: soap, webservice, phprpc, hprose, restful

关于oauth的几篇文章

本文只是一个收集的链接,关于oauth,可以去看一下wiki百科,对于PHP的oauth支持,可以看一下手册
国内很早就有不少网站支持oauth,只是更多的网站都没有做出此类开放的功能。不过,疯狂的时候来的总是那么突然(这让我想起在单位的年夜饭上,刚吃了一小时,突然副总说了一句,快乐的时光总是短暂的)。国内对Oauth的支持也就突然间的多了起来,可能,最让人记的清楚的还是新浪。但当时关于oauth的文章还不是特别多,只是在QQ开放oauth后,突然间文章就多了很多,理由是,QQ所支持的oauth协议居然是非标的。。。。

好吧,让我们看看其他人是怎么说的:

1、使用QOAuth来进行新浪/腾讯微博验证(一)

2、老王的:基于PECL OAuth打造微博应用

3、android下的:android开发我的新浪微博客户端-OAuth篇(2.1)

4、腾讯微博开放平台的PECL的OAuth封装

5、腾讯微博开放平台练手:微博擂台

6、使用 PECL 的 OAuth 库访问 QQ 微博 API

其中4、5、6都是mikespook写的,他说,QQ 微博的API里有点重要的事情,并列出来了。看例子:

PHP代码
  1. <?php  
  2. include('define.php');  
  3. try {  
  4.     $oauth = new OAuth(OAUTH_KEY, OAUTH_SECRET, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI);  
  5.     $oauth->enableDebug();  
  6.     // 很重要!!!在 OAuth 标准里是没有规定 nonce 的长度的,但是 QQ 对 nonce 的长度做了要求——32 字节长。如果不设置一下,会返回 400 错误。我为此纠结了一天。  
  7.     $oauth->setNonce(md5(rand()));  
  8.     // CALLBACK 一定要设置,OAuth 扩展的文档上是没设置的,但是 QQ 这里不设会报错  
  9.     $requestTokenInfo = $oauth->getRequestToken(REQUEST_TOKEN, CALLBACK);  
  10.     $_SESSION['oauth_token_secret'] = $requestTokenInfo['oauth_token_secret'];  
  11.     // header("Location: ……") 亦可  
  12.     echo "<p><a href='" . AUTHORIZE . "?oauth_token=" . $requestTokenInfo['oauth_token'] . "'>authorize</a></p>";  
  13. } catch (OAuthException $e) {  
  14.     var_dump($e);  
  15. }  
  16.   
  17. callback.php  
  18.   
  19. <?php  
  20. include('define.php');  
  21. try {  
  22.     $oauth = new OAuth(OAUTH_KEY, OAUTH_SECRET, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI);  
  23.     $oauth->enableDebug();  
  24.     // 很重要!!!如果不设置一下,会返回 401 错误。  
  25.     $oauth->setNonce(md5(rand()));  
  26.     $oauth->setToken($_GET['oauth_token'], $_SESSION['oauth_token_secret']);  
  27.     $accessTokenInfo = $oauth->getAccessToken(ACCESS_TOKEN, null, $_GET['oauth_verifier']);  
  28.     $_SESSION['access_token'] = $accessTokenInfo['oauth_token'];  
  29.     $_SESSION['access_secret'] = $accessTokenInfo['oauth_token_secret'];  
  30.     header('Location: room.php');  
  31. } catch (OAuthException $e) {  
  32.     var_dump($e);  
  33. }  
7、这是针对新浪微博的OAuth协议分析一

 

8、对新浪微博的OAUTH开发,居然还有一个总结:新浪微博OAuth认证总结

9、又是老王发的牢骚:OAuth那些事儿

好吧,就先列出这么多,真要查出oauth之类的东西,google随便一下就有很多,我贴出来的地址,都是我订阅的一些RSS的地址,也算是做一个集中罢了。

 

Tags: php, qq, sina, oauth, pecl

转:jQuery1.5的改进细节

jQuery 1.5beta出来了?看到这篇博客的时候,我很惊讶,1.4开始,jQuery的更新速度就越来越快了。现在,居然1.5beta都同来了。文中说了,ajax完全重写,但没介绍,不过对于使用者来说,这些都无需关心,或者应该开心才是,因为它带来了更多的兼容性,说不定速度也更快了。(猜测而已,最近实在没时间 看这些代码)

下面是原文:

jQuery 1.5 beta1出来了,从学习跟进上来说,这一次已经比较晚了(我竟然不知道1.5什么时候出的alpha,就这么beta了)。

这个1.5版本最大的更新是AJAX的完全重写,提供了更强的可扩展性。但是受制于精力和篇幅,对新的AJAX的分析还是放到下回,本篇先简单介绍一下细节方面的改进。

jQuery._Deferred和jQuery.Deferred

首先不得不说这两个新生事物,因为他们是作为基础设施存在,不把这两个东西讲明白了,有些问题根本没办法解释。

首先,jQuery.Deferred是jQuery._Deferred的增强版,因此对于这个问题,从jQuery._Deferred入手,就能说明一大半的问题。

什么是Deferred?从字面上看,我的第一反应是“延迟加载”,首字母大写的应该是“类型”的定义,所以这大概是一个“透明提供延迟加载功能”的类型吧。然而实际上,虽然确实带有那么一点点“延迟”的意思,这个东西却不是用来实现延迟加载的。

简单来说,jQuery._Deferred是一个函数队列,他的作用有以下几点:

  • 保存若干个函数。
  • 在特定的时刻把保存着的函数全部执行掉。
  • 执行过后,新进来的函数会立刻执行。

感觉是不是和啥东西很像?对,jQuery的ready函数就是这样的逻辑,实际中jQuery 1.5中的ready函数也确实被嫁接到这上面去了。

jQuery._Deferred提供下面的接口:

  • done:function(fn1, fn2, ...)的形式,用于把函数添加到队列中。
  • fire:function(context, args)的形式,使用context指定this对象,args指定参数,调用队列中所有函数。fire被调用后,_Deferred会进入 isResolved状态,未来对done的调用不会再保存函数,而是直接调用函数。
  • resolve:相当于调用fire(this, arguments),一个简化的方法。
  • isResolved:用来判断_Deferred是否在isResolved状态,具体参考前面的fire函数的解释。
  • cancel:取消掉整个队列,这样不管未来是不是fire,队列中的函数都不会再被调用。

说明白了jQuery._Deferred,再来看看jQuery.Deferred。这个东西其实就是2个_Deferred组成的,第一个称为 deferred,用于保管“正常”状态下的函数;第二个称为failDeferred,用于保管“出错”状态下的函数。同时 jQuery.Deferred提供了一些新的接口:

  • then:function(done, fail)的形式,把done添加进deferred,把fail添加进failedDeferred。
  • fail:相当于failDeferred的done函数。
  • fireReject:相当于failDeferred的fire函数。
  • reject:相当于failDeferred的resolve函数。
  • isRejected:相当于failDeferred的isResolved函数。

同时jQuery.Deferred取消了cancel函数。

那么这个是啥用的呢?有“正常”和“出错”2个状态,同时又是异步的,很容易就能想到……对,给AJAX用的,在下一篇分析中再详细说明。

jQuery.ready的变化

因为有了jQuery._Deferred这个东西,jQuery.ready函数变成依赖于函数队列,具体的变化有:

原来的readyList变量已经不再是一个数组,而变成了jQuery._Deferred对象。

原本在DOMContentLoaded时,调用readList中所有函数的逻辑,现在也使用了jQuery._Deferred中,原来的代码:

while ( (fn = ready[ i++ ]) ) {
fn.call( document, jQuery );
}

变成了:

readyList.fire( document , [ jQuery ] );

jQuery.parseXML函数

新增了静态函数jQuery.parseXML,用于提供浏览器兼容的从字符串转为XML文档的功能。

该函数的逻辑网上有很多,jQuery也没有特别的地方,大致分为以下2种:

  • 对于标准浏览器,使用DOMParser对象:

    var parser = new DOMParser();
    var xml = parser.parseFromString(text, 'text/html');
  • 对于IE,使用Microsoft.XMLDOM对象:

    var parser = new ActiveXObject('Microsoft.XMLDOM');
    parser.async = 'false';
    parser.loadXML(text);
    var xml = parser.documentElement;

data部分

添加了jQuery.hasData函数,用于判断一个元素是否有jQuery附加上去的数据。

修改了jQuery.expando的实现,在原来单纯地取当前时间的基础上,添加了一个随机数:

expando = "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" );

这样保证在同一时间,引入多个jQuery副本,这几个副本之间的expando不会相互冲突,导致元素上的data变得错乱。一般来说,是不会引入多个jQuery副本的,但是使用SealJS等的时候,配置不当的话,也是很容易出现此类问题的。

DOM操作部分

原本的hasClass、addClass、removeClass函数都需要将元素的class属性分隔为数组,在1.4.4版本中,通过\n或\t进行分隔,在1.5中增加了一个\r,用于对应Windows平台下的换行符(\r\n)。

jQuery.fn.attr函数,1.4.4版本中拒绝从TextNode和CommentNode上获取属性,在1.5版本中添加了一个AttributeNode(noteType == 2)。

在1.4.4版本中,jQuery会在页面unload的时候清理掉由jQuery维护的所有DOM事件,这是为了避免IE的内存泄露问题。但是在1.5中这一段代码不见了,不知是出于什么考虑。

对于IE下使用cloneNode复制节点,会将事件也一起复制过来的问题,1.4.4中是采取复制innerHTML的方式给予解决,而在1.5中则采纳了mootools团队提供的方法,使用cloneFixAttribute函数修正该问题。

cloneFixAttribute函数们于jQuery 1.5 beta1源码文件的5388-5438行,处理IE的BUG的原理很简单,当然前端里一些看似简单的东西,都是很难发现的:

  1. IE中有个叫clearAttributes的函数,会清除到节点上的所有属性,顺便把和事件相关的onclick之类的属性也去掉了。在复制出来的节点上调用这个函数,就会把属性清得干干净净。
  2. IE中还有一个叫mergeAttributes的函数,把一个节点的属性复制到另一个节点上,但他不会把和事件相关的属性复制过去。所以再把原始节点调用mergeAttributes,把属性重新放回复制出来的节点上,这就相当于起到了去除事件相关属性的作用。

另外cloneFixAttribute函数还处理了非常多IE6-8在cloneNode上的兼容性问题,非常值得详细研究。

AJAX部分

AJAX已经完全重写了,只留下一点边边角角保留着1.4.4版本的风采,这里只抽取一部分进行简单的说明。

原来版本中$.get和$.post的实现非常相似,具体来说仅有一个method配置项不同,因此在1.5版本中被合并起来了:

$.each(['get', 'post'], function(i, method) {
$[method] = function() { ... };
});

ajaxSetup函数现在加了一行return this;,可以链式调用了。

serializeArray函数现在统一将value中的换行符替换成Windows的风格(\r\n)。

AJAX的回调函数中,作为参数的对象不再是原生的XMLHTTPRequest,而是jQuery自己封装的称为jXHR的对象,这个对象提供了XMLHTTPRequest的常用接口。

原本对于“请求成功”的浏览器状态码,除200-299以及304外,还有一个1223,来自于IE的一个BUG,会将204的状态码变成 1223。现在因为有了jXHR对象,相当于中间多了一层,因此从jXHR对象获取statusCode不会出现1223的情况,已经被变回204了。

jQuery.ajax函数的配置项中多了一个statusCode项,其结构为map,用于指定返回特定状态码时的回调函数,大致形式如下:

jQuery.ajax({
url: 'xxx',
statusCode: {
200: function() { 处理请求成功 },
404: function() { 处理页面未找到 },
503: function() { 处理Service Unavailable }
}
});

再添加了这个回调后,jQuery.ajax函数已经有非常多的回调函数,其触发过程如下:

  1. 根据返回的状态码,触发success或者error回调。
  2. 根据状态码,触发对应的statusCode回调。
  3. 触发complete回调。
  4. 触发全局ajaxComplete回调。
  5. 如果此时没有正在执行的AJAX,触发全局ajaxStop回调。

其他细节

入口函数jQuery.fn.init现在多了一个参数,值始终为rootjQuery,用于加速init函数中对rootjQuery变量的查找速度(减少了一层作用域):

//jQuery 1.5 beta1 源码23行
jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );
}

jQuery对象支持继承了,具体的修改是将几处直接调用jQuery的代码改为了对this.constructor的调用:

202行:return this.constructor( context ).find( selector );
253行:var ret = this.constructor();
334行:return this.prevObject || this.constructor(null);

同时还提供了jQuery.subclass函数用于创建一个继承自jQuery的类型,由于不是很常用jQuery,更是从来没有用到过需要继承jQuery的情况,因此也不方便说这个功能的作用有多大。

原文来自:http://www.cnblogs.com/GrayZhang/archive/2011/01/18/jquery-1-5-enhanced-detail.html

Tags: jquery

Yii ClinkPager 郁闷

开发的时候,分页用了CLinkPager,然而在某一个页面的时候,page一直在变,但是下面的分类中的当前页永远在1上,不随着页码的变化而变化。
开始的时候以为是分页程序有问题,仔细对应了一下,发现分页的数据是正确的。
排查了半个多小时,突然想起,会不会$_GET['page']被unset了?
找了一下页面,最后在模版页里居然真的发现了unset($_GET['page']),当时我就傻眼了。
顺便再上一个option的onchange切换函数。很烂,只求先解决问题。。。。

JavaScript代码
  1. function urlchange(field,value) {  
  2.     var href= location.href;  
  3.     var regex = new RegExp(field+"=[\-|0-9]{0,}");  
  4.     if(href.indexOf(field)!=-1){  
  5.         location.href = href.replace(regex,field+"="+value);  
  6.     }else{  
  7.         location.href = href + "&"+field+"="+value;  
  8.     }  
  9. }      

用法就是<select onchange="urlchange('page',this.value)"><option value='1'>第一页</option><option value='2'>第二页</option><option value='10'>第十页</option></select>

Tags: yii, clinkpager

YUI PHP Loader Utility

YUI是一个低调又强大的框架。你不能说它有什么,但它确实就存在着。。。
jQuery是Yii框架自带的一个工具,比如ZII里集成的全是JQuery,但YUI也是有着自己的工具,比如这个YUI PHP Load Ulility

The YUI PHP Loader Utility is a server-side utility that allows you to load specific YUI components and their dependencies into your page via PHP. YUI PHP Loader can operate as a holistic solution by loading all of your necessary YUI components, or it can be used to add one or more components to a page on which some YUI content already exists.

YUI also contains a client-side loader, which provides similar functionality from JavaScript.

YUI PHP Loader adds value in the following ways:

  1. Reliable, sorted loading of dependencies: YUI comprises more than two-dozen components, many of which work together to provide the best possible compromise between compartmentalization and code reuse. Because of this, YUI components often need to load with specific dependencies in a specific order. YUI PHP Loader understands which components depend on one another, and based on this knowledge it ensures that the right resources are loaded in the right order.
  2. Automatic use of rolled-up files. YUI PHP Loader knows about all of the built-in rollup files that ship with YUI — like the yahoo-dom-event.js file that contains the Yahoo Global Object, the Dom Collection, and the Event Utility, three components that are commonly used together. By automatically using rolled-up files when it makes sense to do so, the YUI PHP Loader helps you reduce HTTP requests and thereby keep your page as efficient as possible.

As you think about how you want to load YUI on the page, you may find it useful to refer to this overview of some of the most common loading strategies and their relative merits:

YUI的CSS其实也不错,现在细想想如果不是当年YAHOO那么强势的推PHP,如今的PHP也不会被这么多公司所能够接受吧。google是在强推python,虽然现在有着go语言,但python也正在被越来越多的公司所接受了,比如它的兼容性,它的运行速度。。。我还是比较喜欢的。。。。。。

Tags: yui, javascript, framework, jquery, yii