一直想写一个给wordpress群发文章的应用,这样我就能自动采集文章,然后写个脚本自动发送文章了,哈哈。虽然用python干这种事情貌似更加擅长,但是我想做个web界面访问该应用,而python的虚拟主机现在还好少(至少PHP真的很容易有),于是拿起老本行,用PHP来搞定。
学PHP也已经有很长时间,从原来的纯手工编写,到后来的网上找类库自己整合,再到如今的直接使用框架。我再也不愿意从头开始写程序,现成的框架有大量的优秀代码,拿来用能实现目标何乐而不为,之前也用过zend、thinkphp、codeigniter,前两者其实都不错,但是现在我还是很偏爱codeigniter,就因为它强大的在线文档。
我使用的是CI(codeigniter)的“XML-RPC 和 XML-RPC 服务器类”,以下代码实现了将服务器wordpress站点的标签信息获取下来打印:
public function index(){ //加载CI的xmlrpc类库 $this->load->library('xmlrpc'); //设定远程的XMLRPC.php文件的地址 $this->xmlrpc->server('http://jobrule.sinaapp.com/xmlrpc.php'); /* * 设定需要操作的方法,该字符串,可以在wordpress服务器上 * 的/wp-includes/class-wp-xmlrpc-server.php里面找到 */ $this->xmlrpc->method('wp.getTags'); /* * 设定请求参数,可以直接去看class-wp-xmlrpc-server.php的源代码, * 其中第0个是id,第一个和第二个是用户名密码 */ $request = array('','admin', '123456789'); //将参数设定到请求里面,这时候还没有发送请求 $this->xmlrpc->request($request); //发送请求 if ( ! $this->xmlrpc->send_request()){ echo $this->xmlrpc->display_error(); } //打印结果看一看 echo "<pre>"; print_r( $this->xmlrpc->display_response()); echo "</pre>"; //$this->load->view('welcome_message'); }
CI的官方文档列出了xmlrpc类的API:
- $this->xmlrpc->server():设定发送请求的服务器URL和端口号
- $this->xmlrpc->timeout():设定一个发送请求的响应时间
- $this->xmlrpc->method():设定请求的服务方法字符串(重要)
- $this->xmlrpc->request():绑定发送请求的数据参数,并不发送请求
- $this->xmlrpc->send_request():发送请求
- $this->xmlrpc->display_error():打印错误信息
- $this->xmlrpc->display_response():打印返回的响应信息
- $this->xmlrpc->set_debug(TRUE):开发过程中打印一些调试信息
关键在于$this->xmlrpc->method(),该接口设定向服务器发送什么样的请求。下载一个wordpress源码,打开\wp-includes\class-wp-xmlrpc-server.php文件,可以看到所有的我们能够调用的服务:
// WordPress API 'wp.getUsersBlogs' => 'this:wp_getUsersBlogs', 'wp.newPost' => 'this:wp_newPost', 'wp.editPost' => 'this:wp_editPost', 'wp.deletePost' => 'this:wp_deletePost', 'wp.getPost' => 'this:wp_getPost', 'wp.getPosts' => 'this:wp_getPosts', 'wp.newTerm' => 'this:wp_newTerm', 'wp.editTerm' => 'this:wp_editTerm', 'wp.deleteTerm' => 'this:wp_deleteTerm', 'wp.getTerm' => 'this:wp_getTerm', 'wp.getTerms' => 'this:wp_getTerms', 'wp.getTaxonomy' => 'this:wp_getTaxonomy', 'wp.getTaxonomies' => 'this:wp_getTaxonomies', 'wp.getPage' => 'this:wp_getPage', 'wp.getPages' => 'this:wp_getPages', 'wp.newPage' => 'this:wp_newPage', 'wp.deletePage' => 'this:wp_deletePage', 'wp.editPage' => 'this:wp_editPage', 'wp.getPageList' => 'this:wp_getPageList', 'wp.getAuthors' => 'this:wp_getAuthors', 'wp.getCategories' => 'this:mw_getCategories', // Alias 'wp.getTags' => 'this:wp_getTags', 'wp.newCategory' => 'this:wp_newCategory', 'wp.deleteCategory' => 'this:wp_deleteCategory', 'wp.suggestCategories' => 'this:wp_suggestCategories', 'wp.uploadFile' => 'this:mw_newMediaObject', // Alias 'wp.getCommentCount' => 'this:wp_getCommentCount', 'wp.getPostStatusList' => 'this:wp_getPostStatusList', 'wp.getPageStatusList' => 'this:wp_getPageStatusList', 'wp.getPageTemplates' => 'this:wp_getPageTemplates', 'wp.getOptions' => 'this:wp_getOptions', 'wp.setOptions' => 'this:wp_setOptions', 'wp.getComment' => 'this:wp_getComment', 'wp.getComments' => 'this:wp_getComments', 'wp.deleteComment' => 'this:wp_deleteComment', 'wp.editComment' => 'this:wp_editComment', 'wp.newComment' => 'this:wp_newComment', 'wp.getCommentStatusList' => 'this:wp_getCommentStatusList', 'wp.getMediaItem' => 'this:wp_getMediaItem', 'wp.getMediaLibrary' => 'this:wp_getMediaLibrary', 'wp.getPostFormats' => 'this:wp_getPostFormats', 'wp.getPostType' => 'this:wp_getPostType', 'wp.getPostTypes' => 'this:wp_getPostTypes', // Blogger API 'blogger.getUsersBlogs' => 'this:blogger_getUsersBlogs', 'blogger.getUserInfo' => 'this:blogger_getUserInfo', 'blogger.getPost' => 'this:blogger_getPost', 'blogger.getRecentPosts' => 'this:blogger_getRecentPosts', 'blogger.getTemplate' => 'this:blogger_getTemplate', 'blogger.setTemplate' => 'this:blogger_setTemplate', 'blogger.newPost' => 'this:blogger_newPost', 'blogger.editPost' => 'this:blogger_editPost', 'blogger.deletePost' => 'this:blogger_deletePost', // MetaWeblog API (with MT extensions to structs) 'metaWeblog.newPost' => 'this:mw_newPost', 'metaWeblog.editPost' => 'this:mw_editPost', 'metaWeblog.getPost' => 'this:mw_getPost', 'metaWeblog.getRecentPosts' => 'this:mw_getRecentPosts', 'metaWeblog.getCategories' => 'this:mw_getCategories', 'metaWeblog.newMediaObject' => 'this:mw_newMediaObject', // MetaWeblog API aliases for Blogger API // see http://www.xmlrpc.com/stories/storyReader$2460 'metaWeblog.deletePost' => 'this:blogger_deletePost', 'metaWeblog.getTemplate' => 'this:blogger_getTemplate', 'metaWeblog.setTemplate' => 'this:blogger_setTemplate', 'metaWeblog.getUsersBlogs' => 'this:blogger_getUsersBlogs', // MovableType API 'mt.getCategoryList' => 'this:mt_getCategoryList', 'mt.getRecentPostTitles' => 'this:mt_getRecentPostTitles', 'mt.getPostCategories' => 'this:mt_getPostCategories', 'mt.setPostCategories' => 'this:mt_setPostCategories', 'mt.supportedMethods' => 'this:mt_supportedMethods', 'mt.supportedTextFilters' => 'this:mt_supportedTextFilters', 'mt.getTrackbackPings' => 'this:mt_getTrackbackPings', 'mt.publishPost' => 'this:mt_publishPost', // PingBack 'pingback.ping' => 'this:pingback_ping', 'pingback.extensions.getPingbacks' => 'this:pingback_extensions_getPingbacks', 'demo.sayHello' => 'this:sayHello', 'demo.addTwoNumbers' => 'this:addTwoNumbers'
根据方法名字,很容易知道是什么意思。要知道某一个方法需要发送什么参数,直接找到该方法,方法的注释可以看出需要什么参数,比如发送文章的newpost方法,根据注释知道需要如下参数:
/** * Create a new post for any registered post type. * * @since 3.4.0 * * @param array $args Method parameters. Contains: * - int $blog_id * - string $username * - string $password * - array $content_struct * $content_struct can contain: * - post_type (default: 'post') * - post_status (default: 'draft') * - post_title * - post_author * - post_exerpt * - post_content * - post_date_gmt | post_date * - post_format * - post_password * - comment_status - can be 'open' | 'closed' * - ping_status - can be 'open' | 'closed' * - sticky * - post_thumbnail - ID of a media item to use as the post thumbnail/featured image * - custom_fields - array, with each element containing 'key' and 'value' * - terms - array, with taxonomy names as keys and arrays of term IDs as values * - terms_names - array, with taxonomy names as keys and arrays of term names as values * - enclosure * - any other fields supported by wp_insert_post() * @return string post_id */
至此PHP远程操作wordpress的基本流程已经非常清晰,本文使用的是CI的xmlrpc类,网友可以自己网上随便找个开源类代替,他们的接口肯定大同小异。关键是弄懂了服务端提供了什么服务,直接调用就好了。
这个听高级的,我就不擅长wp