其实,不久前就知道新浪微博的ID的长度发生了变化,所以,原来的无符号长整形的长度是肯定不够了,超出后就变成了科学计数法。这样的URL可是没有办法在浏览器中打开的。
但服务器上一直没有这个问题,运行了uname -a后发现是64位系统,但测试机是32位的,怎么解决这个问题呢?
检查了一下oauth的代码,发现问题出在了json_decode函数上,因为取回来的数据都是字符串,只是在经过json_decode后,数字才超出长度了。知道这个问题后就好办了。
搜索json_decode,在这上面加上一行:
$response = preg_replace('@"id":(\d+)@','"id":"\\1"',$response);
为ID强制加上引号,变成字符串,而不是int型,所以在经过json_decode后,就仍然是字符串了。NND,新浪真偷懒,全部搞成字符串不就结了?到现在还在那里折腾整形不整形的。。
所幸,问题解决了。
这是一篇很小的例子,事实上网上这些例子是超多的,不过由于我是要模拟metaweblog或者是wordpress的一些操作,那我就必须要先了解很多相关的背景。
不过这里只是模拟一些发布和读取的接口,稍作了解即可。
原文来自:用XML-RPC协议读写WordPress上的文章我这里只简要的摘取一部分。
WordPress提供了XML-RPC接口使得第三方的博客写作软件(如windows live writer等)可以与之通信来发布和修改博客。我们也可以在网站上使用这个接口做一些工作,例如:在网站首页显示最新的博客、在博客之外的页面上发表博 客文章、把博客与其他内容管理系统结合,等等。
一、开启XML-RPC支持
XML-RPC协议默认是未开启的,需要到WordPress管理后台的“设置–>撰写”里的“远程发布”给XML-RPC打上勾。其说明文 字为:启用 WordPress,Movable Type,MetaWeblog和Blogger 的 XML-RPC发布协议。
二、获取接口的信息
我们查看博客首页的源代码,在head中可以发现类似这样的link项
XML/HTML代码
- <link title="RSD" rel="EditURI" type="application/rsd+xml" href="http://blog.bluesky.cn/xmlrpc.php?rsd" />
其中的"RSD"是“Really Simple Discovery”的意思,也就是说这是一个“简单的发现博客编辑接口”的地址。我们用浏览器直接访问这个地址就可以在其返回XML中获知博客的 ID(blogID,一般这个的值是“1”)以及它所支持的接口类型和接口地址。
三、API接口选择
WordPress提供了对Blogger API、metaWeblog API、Movable Type API以及其自身的WordPress API的支持。其中WordPress API最为丰富,提供了包括操作评论文章在内的各种各样的支持。Blogger API功能较少,基本上淘汰不用了;而metaWeblog API提供了常用的接口且参数比较简洁,用得较多一些。
四、例子代码
以下是使用Incutio的XML-RPC库和Blogger API发布文章的例子,其中IXR库也是Wordpress自身所用的库,可以在“wp-includes/class-IXR.php”找到。
PHP代码
- <?php
- $xmlrpcurl='http://blog.bluesky.cn/xmlrpc.php';
- $blogid='1';
- $username='admin';
- $password='pass';
- $postTitle='标题';
- $postContent='正文内容';
-
- require('class-IXR.php');
- $client = new IXR_Client($xmlrpcurl);
-
- $params=array(
- '',
- 'blog_ID'=>$blogid,
- 'user_login'=>$username,
- 'user_pass'=>$password,
- 'post_content'=>'' . $postContent,
- 'publish'=>true
- );
- $params=array_values($params);
-
- $client->query("blogger.newPost",$params);
- $response=$client->getResponse();
-
- if ($response['faultCode']==0){
- print 'Success';
- } else {
- print 'Fail:' . $response['faultString'];
- }
- ?>
以下是用XML-RPC for PHP库和metaWeblog接口发布文章的例子。要先下载phpxmlrpc库取出其中的xmlrpc.inc来用。
PHP代码
- <?php
- include("xmlrpc.inc");
- $GLOBALS['xmlrpc_internalencoding'] = 'UTF-8';
-
- define ('DOMAIN', 'blog.bluesky.cn');
- define ('BLOGID', 1);
- define ('USER', 'admin');
- define ('PASSWORD', 'pass');
-
-
- $cl = new xmlrpc_client ( "/xmlrpc.php", DOMAIN, 80);
-
-
- $req = new xmlrpcmsg('metaWeblog.newPost');
-
- $req->addParam ( new xmlrpcval ( BLOGID, 'int'));
- $req->addParam ( new xmlrpcval ( USER, 'string' ));
- $req->addParam ( new xmlrpcval ( PASSWORD, 'string' ));
- $struct = new xmlrpcval (
- array (
- "title" => new xmlrpcval ( '标题', 'string' ),
- "description" => new xmlrpcval ( '正文内容', 'string'),
- ), "struct"
- );
- $req->addParam ( $struct );
- $req->addParam ( new xmlrpcval (1, 'int'));
-
-
- $ans = $cl->send($req);
-
- var_dump ( $ans );
- ?>
注意一定要加上:$GLOBALS['xmlrpc_internalencoding'] = ‘UTF-8′;这一句,否则不能正确处理中文。 另一段也是用phpxmlrpc库和metaWeblog接口发表文章的例子代码,该代码使用了返回类型为“phpvals”,这样可以直接用返回结果 的$r->val来获取文章ID号。
PHP代码
- <?php
- include("xmlrpc.inc");
- $GLOBALS['xmlrpc_internalencoding'] = 'UTF-8';
-
- $c = new xmlrpc_client("/xmlrpc.php", "blog.bluesky.cn", 80);
- $content['title']="标题";
- $content['description']="正文内容";
- $content['mt_keywords']="标签1,标签2";
- $content['wp_password']="";
- $content['categories'] = array("分类1","分类2");
- $x = new xmlrpcmsg("metaWeblog.newPost",
- array(php_xmlrpc_encode("1"),
- php_xmlrpc_encode("admin"),
- php_xmlrpc_encode("pass"),
- php_xmlrpc_encode($content),
- php_xmlrpc_encode("1")));
-
- $c->return_type = 'phpvals';
- $r =$c->send($x);
- if ($r->errno=="0")
- echo "发表成功,文章序号为:".$r->val;
- else {
- echo "出错了";
- print_r($r);
- }
- ?>
以下是读取最新一篇文章的例子代码:
PHP代码
- <?php
- include("xmlrpc.inc");
- $GLOBALS['xmlrpc_internalencoding'] = 'UTF-8';
- $c = new xmlrpc_client("/xmlrpc.php", "blog.bluesky.cn", 80);
-
- $msg = new xmlrpcmsg('metaWeblog.getRecentPosts',
- array(php_xmlrpc_encode("1"),
- php_xmlrpc_encode("admin"),
- php_xmlrpc_encode("pass"),
- php_xmlrpc_encode("1")) );
- $res = $c->send($msg);
- $val = $res->value();
-
- $val->arraymem(0)->structreset();
- while (list($key, $v) = $val->arraymem(0)->structeach())
- {
- echo "Element: $key; Type: ".$v->kindOf()."; Value:".$v->scalarval()."\n";
- }
- ?>
原文地址:
http://blog.bluesky.cn/archives/466/using-xml-rpc-protocol-to-read-and-write-articles-on-wordpress.html
来自xmlrpc网站的资料:http://www.xmlrpc.com/metaWeblogApi
关于这些api还有一些背景资料在这里的:http://www.xmlrpc.com/stories/storyReader$2509,多看看啦。。。
Document status
This document was updated on 8/8/03, to incorporate all the RFCs related to the MetaWeblog API. The earlier version of the document is archived here. It has been reviewed by members of the MetaWeblog API mail list, and feedback has been incorporated.
On 8/24/03, I posted a last call for comments, and received several and incorporated some.
As of 8/26/03, this document is deployable. There may be changes, but they will be clearly documented, and will only clarify the spec, in no way will they change the format or protocol. It is now safe to deploy applications based on this spec.
What is the MetaWeblog API?
The MetaWeblog API (MWA) is a programming interface that allows external programs to get and set the text and attributes of weblog posts. It builds on the popular XML-RPC communication protocol, with implementations available in many popular programming environments.
Relationship between MetaWeblog API and the Blogger API
The MetaWeblog API is designed to enhance the Blogger API, which was limited in that it could only get and set the text of weblog posts. By the time MWA was introduced, in spring 2002, many weblog tools had more data stored with each post, and without an API that understood the extra data, content creation and editing tools could not access the data.
At the time of this writing, summer 2003, most popular weblog tools and editors support both the Blogger API and the MetaWeblog API.
Relationship between MetaWeblog API and RSS 2.0
The MetaWeblog API uses an XML-RPC struct to represent a weblog post. Rather than invent a new vocabulary for the metadata of a weblog post, we use the vocabulary for an item in RSS 2.0. So you can refer to a post's title, link and description; or its author, comments, enclosure, guid, etc using the already-familiar names given to those elements in RSS 2.0. Further since RSS 2.0 is extensible, so is the MetaWeblog API. We have designed conventions for representing attributes and namespaces in MWA.
Basic entry-points
There are three basic entry-points in the API:
metaWeblog.newPost (blogid, username, password, struct, publish) returns string
metaWeblog.editPost (postid, username, password, struct, publish) returns true
metaWeblog.getPost (postid, username, password) returns struct
The blogid, username, password and publish params are as in the Blogger API. newPost returns a string representation of the post id, again as defined by the Blogger API. The struct is where the juice is.
The struct
In newPost and editPost, content is not a string, as it is in the Blogger API, it's a struct. The defined members of struct are the elements of <item> in RSS 2.0, providing a rich variety of item-level metadata, with well-understood applications.
The three basic elements are title, link and description. For blogging tools that don't support titles and links, the description element holds what the Blogger API refers to as "content."
Where an element has attributes, for example, enclosure, pass a struct with sub-elements whose names match the names of the attributes according to the RSS 2.0 spec, url, length and type.
For the source element, pass a struct with sub-elements, url and name.
For categories, pass an array of strings of names of categories that the post belongs to, named categories. On the server side, it's not an error if the category doesn't exist, only record categories for ones that do exist.
In getPost, the returned value is a struct, as with the Blogger API, but it contains extra elements corresponding to the struct passed to newPost and editPost.
The server must ignore all elements that it doesn't understand.
In a call to metaWeblog.newPost or metaWeblog.editPost, if the struct contains a boolean named flNotOnHomePage, then the post does not appear on the home page, and only appears on the specified category pages.
Request and response
Here's an example of a request and a response.
Here's the post that this request is getting info about.
metaWeblog.newMediaObject
metaWeblog.newMediaObject (blogid, username, password, struct) returns struct
The blogid, username and password params are as in the Blogger API.
The struct must contain at least three elements, name, type and bits.
name is a string, it may be used to determine the name of the file that stores the object, or to display it in a list of objects. It determines how the weblog refers to the object. If the name is the same as an existing object stored in the weblog, it may replace the existing object.
type is a string, it indicates the type of the object, it's a standard MIME type, like audio/mpeg or image/jpeg or video/quicktime.
bits is a base64-encoded binary value containing the content of the object.
The struct may contain other elements, which may or may not be stored by the content management system.
If newMediaObject fails, it throws an error. If it succeeds, it returns a struct, which must contain at least one element, url, which is the url through which the object can be accessed. It must be either an FTP or HTTP url.
metaWeblog.getCategories
metaWeblog.getCategories (blogid, username, password) returns struct
The struct returned contains one struct for each category, containing the following elements: description, htmlUrl and rssUrl.
This entry-point allows editing tools to offer category-routing as a feature.
metaWeblog.getRecentPosts
metaWeblog.getRecentPosts (blogid, username, password, numberOfPosts) returns array of structs
Each struct represents a recent weblog post, containing the same information that a call to metaWeblog.getPost would return.
If numberOfPosts is 1, you get the most recent post. If it's 2 you also get the second most recent post, as the second array element. If numberOfPosts is greater than the number of posts in the weblog you get all the posts in the weblog.
Transmitting elements with attributes
The members of the struct passed in newPost and editPost come from the elements of items in RSS 2.0. The most commonly used core elements have no attributes, so it's clear how to include them in the struct. However, some elements, such as source, enclosure and category, may have attributes and a value. Here are a simple set of rules for elements that have attributes and a value. Note that these rules do not apply to enclosure and source, which are provided for specifically above.
1. If an element has attributes, then represent the element with a struct, and include the attributes as sub-elements of the struct.
2. If an element has both attributes and a value, make the element a struct, include the attributes as sub-elements, and create a sub-element for the value with the name _value. Note that this means that no element can be passed through the API that has an attribute whose name is _value.
Transmitting elements from namespaces
RSS 2.0 allows for the use of namespaces. If you wish to transmit an element that is part of a namespace include a sub-struct in the struct passed to newPost and editPost whose name is the URL that specifies the namespace. The sub-element(s) of the struct are the value(s) from the namespace that you wish to transmit.
Comments
The Blogger API provides a parameter called appkey that allows vendors to assign a key to developers so they can track and possibly limit usage of the API for certain tools. The MetaWeblog API doesn't specifically provide a parameter for an appkey. Applications that wish to transmit an appkey should add an element to the struct called appkey and set its value to the appkey that should be associated with the call.
Applications should use the fault-response scheme defined by XML-RPC. For example, trying to create, get, or edit a post without a valid username-password should generate a fault. Client applications should display the error string, as appropriate, to the user, for example, in a dialog, or in a server log.
Thanks
Thanks to Michael Bernstein for help editing this spec in summer 2003.
References
RSS 2.0; Dave Winer; 9/02.
RFC: MetaWeblog API; Dave Winer; 3/02.
Blogger API; Evan Williams; 8/01.
ManilaRPC; Andre Radke, Brent Simmons, Dave Winer; 1999.
XML-RPC; Dave Winer; 1998
没有什么好说的,学习一下这些资料。然后折腾中。
想用word发布博客,这些就必须要看。
原文来自:http://m2009.org/?p=998
WordPress支持四种远程发布协议,他们是 WordPress,Movable Type,MetaWeblog和Blogger 的 XML-RPC发布协议。
WordPress发布协议
WordPress 发布协议值wordpress自己的文章发布协议,他的接口最为丰富,提供了包括操作评论文章在内的各种各样的支持
WordPress发布协议文档:http://codex.wordpress.org/XML-RPC_wp
Movable Type发布协议
Movable Type,简称MT,是由位于美国加州的Six Apart公司推出的网志(blog)发布系统。它是全球最受欢迎的网志系统之一,包含多用户,评论,引用(TrackBack),主题等功能,并广泛的支持各种第三方插件。
Movable Type不仅可以应用于个人的网志系统,而且可以应用于商业、教育等领域。Movable Type于2007年12月12日正式宣布以GPLv2的协议开源。
Movable Type发布协议文档:http://www.movabletype.org/documentation/
Movable Type 文件集: http://mtbook.org/
MetaWeblog发布协议
The MetaWeblog API is an application programming interface created by software developer Dave Winer that enables weblog entries to be written, edited, and deleted using web services.
The API is implemented as an XML-RPC web service with three methods whose names describe their function: metaweblog.newPost(), metaweblog.getPost() and metaweblog.editPost(). These methods take arguments that specify the blog author’s username and password along with information related to an individual weblog entry.
The impetus for the creation of the API in 2002 was perceived limitations of the Blogger API, which serves the same purpose. Another weblog publishing API, the Atom Publishing Protocol became an IETF Internet standard (RFC 5023) in October 2007.
Many blog software applications and content mangement systems support the MetaWeblog API, as do numerous desktop clients.
MetaWeblog文档:http://www.xmlrpc.com/metaWeblogApi
Blogger发布协议
The Blogger Data API allows client applications to view and update Blogger content in the form of Google Data API feeds.
文档(墙外):http://www.blogger.com/developers/api/1_docs/
google:http://code.google.com/intl/zh-CN/apis/blogger/
比较详细的api文档
API参考文档:http://www.sixapart.com/developers/xmlrpc/
在看代码的时候看到了这个offsetParent也就顺便找了一下资料:
XML/HTML代码
- offsetParent从字面上理解,这是在查找元素的父亲.可实际应用中,根据浏览器他会返回不同的结果.在Opera较低版本中返回被引用元素的直接父元素,在IE中使用offsetParent有时会返回body元素,有时会返回被引用元素的父元素.为什么IE会这样.我会在下面的实例演示中解释清楚.而在FireFox中他总是返回body元素.
- 注意:offsetLeft与offsetTop永远是根据offsetParent来返回值,如果offsetParent返回的是父元素,那么他们就返回与父元素的偏移结果,如果offsetParent返回的是body元素,那么他们就返回与body元素的偏移结果.请根据浏览器进行测试.
然后找了一段代码进行测试:
XML/HTML代码
- <html>
- <head>
- <title>Dom:offsetParent使用</title>
- </head>
- <body>
- <p>该网页中有4个div 他们的id值分别是a,a_1,b,b_1<br/> a包含了a_1.b包含了b_1<br/> a和b是相互独立的..下面我们分别对a_1和b_1两个子元素使用offsetParent方法.
- 你用IE浏览器测试,你会发现a1的运函数弹出body,而b1的运行函数返回了div,同样的两个子元素.同样的使用方法.为什么返回的结果不一样呢? 原因就是我为b1的父元素b,增加了一个宽度属性以后.他就把offsetParent看做是元素的父元素.如果不为b元素指定任何属性样式,他则返回body
- 而在火狐和谷歌浏览器中两次都会弹出body,不会受此影响.</p>
- <div id="a">
- <div id="a_1"></div>
- </div>
- <div id="b" style="width:200px;">
- <div id="b_1"></div>
- </div>
- <script type="text/javascript">
- function a1_offsetParent() { //测试b元素的offsetParent
- var a_1 = document.getElementById("a_1");
- alert(a_1.offsetParent.tagName);
- }
- a1_offsetParent();//运行a1测试函数
- function b1_offsetParent() {
- var b_1 = document.getElementById("b_1");
- alert(b_1.offsetParent.tagName);
- }
- b1_offsetParent();//运行b1测试函数
- </script>
- </body>
- </html>
这个时候就象上面的说明所说的,在firefox和webkit核心下两者都返回了“body”,然而:
XML/HTML代码
- 网友hcp8706说:
- 在FF中使用offsetParent时不一定总返回body元素,当父元素使用css设置了定位属性时,offsetParent就会返回父元素.
于是我在div的id="b"的style里加入了position:absolute,然后再测试,果然就返回了DIV。
XML/HTML代码
- <div id="b" style="width:200px;position:absolute;">
- <div id="b_1"></div>
- </div>
- <script type="text/javascript">
- function b1_offsetParent() {
- var b_1 = document.getElementById("b_1");
- alert(b_1.offsetParent.tagName);
- }
- b1_offsetParent();//运行b1测试函数
- </script>
学习完毕,上述的信息来自:http://www.web666.net/dom/offsetParent.html