Изобретая велосипеды: xmlrpc

19 апреля 2011

Вчера озаботился возможностью что-то опубликовать в блоке посредством xmlrpc из php.

Проковырявшись в общей сложности часа 4 с библиотекой xmlrpc и встроенной функцией xmlrpc_encode_equest и так и не добившись нормальной работы всего этого безобразия, собрался и сегодня за 1.5 часа сделал свой велосипед 🙂

<?php
/*
 * Велосипед для работы с xmlrpc
 * версия 0.1beta
 *
 * Copyright (c) 2011 mrdaark.
 * Все права защищены
 * 
 */
 
/*
 * Функция для отправки запроса на xmlrpc сервер
 * использует библиотеку curl
 * в качестве параметров:
 * @url - url адрес сервера
 * @request - запрос формируемый с помощью функции xmlrpc_request
 */
function xmlrpc_send($url,$request)
{
    if(!function_exists('curl_init')) {
        die ("Curl PHP package not installed\n");
    }
 
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: text/xml; charset=utf-8"));
    curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
    $response = curl_exec($ch);
    $response = xmlrpc_decode($response);
    curl_close($ch);
    return $response;
}
 
/*
 * Функция формирования xml запроса на xmlrpc
 * в качестве параметров:
 * @method - вызываемый метод
 * @params - массив списка параметров
 */
function xmlrpc_request($method,$params)
{
    $xml ="<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
    $xml.="<methodCall><methodName>".$method."</methodName><params>";
 
    if (is_array($params))
    {
        foreach ($params as $v)
        {
            if (is_numeric($v))
            {
                $xml.="<param><value><int>".$v."</int></value></param>";
            }
            else if (is_string ($v))
            {
                $xml.="<param><value><string>".$v."</string></value></param>";
            }
            else if (is_bool($v))
            {
                $xml.="<param><value><boolean>". ($v ? "1":"0") ."</boolean></value></param>";
            }
            else if (is_array($v))
            {
                $xml.="<param>"._xmlrpc_genstruct($v)."</param>";
            }
        }
    }
    $xml.="</params></methodCall>";
    return $xml;
}
 
/*
 * Функция формирования именованной структуры
 * в качестве параметров:
 * @params - массив списка параметров
 */
function _xmlrpc_genstruct($params)
{
    if (is_array($params))
    {
        $xml="<value><struct>";
        foreach ($params as $k=>$v)
        {
            //формируем поля запроса.
            if (is_numeric($v))
            {
                $xml.="<member><name>".$k."</name><value><int>".$v."</int></value></member>";
            }
            else if (is_string ($v))
            {
                $xml.="<member><name>".$k."</name><value><string>".$v."</string></value></member>";
            }
            else if (is_bool($v))
            {
                $xml.="<member><name>".$k."</name><value><boolean>". ($v ? "1":"0") ."</boolean></value></member>";
            }
            else if (is_array($v))
            {
                $xml.="<member><name>".$k."</name>";
                if (_xmlrpc_is_struct($v))
                {
                    $xml.=_xmlrpc_genstruct($v);
                }
                else
                {
                    $xml.=_xmlrpc_genarray($v);
                }
                $xml.="</member>";
            }
        }
        $xml.="</struct></value>";
        return $xml;
    }
    else
    {
        return "";
    }
}
 
/*
 * Функция формирования неименованного массива
 * в качестве параметров:
 * @params - массив списка параметров
 */
function _xmlrpc_genarray($params)
{
    if (is_array($params))
    {
        //проверим необходимость добавления имени
        $xml="<value><array><data>";
        foreach ($params as $v)
        {
            //формируем поля запроса.
            if (is_numeric($v))
            {
                $xml.="<value><int>".$v."</int></value>";
            }
            else if (is_string ($v))
            {
                $xml.="<value><string>".$v."</string></value>";
            }
            else if (is_bool($v))
            {
                $xml.="<value><boolean>". ($v ? "1":"0") ."</boolean></value>";
            }
            else if (is_array($v))
            {
                if (_xmlrpc_is_struct($v))
                {
                    $xml.=_xmlrpc_genstruct($v);
                }
                else
                {
                    $xml.=_xmlrpc_genarray($v);
                }
            }
        }
        $xml.="</data></array></value>";
        return $xml;
    }
    return "";
}
 
/*
 * Функция проверки переданного массива на
 * предмет необходимости формирования
 * именованной структуры
 * в качестве параметров:
 * @params - массив списка параметров
 */
function _xmlrpc_is_struct($params)
{
    $keys=array_keys($params);
    foreach ($keys as $k=>$v)
    {
        if ($k!=$v)
        {
            return true;
        }
    }
    return false;
}
?>

Пользоваться безобразием просто, вот примерчик постинга в блог на wordpress:

<<?php
require("xmlrpc.php");
//формируем массив с параметрами запроса
$content=array();
$content['title']="Тестовая запись";
$content['categories'] = array("news");
$content['description']="Описание тестовой запись (то, что до тега <!--more-->)";
$content['mt_text_more']="Собственно основная часть постинга";
$content['mt_keywords']="ключевые, слова";
 
//формируем xml запрос
$request=xmlrpc_request("metaWeblog.newPost",
        array(1,"admin","password",$content,false));
 
//отправляем серверу
xmlrpc_send("http://example.com/wordpress/xmlrpc.php",$request);
?>

вроде все просто и понятно. Работает на данный момент только с кодировкой UTF-8. Собственно и затеялось как раз потому, что два предыдущих варианта напрочь отказывались нормально отправлять в UTF-8.

Реализованы не все типы, возможные в xmlrpc, однако мне для постинга в WordPress этого пока хватит, буде кому понадобится еще чего можете меня попинать — допишу, ну или сами, а я добавлю со ссылкой на автора 🙂

P.S. походу wordpress чудит с кавычками. файл исходника xmlrpc.phps

Опубликовал: