2009年

[WordPress] XML-RPC を使用する方法 このエントリーを含むはてなブックマーク

WordPress Add comments

XML-RPC を使用して、WordPress に投稿する方法です。

XML-RPC とは簡単に言うと XML を HTTP でやり取りしてリモート手続き呼び出しを行うための方法です。非常に簡単な仕様で、仕様書も短いですので興味のある方は下記サイトで仕様を確認してください。
XML-RPC Specification
XML-RPC 仕様書 (上記仕様の日本語訳)

その他の参考サイト
PEAR の XML_RPC のマニュアル
Manual :: XML_RPC

WordPress でサポートされている XML-RPC API
Blogger API
MetaWeblog API
Movable Type API

WordPress の XML-RPC API
XML-RPC wp ? WordPress Codex

日本語の情報では下記サイトが見やすくまとめられています。
MovableType で使える XML-RPC API

準備

PHP で XML-RPC を使用するときに PEAR の XML_RPC を使うと非常に簡単です。下記コマンドでインストールします。

# pear install XML_RPC

WordPress が当然必要になるのですが、実際に公開しているブログでテストするのはあれなので、ローカルサーバにテスト用の WordPress をインストールしました。WordPress 2.7 では XML-RPC がデフォルトで使用できないようになっていますので、「設定」>「投稿設定」の中にある XML-RPC のチェックボックスにチェックを入れてます。これで WordPress の XML-RPC が有効になります。

ブログ情報の取得

WordPress の URL が http://example.com/wordpress/ だとすると host は example.com 、XML-RPC サーバ(xmlrpc.php)へのパスは /wordpress/xmlrpc.php となります。
ユーザ名とパスワードには WordPress に登録したユーザを指定します。appkey という項目は Blogger API で使用しますが、WordPress では使われない項目なので空白でかまいません。

記事を投稿したりするときには、blog_id が必要になるのでまず下記のようにして、blog_id を取得します。実際には blog_id の他にも URL やブログ名、ユーザの属性などが取得できます。

require_once("XML/RPC.php");

$host = "example.com";
$xmlrpc_path = "/wordpress/xmlrpc.php";
$appkey = '';
$user = 'username';
$passwd ='password';

$c = new XML_RPC_client($xmlrpc_path, $host, 80);
$appkey = new XML_RPC_Value($appkey, 'string');
$username = new XML_RPC_Value( $user, 'string' );
$passwd = new XML_RPC_Value( $passwd, 'string' );

$message = new XML_RPC_Message(
    'blogger.getUsersBlogs',
    array($appkey, $username, $passwd) );

$result = $c->send($message);

if( !$result ){
 	exit('Could not connect to the server.');
}else if( $result->faultCode() ){
 	exit($result->faultString());
}
$blogs = XML_RPC_decode($result->value());

$blog_id = new XML_RPC_Value($blogs[0]["blogid"], "string");

Recent Post の取得

$numbers = new XML_RPC_Value(20, "int");
$message = new XML_RPC_Message(
    'metaWeblog.getRecentPosts',
    array($blog_id, $username, $passwd, $numbers) );

$result = $c->send($message);

if( !$result ){
    exit('Could not connect to the server.');
}else if( $result->faultCode() ){
    exit($result->faultString());
}
$posts = array_map(
    'array_convEnc',
    XML_RPC_decode($result->value())
);

function array_convEnc($a){
    if( is_array($a) ){ return array_map( 'array_convEnc', $a ); }
    return mb_convert_encoding($a, mb_internal_encoding(),'UTF-8');
}

ファイルのアップロード

写真などのファイルをアップロードすることもできます。記事に写真を入れたい時には予めファイルをアップロードしておく必要があります。アップロード後に URL など取得できるのでそれを投稿する時に使用します。

$image = file_get_contents("/path/to/filename.jpg");
$file = array(
    "bits" => new XML_RPC_Value($image, "base64"),
    "name" => new XML_RPC_Value("filename.jpg", "string"),
);
$file = new XML_RPC_Value($file, "struct");
$message = new XML_RPC_Message(
    'metaWeblog.newMediaObject',
    array($blog_id, $username, $passwd, $file)
);
$result = $c->send($message);
if( !$result ){
    exit('Could not connect to the server.');
}else if( $result->faultCode() ){
    exit($result->faultString());
}
$resp = XML_RPC_decode($result->value());
$image_url = $resp["url"];

記事の投稿

タイトルやカテゴリ、本文、投稿日時、公開するか下書きにするかなどを指定します。

$title = 'TITLE';
$categories = array(
    new XML_RPC_Value("category name1", "string"),
    new XML_RPC_Value("category name2", "string")
);
$description = "ここに本文を入れます。<p>HTML も書けます</p><img src='".$image_url."'>";
$content = new XML_RPC_Value(
    array(
        'title' => new XML_RPC_Value($title, 'string'),
        'categories' => new XML_RPC_Value($categories, 'array'),
        'description' => new XML_RPC_Value($description, 'string'),
        'dateCreated' => new XML_RPC_Value(time(), 'dateTime.iso8601')
    ),
    'struct');
$publish = new XML_RPC_Value(1, "boolean");
$message = new XML_RPC_Message(
    'metaWeblog.newPost',
    array($blog_id, $username, $passwd, $content, $publish));

$result = $c->send($message);

if( !$result ){
    exit('Could not connect to the server.');
}else if( $result->faultCode() ){
    exit($result->faultString());
}
$post_id = XML_RPC_decode($result->value());

metaWeblog.newPost でカテゴリを指定するときは 配列にする必要があり、またカテゴリ名で指定しなければいけません。blogger.newPost ではタイトルやカテゴリは本文と一緒に下記のように指定します。そのときのカテゴリの指定はカテゴリID だったのでちょっとはまりました。

$content = "<title>TITLE</title><category>4</category>本文...";

関連する投稿

27 Responses to “[WordPress] XML-RPC を使用する方法”

  1. showBOO Says:

    はじめまして。
    参考にさせていただいております。

    上記のコードのように、WPに大してPostしてみたのですが、
    上記の「記事の投稿」の20行の時点で、
    Fatal error: Call to a member function serialize() on a non-object in C:\xampp\php\PEAR\XML\RPC.php on line 1292
    と出てしまいます。

    なにが原因が考えられますでしょうか?

    突然の質問で申し訳ありません。

  2. matsuura Says:

    質問はいつでも歓迎です。

    文字コードはどうなっていますか?
    マルチバイト文字が入っている場合は UTF-8 でないと同様のエラーになったことがありました。

    または、blog_id は正しく入っていますか?
    blog_id, username, passwd などが XML_RPC_Value で入れていないと同様のエラーになりました。

    require_once(“XML/RPC.php”);
    $host = “example.com”;
    $xmlrpc_path = “/wordpress/xmlrpc.php”;
    $appkey = ”;
    $user = ‘username’;
    $passwd =’password’;

    $c = new XML_RPC_client($xmlrpc_path, $host, 80);
    $appkey = new XML_RPC_Value($appkey, ‘string’);
    $username = new XML_RPC_Value( $user, ‘string’ );
    $passwd = new XML_RPC_Value( $passwd, ‘string’ );

    $blog_id = new XML_RPC_Value($blogs[0]["blogid"], “string”);

    参考になれば幸いです。

  3. showBOO Says:

    お返事ありがとうございます。
    文字コードはUTF-8でやろうとしています。
    $blog_idをダンプすると以下のようになります。

    object(XML_RPC_Value)#33 (2) {
    ["me"]=>
    array(1) {
    ["string"]=>
    string(1) “1″
    }
    ["mytype"]=>
    int(1)
    }

    これはblog_idが正しく取得できていると言うことで良いでしょうか?

  4. matsuura Says:

    blog_id はそれで大丈夫ですね。

    var_dump($message->serialize());
    としてみたらどうなりますか?

    serialize すると $message の内容が XML になります。それで自分が作った $message が思った通りの XML になっているか確認できますので。

  5. showBOO Says:

    たびたびすみません。。。
    var_dump($message->serialize());
    で同じエラーが表示されます。

    ちなみに私が作成しているコードは以下のようなコードなのですが、間違っていますでしょうか?

    面倒をかけますが、よろしくお願いいたします。

    require_once(“XML/RPC.php”);

    $host = “somehost”;
    $xmlrpc_path = “/pathto/xmlrpc.php”;
    $appkey = ”;
    $user = ‘user’;
    $passwd =’password’;

    $c = new XML_RPC_client($xmlrpc_path, $host, 80);

    $appkey = new XML_RPC_Value($appkey, ‘string’);
    $username = new XML_RPC_Value( $user, ‘string’ );
    $passwd = new XML_RPC_Value( $passwd, ‘string’ );

    $message = new XML_RPC_Message(
    ‘blogger.getUsersBlogs’,array($appkey, $username, $passwd)
    );

    $result = $c->send($message);

    if(!$result){
    exit(‘Could not connect to the server.’);
    } else if( $result->faultCode() ){
    exit($result->faultString());
    }

    $blogs = XML_RPC_decode($result->value());

    $blog_id = new XML_RPC_Value($blogs[0]["blogid"], “string”);

    $title = ‘TITLE’;
    $categories = array(
    new XML_RPC_Value(“未分類”, “string”),
    );
    $description = “ここに本文を入れます。HTML も書けます”;
    $content = new XML_RPC_Value(
    array(
    ‘title’ => new XML_RPC_Value($title, ‘string’),
    ‘categories’ => new XML_RPC_Value($categories, ‘array’),
    ‘description’ => new XML_RPC_Value($description, ‘string’),
    ‘dateCreated’ => new XML_RPC_Value(time(), ‘dateTime.iso8601′)
    ),
    ‘struct’);

    $publish = new XML_RPC_Value(1, “boolean”);

    $message = new XML_RPC_Message(
    ‘metaWeblog.newPost’,
    array($blog_id, $user, $passwd, $content, $publish)
    );

    $result = $c->send($message);

    if(!$result){
    exit(‘Could not connect to the server.’);
    } else if( $result->faultCode() ){
    exit($result->faultString());
    }
    $post_id = XML_RPC_decode($result->value());

  6. matsuura Says:

    $message = new XML_RPC_Message(
    ‘metaWeblog.newPost’,
    array($blog_id, $user, $passwd, $content, $publish)
    );

    の部分が違いますね。$user ではなく、XML_RPC_Value の $username を使ってください。これでうまくいくはずです。

  7. showBOO Says:

    度々ありがとうございます!
    解決しました!!
    何度も答えていただいて恐縮です。
    ありがとうございました。

  8. matsuura Says:

    うまくいったようでよかったです!

  9. ひろぽんの小石川日乗WP版 » なんだ、初期設定か Says:

    [...] WordPress で XML-PRCを使用する方法 [...]

  10. wordpressclip | scribefireを使うためのwordpress設定 Says:

    [...] [WordPress] XML-RPC を使用する方法 | Sun Limited Mt. WordPress が当然必要になるのですが、実際に公開しているブログでテストするのはあれなので、ローカルサーバにテスト用の WordPress をインストールしました。WordPress 2.7 では XML-RPC がデフォルトで使用できないようになっていますので、「設定」>「投稿設定」の中にある XML-RPC のチェックボックスにチェックを入れてます。これで WordPress の XML-RPC が有効になります。 [...]

  11. [Wordpress] XML-RSSを駆使してブログの記事を投稿してみる Says:

    [...] 参考にさせていただいた記事はこちらです [WordPress] XML-RPC を使用する方法 [...]

  12. regepan Says:

    おお!
    投稿出来ました!すばらしい!

  13. matsuura Says:

    regepan さん、お役に立てたようでよかったです :-)

  14. Windows Live Writer | egoblock Says:

    [...] WordPressでXML-RPCを使う。 カテゴリー: Microsoft, ソフトウェア   パーマリンク ← 楽天ぴたっとアド [...]

  15. wordpress XML-RPCで画像をつけた記事を投稿 | DBIT Says:

    [...] http://blog.syuhari.jp/archives/1373 http://www.moonmile.net/blog/archives/1717 [...]

  16. aki Says:

    はじめまして。突然の質問でご容赦下さい。
    私もXML-RPCを使ってPHPからWordPressへの投稿を試みているのですがうまくいきません。

    エラーは
    Didn’t receive 200 OK from remote server. (HTTP/1.1 403 Forbidden)

    です。
    ユーザー/パスワードやxmlrpc.phpのパスは間違っていないはずなのですが。WordPress側の投稿設定もチェック済みです。ハッスルサーバーを使用して、PEARは自分で導入しました。

    気になる点としては
    ・WordPressをマルチサイト化している。
    ・WP_XMLRPC_PATH に存在しないパス(xxx.phpなど)を指定しても同じエラーが発生する。

    何かお気づきの点がありましたらご教授頂けないでしょうか?厚かましいお願いで恐縮ですがよろしくお願いします。

  17. matsuura Says:

    aki さん
    はじめまして。
    403 なのと違うパスを指定しても同じエラーが出ることより、サーバが外部からのアクセスを禁止しているように思います。
    問題を切り分ける意味で XML-RPC を使っているブログ投稿用のプログラムを使用してみるのはいかがでしょうか?それでアクセスできればご自分のコードの問題ですし、アクセスできばければサーバの問題です。
    または、お使いのサーバの規約を確認してみるか、管理元に問合せしてみてはいかがでしょうか?

    よい解決法でなく申し訳ございません。

  18. aki Says:

    ご回答ありがとうございます。
    WindowsLiveWriterからの投稿は問題無くできました。
    追いかけてみたところ最初のmessage送信(ブログIDの取得)のところでエラーとなっているようなのでやはりxmlrpc.phpのパスの問題でしょうか。

    $host = “sample.biz”;
    $xmlrpc_path = “/xmlrpc.php”;

    これで間違えようは無い気がするのですが。なお
    http://sample.biz/xmlrpc.php にブラウザからアクセスできることは確認しました。

    また上記の最初のmessage送信のresultのダンプは

    object(XML_RPC_Response)#6 (4)
    {
    ["xv"]=> NULL
    ["fn"]=> int(5)
    ["fs"]=> string(66) “Didn’t receive 200 OK from remote server. (HTTP/1.1 403 Forbidden)”
    ["hdrs"]=> NULL
    }

    です。

    お手数をおかけして恐縮ですが、お気づきの点がありましたらご指摘下さい。

  19. aki Says:

    解決しました!
    ハッスルサーバーに問い合わせたところ
    ————————————–
    ハッスルサーバーでは、外国からの一部の一部のアクセスを制限させて
    いただいております。もし解除されたい場合は、

    <Files *>
    <Limit POST>
    order allow,deny
    allow from all
    </Limit>
    </Files>

    という内容の.htaccessを設置すると、制限が解除されますので、
    ご利用ください。
    ———————————–

    という返答が返ってきました。「同じサーバー内からのアクセスなのにまさかなー」と思いつつxmlrpc.phpのあるディレクトリの.htaccessを書き換えたところ、投稿可能となりました。

    低レベルな質問でお手を煩わせてしまい申し訳ございません。
    素早いレスを頂き本当に感謝しております、ありがとうございました。

  20. matsuura Says:

    aki さん
    解決してよかったです!あまりお役に立てずにすいません。

  21. baku Says:

    初めまして。

    記事を拝見させていただきまして、
    現在チャレンジ中です。
    ありがとうございます。

    いきなりの質問で申し訳ございません。

    記事の通り、phpファイルを作ったのですが、
    動作方法は該当のphpファイルにアクセスするだけで
    大丈夫でしょうか?

    大丈夫と仮定した場合、
    実際にアクセスしてみると
    「Parse error: syntax error, unexpected T_LNUMBER in xxx」
    とうエラーが出ました。

    ソースコード上では、require_once(“XML/RPC.php”);
    の部分になります。

    調べてみたのですが、よく分かりませんでした。

    原因などお分かりでしたら教えて頂ければ幸いです。

    宜しくお願い致します。

  22. matsuura Says:

    > bakuさん
    はじめまして。参考にしていただきありがとうございます。Parse error ですので入力内容に間違いがないか再度確認してみてください。あと、PEAR の XML_RPC が入っているか、パスが通っているかなども確認してみてください。

  23. baku Says:

    matsuuraさん

    ご回答ありがとうございます。
    見直し、Parse errorは出なくなりましたが
    代わりに下記エラーが出るようになりました。

    Deprecated: Function split() is deprecated in C:\xampp\php\PEAR\XML\RPC.php on line 1558

    Deprecated: Function split() is deprecated in C:\xampp\php\PEAR\XML\RPC.php on line 1558
    parse error. not well formed

    調べたところ、PHPのバージョンの問題らしく、
    split() が問題なので、explode() に置換すればいい
    そうなのですがmatsuuraさんも同じような対応を
    されたことがあるのでしょうか?

    宜しくお願い致します。

  24. matsuura Says:

    > bakuさん
    PHP5.3 を使われているのですね。5.3 だとそのエラーが出ますね。対応方法はそれで問題ないです。

  25. baku Says:

    matsuuraさん

    さきほどのDeprecated: Function split() is deprecatedのエラーも解消されました。

    その後、phpファイルにアクセスすると、parse error. not well formedというメッセージが表示されます。

    これはプログラムが悪いのでしょうか?
    行数が表示されてないのでプログラムが原因なのか分かりません。
    ワードプレスを見てみても投稿されてなかったので失敗しているとは思いますが。

    何か思い当たることはおありでしょうか?

    宜しくお願い致します。

  26. baku Says:

    matsuuraさん

    先ほど無事投稿できました。

    プログラムをutf-8で保存するとうまくいきました。

    ありがとうございました。

  27. sas Says:

    参考にさせていただきwordpressに投稿することができました。ありがとうございます。

    が、日本語がなぜか文字化けしてしまいます。

    投稿先サーバは桜サーバで自前のwordpressになり文字コードはutf-8となっております。
    どこに問題があるかご教授いただけないでしょうか?

    require_once(“XML/RPC.php”);

    $host = “host”;
    $xmlrpc_path = “path”;
    $appkey = ”;
    $user = ‘user’;
    $passwd =’pass’;

    $c = new XML_RPC_client($xmlrpc_path, $host, 80);
    $appkey = new XML_RPC_Value($appkey, ‘string’);
    $username = new XML_RPC_Value( $user, ‘string’ );
    $passwd = new XML_RPC_Value( $passwd, ‘string’ );

    $message = new XML_RPC_Message(
    ‘blogger.getUsersBlogs’,
    array($appkey, $username, $passwd) );

    $result = $c->send($message);

    if( !$result ){
    exit(‘Could not connect to the server.’);
    }else if( $result->faultCode() ){
    exit($result->faultString());
    }
    $blogs = XML_RPC_decode($result->value());

    $blog_id = new XML_RPC_Value($blogs[0]["blogid"], “string”);

    $title = ‘TITLE’;
    $categories = array(
    new XML_RPC_Value(“category name1″, “string”),
    new XML_RPC_Value(“category name2″, “string”)
    );
    $description = “ここに本文を入れます。HTML も書けます”;
    $content = new XML_RPC_Value(
    array(
    ‘title’ => new XML_RPC_Value($title, ‘string’),
    ‘categories’ => new XML_RPC_Value($categories, ‘array’),
    ‘description’ => new XML_RPC_Value($description, ‘string’),
    ‘dateCreated’ => new XML_RPC_Value(time(), ‘dateTime.iso8601′)
    ),
    ‘struct’);
    $publish = new XML_RPC_Value(1, “boolean”);
    $message = new XML_RPC_Message(
    ‘metaWeblog.newPost’,
    array($blog_id, $username, $passwd, $content, $publish));

    $result = $c->send($message);

    if( !$result ){
    exit(‘Could not connect to the server.’);
    }else if( $result->faultCode() ){
    exit($result->faultString());
    }
    $post_id = XML_RPC_decode($result->value());

Leave a Reply

Additional comments powered by BackType

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS ログイン