XML-RPC and XML-RPC Server 類別
CI 的 XML-RPC 類別可以讓你對其它 XML-RPC server 發出請求或是設定你自己的 XML-RPC server 來接收他人的請求
什麼是 XML-RPC?
簡單來說就是二台電腦在網路上透過 XML 來相互通訊,一台叫作 client,一台叫作 server,client 端發出 XML-RPC 的請求給 server 端,server 端在接收到請求並處理完畢後會再發出回應來告知 client 端
想知道更詳細的資料請上 XML-RPC 網站
初始化類別
就像大多數在 CI 中的類別一樣,在控制器中初始化 XML-RPC 與 XML-RPCS 類別使用 $this->load->library 函數:
$this->load->library('xmlrpc');
載入之後可以這樣使用: $this->xmlrpc
$this->load->library('xmlrpcs');
載入之後可以這樣使用: $this->xmlrpcs
注意: 當時用 XML-RPC Server 類別時,你必須同時載入 XML-RPC 與 XML-RPC Server 類別
發送 XML-RPC 請求
發送 XML-RPC 請求時你必須具體指定以下資訊:
- server 的位址
- 在 server 上你想要呼叫的方法(method)
- 請求的內容
底下是一個簡易的範例,從 Weblogs.com 發送的 ping 的請求到 Ping-o-Matic
$this->load->library('xmlrpc');
$this->xmlrpc->server('http://rpc.pingomatic.com/',80);
$this->xmlrpc->method('weblogUpdates.ping');
$request = array('My Photoblog','http://www.my-site.com/photoblog/');
$this->xmlrpc->request($request);
if ( ! $this->xmlrpc->send_request())
{
echo $this->xmlrpc->display_error();
}
說明
以上的程式碼初始化 XML-RPC 類別後設定 server 位址與呼叫的方法(weblogUpdates.ping),請求的內容放在陣列內透過 request() 函數編繹,最後在完整的發出請求後如果 send_request() 的回傳值為 False 則顯示從 server 所回傳的錯誤訊息
解析請求的內容
發送到 server 的請求是一個非常簡單的結構,在這個結構中的每個資料都是代表一個參數,以上述的例子來說這個請求包含了二個參數:位址(URL)與標題(title),當 server 接收到請求後它將會開始解析這些參數
請求的參數必須是放置陣列中傳送,並且每個參數的型態可以是字串、數字、日期...等,如果你的參數型態不是字串,則必須在陣列中指明底下的範例是一個簡單的參數陣列:
$request = array('John','Doe','www.some-site.com');
$this->xmlrpc->request($request);
如果你的參數型態不是字串或是你有好幾種不同的參數型態,你必須指明它們的型態並且放置在各自的陣列中,範例如下:
$request = array (
array('John','string'),
array('Doe','string'),
array(FALSE,'boolean'),
array(12345,'int')
);
$this->xmlrpc->request($request);
資料型態
建立 XML-RPC server
server 就像是個交通警察,等待接踵而來的請求並且導引它們到適當的函數中。
建立 server 必須在控制器中初始化 XML-RPC Server 類別,並且設定陣列來導引各個請求到適當的函數中
以下範例說明:
$this->load->library('xmlrpc');
$this->load->library('xmlrpcs');
$config['functions']['new_post'] = array('function' => 'My_blog.new_entry'),
$config['functions']['update_post'] = array('function' => 'My_blog.update_entry');
$config['object'] = $this;
$this->xmlrpcs->initialize($config);
$this->xmlrpcs->serve();
在以上的範例陣列中,具體的指明二個 server 所允許使用的方法,左邊的陣列代表允許使用的方法,當接收到請求時將會映對到右邊陣列所指定的函數中
'object' key is a special key that you pass an instantiated class object with,which is necessary when the method you are mapping to is not part of the CodeIgniter super object.
如範例所示,假如 client 發送請求並且指定使用 new_post 方法時,server 將載入 My_blog 類別並且呼叫 new_entry 函數,假如請求是指定使用 update_post 方法時,server 將載入 My_blog 類別並且呼叫 update_entry 函數
在 server 的函數名稱並無限制,你可以自行決定,假如你使用標準化的 API 例如: Blogger 或 MetaWeblog API ,你將會使用它們的函數名稱
此外,在初始化 XML-RPC Server 類別時有二個配置你或許會用到: debug 可以設定為 TRUE 來開啟除錯模式, xss_clean 設定為 FALSE 避免在傳送資料時會經過 Security 類別的 xss_clean 函數
處理請求
server 透過物件的方式來處理請求,在以上的範例中,當 new_post 這個函數被需求時,預期會出現以下的模型:
class My_blog extends CI_Controller {
function new_post($request)
{
}
}
$request 這個變數是個由 server 編譯過的物件,它包含了從 client 所發出的請求,使用這個物件你將有權利存取請求的變數並且處理它,當一切都處理完畢後將會發送回應告知 client
以下真實的範例,使用 Blogger API 中的 getUserInfo() 函數,client 將會向 server 傳送 username 與 password ,server 將會回傳特定使用者的資料(暱稱,使用者ID,電子信箱..等):
class My_blog extends CI_Controller {
function getUserInfo($request)
{
$username = 'smitty';
$password = 'secretsmittypass';
$this->load->library('xmlrpc');
$parameters = $request->output_parameters();
if ($parameters['1'] != $username AND $parameters['2'] != $password)
{
return $this->xmlrpc->send_error_message('100', 'Invalid Access');
}
$response = array(array('nickname' => array('Smitty','string'),
'userid' => array('99','string'),
'url' => array('http://yoursite.com','string'),
'email' => array('jsmith@yoursite.com','string'),
'lastname' => array('Smith','string'),
'firstname' => array('John','string')
),
'struct');
return $this->xmlrpc->send_response($response);
}
}
注意:
output_parameters() 函數取得了從 client 發送並且已經編成索引的陣列,在上述的範例中輸出參數為: username 與 password
假如 username 與 password 是無效的,則 send_error_message() 將會回傳錯誤訊息
反之,若為有效的,則會回傳使用者資訊
回應的格式
與請求相同,回應必須為陣列,但差別在於回應的陣列只容納單一項目,這個項目可以是一個多維陣列,但是只能有一個主要的索引,底下為一個基本的模型:
$response = array('Response data', 'array');
然而,一般來說回應通常都是包含多樣的資訊,為了達成這樣的目的,我們必須把回應資訊放在陣列中:
$response = array (
array(
'first_name' => array('John','string'),
'last_name' => array('Doe','string'),
'member_id' => array(123435,'int'),
'todo_list' => array(array('clean house','call mom','water plants'),'array'),
),
'struct'
);
上述的陣列被編排成 結構,對於回應來說,這是一個很常見的資料型態
就像請求一樣,回應的的資料型態可以是以下的資料型態
傳送含有錯誤訊息的回應
如果你需要在回應中含有錯誤訊息,可以參考以下範例:
return $this->xmlrpc->send_error_message('123','Requested data not available');
第一個參數為錯誤代碼,第二個參數為錯誤訊息
建立你自己的 client 與 server
為了幫助你了解,我們建立了一對控制器來做為 client 端與 server 端,你可以從 client 發出請求,並且接收到回應
Client 端
使用文字編輯器建立一個控制器叫作 xmlrpc_client.php,並且輸入以下的程式碼後儲存到 applications/controllers/ 資料夾:
注意: 在上述的範例中我們使用 "url helper",你可以在 補助函數(Helper Functions) 找到更詳細的資訊.
Server 端
使用文字編輯器建立一個控制器叫作 xmlrpc_server.php,並且輸入以下的程式碼後儲存到 applications/controllers/ 資料夾:
試試看!
現在就造訪你的網站,並且使用相似的路徑:
example.com/index.php/xmlrpc_client/
你現在感該可以看見你發送到 server 的訊息,並且接收到回應
你在 client 中發送("How's is going?")的訊息到 server 中,並且請求使用"Greetings"這個方法來處理,最後傳回了一個回應
在請求的參數中使用關連式陣列
如果你想在請求的參數中加入關聯式陣列,你需要使用 'struct' 資料型態:
$request = array(
array(
// Param 0
array(
'name'=>'John'
),
'struct'
),
array(
// Param 1
array(
'size'=>'large',
'shape'=>'round'
),
'struct'
)
);
$this->xmlrpc->request($request);
當請求經過 server 處理後你可以重新得到關聯式陣列
$parameters = $request->output_parameters();
$name = $parameters['0']['name'];
$size = $parameters['1']['size'];
$size = $parameters['1']['shape'];
函數參考
$this->xmlrpc->server()
設定 server 的位址與 port number:
$this->xmlrpc->server('http://www.sometimes.com/pings.php',80);
$this->xmlrpc->timeout()
設定請求的逾時時間(秒):
$this->xmlrpc->timeout(6);
$this->xmlrpc->method()
設定 server 將會被呼叫到的方法:
$this->xmlrpc->method('method');
method 是指有一個函數叫作 method
$this->xmlrpc->request()
將帶有資料的陣列建立成請求:
$request = array(array('My Photoblog','string'),'http://www.yoursite.com/photoblog/');
$this->xmlrpc->request($request);
$this->xmlrpc->send_request()
發送請求的函數,回傳 TURE 或 FALSE 來代表成功或失敗
$this->xmlrpc->set_debug(TRUE);
開啟除錯,它將會顯示各種資訊以及錯誤資訊來幫助除錯
$this->xmlrpc->display_error()
如果你的請求由於某些原因發生失敗時,將會回傳錯誤訊息
echo $this->xmlrpc->display_error();
$this->xmlrpc->display_response()
當 server 接收到請求時將會發送回應告知 client,回應是一個關聯式陣列
$this->xmlrpc->display_response();
$this->xmlrpc->send_error_message()
從 server 發送錯誤訊息到 client ,第一個參數是錯誤代碼,第二個參數為錯誤訊息
return $this->xmlrpc->send_error_message('123','Requested data not available');
$this->xmlrpc->send_response()
server 發送回應給 client。陣列的資料必須透過這個方法來傳送
$response = array(
array(
'flerror' => array(FALSE,'boolean'),
'message' => "Thanks for the ping!"
)
'struct');
return $this->xmlrpc->send_response($response);
資料型態
XML-RPC spec 以下有七種型態的資料可以透過 XML-RPC 來傳送:
- int or i4
- boolean
- string
- double
- dateTime.iso8601
- base64
- struct (contains array of values)
- array (contains array of values)