Do nhiều trao đổi thông tin của tôi với bạn bè và đồng nghiệp diễn ra trên e-mail, tôi đã trở nên quen với việc lưu trữ thông tin liên hệ trong ứng dụng sổ địa chỉ đi kèm với Mozilla Thunderbird, trình khách e-mail mặc định của tôi. Tuy nhiên, trong vài tháng gần đây, tôi đã dần dần chuyển thông tin lên Gmail, nó có kèm một sổ địa chỉ mạnh mẽ của riêng mình. Tính năng này, được biết với tên Google Contacts, rất dễ truy cập trên Web, nó hỗ trợ một lượng lớn các trường thông tin và có cả tính năng nhập khẩu và xuất khẩu. Điều này làm cho nó có khả năng không chỉ lưu trữ các dữ liệu toàn diện về các liên hệ, mà còn cho các thông tin liên hệ đó “du lịch” theo bạn từ nơi này đến nơi khác, vì bạn có thể truy cập nó từ bất kỳ máy tính nào có thể truy cập được Web.
Cả từ phối cảnh phát triển, Google Contacts cũng thật thú vị: Giống như nhiều sản phẩm Google khác, nó đưa ra một API Dữ liệu cho phép các nhà phát triển dễ dàng xây dựng các ứng dụng mới xoay quanh các dữ liệu lưu trong một sổ ghi địa chỉ riêng tư. API này, tuân theo mô hình REST, có thể truy cập được thông qua bất kỳ bộ công cụ phát triển có khả năng XML nào, và đã có sẵn từ trước các thư viện khách dành cho nhiều ngôn ngữ lập trình phổ biến... gồm cả thứ yêu thích của tôi là PHP.
Bài viết này sẽ giới thiệu nhập môn cho bạn về API dữ liệu của Google Contacts, và chỉ cho bạn cách tích hợp và sử dụng các dữ liệu liên hệ bằng một ứng dụng PHP tùy chỉnh. Trong các thí dụ, bạn sẽ lấy ra các địa chỉ liên hệ từ sổ địa chỉ của người dùng, bổ sung liên hệ mới, sửa đổi và xóa các liên hệ, và kiểm soát dữ liệu trả về trong một nguồn nạp liên hệ. Vì vậy, hãy đến, và chúng ta hãy bắt đầu!
Hiểu rõ API của Google Contacts
Trước khi bạn đào sâu vào mã PHP, cần nói vài lời về API dữ liệu của Google Contacts. Cũng như với các API dữ liệu của Google khác, hệ thống tiếp nhận các yêu cầu HTTP chứa một hoặc nhiều tham số đầu vào được mã hóa XML và trả về các nguồn nạp Atom chứa các thông tin được yêu cầu. Những nguồn nạp này sau đó có thể được phân tích cú pháp bằng bất kỳ ngôn ngữ lập trình nhận biết XML nào. Ngoài ra, các hoạt động HTTP chuẩn GET, POST, PUT và DELETE được ánh xạ thành các phương thức API lấy ra, thêm, cập nhật, và xóa các bản ghi tương ứng.
Một nguồn nạp Google Contacts thường chứa rất nhiều thông tin. Hãy xem xét thí dụ trong Liệt kê 1:
Liệt kê 1: Một nguồn nạp Google Contacts mẫu
<atom:feed xmlns:atom="http://www.w3.org/2005/Atom">
<atom:author>
<atom:name>John Doe</atom:name>
<atom:email>user@gmail.com</atom:email>
</atom:author>
<atom:category term="http://schemas.google.com/contact/2008#contact"
scheme="http://schemas.google.com/g/2005#kind"/>
<atom:id>user@gmail.com</atom:id>
<atom:link href="http://www.google.com/" rel="alternate" type="text/html"/>
<atom:link href="http://www.google.com/m8/feeds/contacts/user%40gmail.com/full"
rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
<atom:link href="http://www.google.com/m8/feeds/contacts/user%40gmail.com/full"
rel="http://schemas.google.com/g/2005#post" type="application/atom+xml"/>
<atom:link href="http://www.google.com/m8/feeds/contacts/user%40gmail.com/full/
batch" rel="http://schemas.google.com/g/2005#batch" type="application/atom+xml"/>
<atom:link href="http://www.google.com/m8/feeds/contacts/user%40gmail.com/full?
max-results=25" rel="self" type="application/atom+xml"/>
<atom:link href="http://www.google.com/m8/feeds/contacts/user%40gmail.com/full?
start-index=26&max-results=25" rel="next" type="application/atom+xml"/>
<atom:title type="text">John Doe's Contacts</atom:title>
<atom:updated>2009-08-31T10:48:00.410Z</atom:updated>
<atom:generator uri="http://www.google.com/m8/feeds" version="1.0">Contacts
</atom:generator>
<atom:entry xmlns:default="http://www.w3.org/2007/app"
xmlns:default1="http://schemas.google.com/g/2005"
xmlns:default2="http://schemas.google.com/contact/2008">
<default:edited xmlns="http://www.w3.org/2007/app">2009-08-22T16:52:37.457Z
</default:edited>
<default1:name xmlns="http://schemas.google.com/g/2005">
<default1:fullName>Vikram Vaswani</default1:fullName>
<default1:givenName>Vikram</default1:givenName>
<default1:familyName>Vaswani</default1:familyName>
</default1:name>
<default1:organization xmlns="http://schemas.google.com/g/2005"
rel="http://schemas.google.com/g/2005#work">
<default1:orgName>Melonfire</default1:orgName>
<default1:orgTitle>CEO</default1:orgTitle>
</default1:organization>
<default1:email xmlns="http://schemas.google.com/g/2005"
rel="http://schemas.google.com/g/2005#other" address="vikram@example.org"
primary="true"/>
<default1:email xmlns="http://schemas.google.com/g/2005"
rel="http://schemas.google.com/g/2005#home" address="vikram@example.com"/>
<default1:phoneNumber xmlns="http://schemas.google.com/g/2005"
rel="http://schemas.google.com/g/2005#mobile">0012345678901
</default1:phoneNumber>
<default1:phoneNumber xmlns="http://schemas.google.com/g/2005"
rel="http://schemas.google.com/g/2005#work_fax">0045678901234
</default1:phoneNumber>
<default2:website xmlns="http://schemas.google.com/contact/2008"
href="http://www.melonfire.com/" rel="home"/>
<default2:website xmlns="http://schemas.google.com/contact/2008"
href="http://www.php-beginners-guide.com/" rel="blog"/>
<default2:groupMembershipInfo xmlns="http://schemas.google.com/contact/2008"
deleted="false"
href="http://www.google.com/m8/feeds/groups/user%40gmail.com/base/6"/>
<atom:category term="http://schemas.google.com/contact/2008#contact"
scheme="http://schemas.google.com/g/2005#kind"/>
<atom:id>http://www.google.com/m8/feeds/contacts/user%40gmail.com/base/0
</atom:id>
<atom:link href="http://www.google.com/m8/feeds/photos/media/user%40gmail.com/0"
rel="http://schemas.google.com/contacts/2008/rel#photo" type="image/*"/>
<atom:link href="http://www.google.com/m8/feeds/contacts/user%40gmail.com/full/0"
rel="self" type="application/atom+xml"/>
<atom:link href="http://www.google.com/m8/feeds/contacts/user%40gmail.com/full/0"
rel="edit" type="application/atom+xml"/>
<atom:title type="text">Vikram Vaswani</atom:title>
<atom:updated>2009-08-22T16:52:37.457Z</atom:updated>
<atom:content type="text">PHP enthusiast</atom:content>
</atom:entry>
<atom:entry xmlns:default="http://www.w3.org/2007/app"
xmlns:default1="http://schemas.google.com/g/2005">
</atom:entry>
<openSearch:totalResults xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/"
>153</openSearch:totalResults>
<openSearch:startIndex xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/"
>1</openSearch:startIndex>
<openSearch:itemsPerPage xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/"
>25</openSearch:itemsPerPage>
</atom:feed>
|
Các nguồn nạp Contacts đều mở bằng một phần tử
<feed> như là phần tử gốc. Phần tử
<feed> chứa phần tử
<link>, trong đó chứa các URL của các
phiên bản khác nhau của nguồn nạp, và các phần tử
<openSearch:>, chứa các số liệu thống kê
tóm tắt.
Phần tử <feed> ngoài cùng có chứa một hoặc
nhiều phần tử <entry>, mỗi phần tử biểu
diễn một liên hệ đơn lẻ. Mỗi <entry> chứa
thông tin chi tiết hơn, gồm tên, tổ chức, tiêu đề, địa chỉ thư điện tử,
điện thoại và số fax, trang Web và ảnh của liên hệ (và các thứ khác nữa).
Mỗi <entry> cũng chứa hai phần tử
<link> nữa, là
<link
rel="self" ...> và
<link rel="edit" ...>, chứa các URL tương
ứng để lấy ra toàn bộ mục này và để biên tập mục này.
Điều quan trọng cần nhớ là các nguồn nạp Google Contacts có tính riêng tư. Điều này có nghĩa là bất kỳ hoạt động nào về dữ liệu chứa trong nguồn nạp — gồm cả việc chỉ xem nó — sẽ chỉ thành công nếu hoạt động đó được xác thực với tên người sử dụng và mật khẩu của chủ nguồn nạp bằng cách sử dụng một trong hai phương thức xác thực được Google phê duyệt: AuthSub hoặc ClientLogin.
Thực hiện kiểu xác thực này thủ công là một nhiệm vụ khá hỗn độn, và đòi hỏi nhiều mã lệnh để tính đến các kịch bản khác nhau có thể xuất hiện trong một giao dịch xác thực điển hình. Rất may là bạn không phải lo lắng quá nhiều về vấn đề này: Thư viện khách GData của Zend's® được thiết kế đặc biệt cho các nhà phát triển, những người tích hợp các ứng dụng PHP với API dữ liệu của Google, sẽ xử lý toàn bộ các chi tiết đó cho bạn. Thư viện này, mà bạn có thể tải về riêng lẻ (xem phần Tài nguyên để nhận được liên kết), cung cấp một giao diện hướng đối tượng thuận tiện dành cho API dữ liệu của Google, gói gọn hầu hết các nhiệm vụ thông thường (gồm cả việc xác thực), và để bạn tự do tập trung vào các chức năng cốt lõi của ứng dụng của bạn. Các thí dụ còn lại trong bài này sẽ tận dụng thư viện này, vì vậy phải đảm bảo rằng bạn đã cài đặt nó trước khi tiếp tục.
Sau khi bạn cài đặt xong thư viện GData của Zend, chúng ta hãy tiếp tục một thí dụ về việc xử lý một nguồn nạp dùng API dữ liệu của Google Contacts bằng cách sử dụng PHP. Liệt kê 2 lấy nguồn nạp từ Liệt kê 1 và sử dụng SimpleXML để trích xuất các đoạn dữ liệu liên quan từ nó và định dạng nó thành một trang Web:
Liệt kê 2: Lấy và hiển thị các liên hệ
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Listing contacts</title>
<style>
body {
font-family: Verdana;
}
div.name {
color: red;
text-decoration: none;
font-weight: bolder;
}
div.entry {
display: inline;
float: left;
width: 400px;
height: 150px;
border: 2px solid;
margin: 10px;
padding: 5px;
}
td {
vertical-align: top;
}
</style>
</head>
<body>
<?php
// load Zend Gdata libraries
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_Feed');
// set credentials for ClientLogin authentication
$user = "user@gmail.com";
$pass = "guessme";
try {
// perform login and set protocol version to 3.0
$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'cp');
$gdata = new Zend_Gdata($client);
$gdata->setMajorProtocolVersion(3);
// perform query and get result feed
$query = new Zend_Gdata_Query(
'http://www.google.com/m8/feeds/contacts/default/full');
$feed = $gdata->getFeed($query);
// display title and result count
?>
<h2><?php echo $feed->title; ?></h2>
<div>
<?php echo $feed->totalResults; ?> contact(s) found.
</div>
<?php
// parse feed and extract contact information
// into simpler objects
$results = array();
foreach($feed as $entry){
$xml = simplexml_load_string($entry->getXML());
$obj = new stdClass;
$obj->name = (string) $entry->title;
$obj->orgName = (string) $xml->organization->orgName;
$obj->orgTitle = (string) $xml->organization->orgTitle;
foreach ($xml->email as $e) {
$obj->emailAddress[] = (string) $e['address'];
}
foreach ($xml->phoneNumber as $p) {
$obj->phoneNumber[] = (string) $p;
}
foreach ($xml->website as $w) {
$obj->website[] = (string) $w['href'];
}
$results[] = $obj;
}
} catch (Exception $e) {
die('ERROR:' . $e->getMessage());
}
?>
<?php
// display results
foreach ($results as $r) {
?>
<div class="entry">
<div class="name"><?php echo (!empty($r->name)) ?
$r->name : 'Name not available'; ?></div>
<div class="data">
<table>
<tr>
<td>Organization</td>
<td><?php echo $r->orgName; ?></td>
</tr>
<tr>
<td>Email</td>
<td><?php echo @join(', ', $r->emailAddress); ?></td>
</tr>
<tr>
<td>Phone</td>
<td><?php echo @join(', ', $r->phoneNumber); ?></td>
</tr>
<tr>
<td>Web</td>
<td><?php echo @join(', ', $r->website); ?></td>
</tr>
</table>
</div>
</div>
<?php
}
?>
</body>
</html>
|
Hình 1 trình bày kết quả xuất ra mà bạn có thể nhìn thấy. Trong ảnh chụp màn hình, một số thông tin địa chỉ thư điện tử cá nhân được che khuất.
Hình 1. Một trang Web liệt kê các liên hệ
Đầu tiên Liệt kê 2 tải về các thư viện lớp Zend, và sau
đó khởi tạo một cá thể của lớp dịch vụ Zend_Gdata. Lớp này tận dụng một
đối tượng Zend_Http_Client, được cung cấp với thông tin xác thực người sử
dụng cần thiết và dùng để mở một kết nối được xác thực đến dịch vụ Google
Contacts. Khi một kết nối được xác thực đã mở, phương thức getFeed() lấy ra nguồn nạp các liên hệ. Phương
thức này nhận một đối tượng Zend_Gdata_Query, được chuyển qua URL nguồn
nạp. Cũng phải chú ý lệnh gọi setMajorProtocolVersion() trong Liệt kê 2,
nó báo cho máy chủ dùng v3.0 của API dữ liệu của Google Contacts ; đây là
một lệnh gọi bắt buộc phải có. Nếu bạn bỏ qua nó, bạn có thể thấy các hành
vi không được mong đợi.
Đáp ứng lệnh gọi API getFeed() là một nguồn nạp
XML tương tự như nguồn nạp trong Liệt kê 1, cái mà sau
đó được phân tích cú pháp và được chuyển đổi thành một đối tượng PHP. Các
mục bên trong nguồn nạp được biểu diễn như các phần tử mảng, làm cho ta có
thể lặp đi qua nguồn nạp này và lấy ra các mục liên hệ cá nhân. Do
SimpleXML cung cấp một cách dễ dàng hơn để lấy ra các mẩu tin cụ thể từ
một cây XML, phương thức
simplexml_load_string() được sử dụng để chuyển
đổi XML của từng mục thành một đối tượng SimpleXML. Các nút con dưới từng
<entry> sau đó được lấy ra và dàn phẳng
thành một đối tượng đơn giản hơn để lấy ra dễ dàng, và mỗi đối tượng thu
được sau đó được đặt vào mảng $results (kết
quả). Khi toàn bộ nguồn nạp được xử lý, bạn có thể dễ dàng lặp đi qua mảng
$results bằng một vòng lặp
foreach() và định dạng các nội dung để hiển thị
trong một trình duyệt Web.
Một vài lời ở đây về URL nguồn nạp chuyển đến đối tượng Zend_Gdata_Query:
nó được tạo ra bằng cách nối thêm tên người sử dụng và kiểu nguồn nạp vào
URL nguồn nạp chuẩn, trong
http://www.google.com/m8/feeds/contacts/USERID/TYPE. Các kiểu nguồn nạp có
hai biến thể, đầy đủ và mỏng, với kiểu thứ hai (kiểu mỏng) chỉ trả về một
tập con của toàn bộ các mục nhập. Và việc sử dụng từ khoá đặc biệt
default thay thế tên người sử dụng, như trong
Liệt kê 2, sẽ trả về nguồn nạp mặc định của người sử
dụng.
Đó là nói về liệt kê danh sách các liên hệ. Bây giờ bổ sung các liên hệ mới thì thế nào?
Điều này thực tế không phức tạp như đã hình dung. Để bổ sung một liên hệ
mới, chỉ cần POST (gửi lên) một khối
<entry> mới được mã hóa XML lên URL nguồn
nạp. Liệt kê 3 cho một thí dụ về một khối như vậy:
Liệt kê 3: Một mục Google Contacts mẫu
<?xml version="1.0"?>
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:gd="http://schemas.google.com/g/2005">
<gd:name>
<gd:fullName>Jack Frost</gd:fullName>
</gd:name>
<gd:email address="jack.frost@example.com"
rel="http://schemas.google.com/g/2005#home"/>
<gd:organization rel="http://schemas.google.com/g/2005#work">
<gd:orgName>Winter Inc.</gd:orgName>
</gd:organization>
</atom:entry>
|
Nếu bạn sử dụng thư viện Zend, mọi thứ thậm chí còn đơn giản hơn: tất cả
việc bạn cần làm chỉ là gọi phương thức
insertEntry(), nó tạo ra một yêu cầu POST và
truyền dữ liệu đến URL nguồn nạp. Liệt kê 4 có một thí
dụ:
Liệt kê 4: Bổ sung một liên hệ mới
<?php
// load Zend Gdata libraries
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_Feed');
// set credentials for ClientLogin authentication
$user = "user@gmail.com";
$pass = "guessme";
try {
// perform login and set protocol version to 3.0
$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'cp');
$gdata = new Zend_Gdata($client);
$gdata->setMajorProtocolVersion(3);
// create new entry
$doc = new DOMDocument();
$doc->formatOutput = true;
$entry = $doc->createElement('atom:entry');
$entry->setAttributeNS('http://www.w3.org/2000/xmlns/' ,
'xmlns:atom', 'http://www.w3.org/2005/Atom');
$entry->setAttributeNS('http://www.w3.org/2000/xmlns/' ,
'xmlns:gd', 'http://schemas.google.com/g/2005');
$doc->appendChild($entry);
// add name element
$name = $doc->createElement('gd:name');
$entry->appendChild($name);
$fullName = $doc->createElement('gd:fullName', 'Jack Frost');
$name->appendChild($fullName);
// add email element
$email = $doc->createElement('gd:email');
$email->setAttribute('address' ,'jack.frost@example.com');
$email->setAttribute('rel' ,'http://schemas.google.com/g/2005#home');
$entry->appendChild($email);
// add org name element
$org = $doc->createElement('gd:organization');
$org->setAttribute('rel' ,'http://schemas.google.com/g/2005#work');
$entry->appendChild($org);
$orgName = $doc->createElement('gd:orgName', 'Winter Inc.');
$org->appendChild($orgName);
// insert entry
$entryResult = $gdata->insertEntry($doc->saveXML(),
'http://www.google.com/m8/feeds/contacts/default/full');
echo '<h2>Add Contact</h2>';
echo 'The ID of the new entry is: ' . $entryResult->id;
} catch (Exception $e) {
die('ERROR:' . $e->getMessage());
}
?>
|
Liệt kê 4 mở một kết nối đã xác thực tới API dữ liệu của
Google Contacts bằng cách sử dụng đối tượng Zend_Gdata, như đã thấy trước
đó trong Liệt kê 2. Tiếp theo, phần mở rộng DOM trong
PHP xây dựng theo phương thức động một mục XML <entry> trong Liệt kê 3, và phương
thức insertEntry() được sử dụng để thực sự ghi
lưu XML thu được vào các máy chủ Google. Khi mục nhập được bổ sung, ta
ngay lập tức nhìn thấy được nó trong Google Contacts.
Chú ý là bạn có thể đánh dấu rõ ràng các địa chỉ e-mail và số điện thoại là
thuộc về “nhà riêng” (home), “nơi làm việc” (work), hoặc “di động”
(mobile) bằng cách xác định sơ đồ thích hợp trong phần tử <gd:organization rel="..."
/>.
Hình 2 minh họa kết quả xuất ra sau khi bổ sung thành công một mục liên hệ mới:
Hình 2. Kết quả xuất sau khi bạn bổ sung một liên hệ mới
Trong ảnh chụp màn hình ở Hình 2, có một số trường bị che khuất trong thông
báo xác nhận từ Google. Thông báo có định dạng: The ID
of the new entry is
http://www.google.com/m8/feeds/contacts/USER_ID/base/CONTACT_ID
(Mã nhận dạng của mục nhập mới là
http://www.google.com/m8/feeds/contacts/USER ID/base/CONTACT ID).
Và Hình 3 cho thấy nó trông như thế nào trong giao diện Google Contacts:
Hình 3. Liên hệ mới bổ sung trong Gmail
Các API dữ liệu của Google Contacts cũng cho phép bạn biên tập và xóa các
mục. Để xóa một mục, hãy gửi một yêu cầu DELETE tới URL biên tập của liên
hệ, đó là URL xác định trong phần tử
<link rel="edit" ...> của mục ấy. Trong
bối cảnh thư viện Zend, bạn đơn giản chỉ cần chuyển URL này đến phương
thức delete() của đối tượng Zend_Gdata, như
minh họa trong Liệt kê 5:
Liệt kê 5: Xóa một liên hệ
<?php
// load Zend Gdata libraries
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_Feed');
// set credentials for ClientLogin authentication
$user = "user@gmail.com";
$pass = "guessme";
// set ID of entry to delete
// from <link rel=edit>
$id = 'http://www.google.com/m8/feeds/contacts/default/base/29e98jf648c495c7b';
try {
// perform login and set protocol version to 3.0
$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'cp');
$client->setHeaders('If-Match: *');
$gdata = new Zend_Gdata($client);
$gdata->setMajorProtocolVersion(3);
// delete entry
$gdata->delete($id);
echo '<h2>Delete Contact</h2>';
echo 'Entry deleted';
} catch (Exception $e) {
die('ERROR:' . $e->getMessage());
}
?>
|
Để biên tập một mục, sử dụng phương thức
getEntry() để lấy ra mục đó bằng cách sử dụng
mã định danh duy nhất của nó, thay đổi các giá trị bạn muốn cập nhật. Sau
đó ghi lưu mục nhập vào máy chủ bằng phương thức
updateEntry() của đối tượng Zend_Gdata, nó gửi
một yêu cầu PUT (đặt) tới URL được xác định trong phần tử
<link rel="self" ...> của mục này. Liệt kê 6 minh họa quá trình này, thiết lập một tên và
địa chỉ thư điện tử mới cho một mục liên hệ:
Liệt kê 6: Sửa đổi một liên hệ
<?php
// load Zend Gdata libraries
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_Feed');
// set credentials for ClientLogin authentication
$user = "user@gmail.com";
$pass = "guessme";
// set ID of entry to update
// from <link rel=self>
$id = 'http://www.google.com/m8/feeds/contacts/default/full/0';
try {
// perform login and set protocol version to 3.0
$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'cp');
$client->setHeaders('If-Match: *');
$gdata = new Zend_Gdata($client);
$gdata->setMajorProtocolVersion(3);
// perform query and get entry
$query = new Zend_Gdata_Query($id);
$entry = $gdata->getEntry($query);
$xml = simplexml_load_string($entry->getXML());
// change name
$xml->name->fullName = 'John Rabbit';
// change primary email address
foreach ($xml->email as $email) {
if (isset($email['primary'])) {
$email['address'] = 'jr@example.com';
}
}
// update entry
$entryResult = $gdata->updateEntry($xml->saveXML(),
$entry->getEditLink()->href);
echo 'Entry updated';
} catch (Exception $e) {
die('ERROR:' . $e->getMessage());
}
?>
|
Chú ý là cả Liệt kê 5 và Liệt kê 6 đều thêm vào một tiêu đề bổ sung “If-Match” như một phần của yêu cầu HTTP. Tiêu đề này là đặc biệt có ích trong một môi trường nhiều trình khách (multi-client), vì nó có thể được sử dụng để xóa hoặc cập nhật một mục nếu nó chưa bị thay đổi từ khi được đọc lần cuối. Bộ tài liệu hướng dẫn cho các nhà phát triển về API dữ liệu của Google Contacts (xem phần Tài nguyên để nhận được liên kết) bàn luận về tiêu đề này chi tiết hơn.
API dữ liệu của Google Contacts cũng hỗ trợ một số tham số bổ sung mà bạn có thể sử dụng để kiểm soát nguồn nạp kết quả. Sau đây là một danh sách:
- Tham số
start-index(chỉ mục bắt đầu) xác định khoảng dịch chuyển khởi đầu (start offset) đối với nguồn nạp - Tham số
max-resultsxác định số lượng (tối đa) các mục trong nguồn nạp - Các tham số
orderbyvàsortorderxác định cách sắp xếp các mục nguồn nạp - Tham số
showdeletedgồm thêm các mục bị xóa trong 30 ngày gần nhất vào nguồn nạp
Nếu bạn sử dụng thư viện khách Zend, bạn có thể đặt nhiều tham số chỉ đơn
giản bằng cách thiết lập thuộc tính tương ứng của đối tượng
Zend_Gdata_Query. Đối với các tham số riêng cho dịch vụ, đối tượng
Zend_Gdata_Query cũng cung cấp một phương thức
setParam(). Cả hai kỹ thuật này được minh họa
trong Liệt kê 7, nó giới hạn tập kết quả gồm 10 mục, xếp
theo thứ tự giảm dần của ngày sửa đổi cuối cùng của chúng.
Liệt kê 7: Đặt các tham số truy vấn bổ sung
<?php
// load Zend Gdata libraries
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_Feed');
// set credentials for ClientLogin authentication
$user = "user@gmail.com";
$pass = "guessme";
try {
// perform login and set protocol version to 3.0
$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'cp');
$gdata = new Zend_Gdata($client);
$gdata->setMajorProtocolVersion(3);
// perform query and get result feed
$query = new Zend_Gdata_Query(
'http://www.google.com/m8/feeds/contacts/default/full');
$query->maxResults = 10;
$query->setParam('orderby', 'lastmodified');
$query->setParam('sortorder', 'descending');
$feed = $gdata->getFeed($query);
// display title and result count
// snip...
} catch (Exception $e) {
die('ERROR:' . $e->getMessage());
}
?>
|
Bây giờ bạn đã biết cách API dữ liệu của Google Contacts làm việc như thế nào, bạn có thể thử xây dựng một ứng dụng PHP đơn giản cho phép nhập các liên hệ và thao tác chúng. Ứng dụng dùng thử này có 3 kịch bản lệnh (xem phần Tải về để nhận một tập tin nén):
- contacts-index.php liệt kê các mục liên hệ và cung cấp các liên kết để bổ sung và xóa các mục.
- contacts-save.php hiển thị một biểu mẫu để bổ sung một mục mới, và xử lý phần gửi lên.
- contacts-delete.php xóa một mục đã xác định.
Bắt đầu với kịch bản lệnh đầu tiên và cập nhật Liệt kê 1 bằng một số liên kết bổ sung, như trong Liệt kê 8:
Liệt kê 8: Lấy và hiển thị các liên hệ
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Listing contacts</title>
<style>
body {
font-family: Verdana;
}
div.name {
color: red;
text-decoration: none;
font-weight: bolder;
}
div.entry {
display: inline;
float: left;
width: 450px;
height: 150px;
border: 2px solid;
margin: 10px;
padding: 5px;
}
td {
vertical-align: top;
}
span.links {
float: right;
}
</style>
</head>
<body>
<h2>Contacts</h2>
<?php
// load Zend Gdata libraries
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_Feed');
// set credentials for ClientLogin authentication
$user = "user@gmail.com";
$pass = "guessme";
try {
// perform login and set protocol version to 3.0
$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'cp');
$gdata = new Zend_Gdata($client);
$gdata->setMajorProtocolVersion(3);
// perform query and get feed of all results
$query = new Zend_Gdata_Query(
'http://www.google.com/m8/feeds/contacts/default/full');
$query->maxResults = 0;
$query->setParam('orderby', 'lastmodified');
$query->setParam('sortorder', 'descending');
$feed = $gdata->getFeed($query);
// display number of results
?>
<h2><?php echo $feed->title; ?></h2>
<div>
<?php echo $feed->totalResults; ?> contact(s) found.
</div>
<?php
// parse feed and extract contact information
// into simpler objects
$results = array();
foreach($feed as $entry){
$obj = new stdClass;
$obj->edit = $entry->getEditLink()->href;
$xml = simplexml_load_string($entry->getXML());
$obj->name = (string) $entry->title;
$obj->orgName = (string) $xml->organization->orgName;
$obj->orgTitle = (string) $xml->organization->orgTitle;
foreach ($xml->email as $e) {
$obj->emailAddress[] = (string) $e['address'];
}
foreach ($xml->phoneNumber as $p) {
$obj->phoneNumber[] = (string) $p;
}
foreach ($xml->website as $w) {
$obj->website[] = (string) $w['href'];
}
$results[] = $obj;
}
} catch (Exception $e) {
die('ERROR:' . $e->getMessage());
}
?>
<div>
<a href="contacts-save.php">Add a new contact</a>
</div>
<?php
// display results
foreach ($results as $r) {
?>
<div class="entry">
<div class="name"><?php echo (!empty($r->name))
? $r->name : 'Name not available'; ?>
<span class="links"><a href="contacts-delete.php?
id=<?php echo $r->edit; ?>">Delete</a></span>
</div>
<div class="data">
<table>
<tr>
<td>Organization:</td>
<td><?php echo $r->orgName; ?></td>
</tr>
<tr>
<td>Email:</td>
<td><?php echo @join(', ', $r->emailAddress); ?></td>
</tr>
<tr>
<td>Phone:</td>
<td><?php echo @join(', ', $r->phoneNumber); ?></td>
</tr>
<tr>
<td>Web:</td>
<td><?php echo @join(', ', $r->website); ?></td>
</tr>
</table>
</div>
</div>
<?php
}
?>
</body>
</html>
|
Hình 4 minh họa kết quả xuất ra đã sửa đổi.
Hình 4. Một trang Web liệt kê các liên hệ, với các chức năng bổ sung và xóa
Bạn sẽ thấy từ Hình 4, là bây giờ có thêm một liên kết Delete (xoá) cạnh mỗi mục. Liên kết này gồm có mã nhận dạng mục nhập (entry ID), nó được chuyển đến đích liên kết như là một tham số GET. Kịch bản lệnh đích đọc mã nhận dạng này và xóa nó bằng cách sử dụng kỹ thuật vạch ra trong Liệt kê 5. Liệt kê 9 cho thấy mã lệnh đó trông như thế nào:
Liệt kê 9: Xóa các liên hệ
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Deleting contacts</title>
</head>
<body>
<h2>Delete Contact</h2>
<?php
// load Zend Gdata libraries
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_Feed');
// set credentials for ClientLogin authentication
$user = "user@gmail.com";
$pass = "guessme";
if (empty($_GET['id'])) {
die('ERROR: Missing ID');
}
try {
// perform login and set protocol version to 3.0
$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'cp');
// set GData delete headers
$client->setHeaders('If-Match: *');
$gdata = new Zend_Gdata($client);
$gdata->setMajorProtocolVersion(3);
// delete entry
$gdata->delete($_GET['id']);
echo 'Entry deleted';
} catch (Exception $e) {
die('ERROR:' . $e->getMessage());
}
?>
</body>
</html>
|
Đó là nói về liệt kê và gỡ bỏ các mục. Nhưng bổ sung chúng thì thế nào? Liệt kê 10 đưa ra một kịch bản lệnh khác cho phép người sử dụng bổ sung các liên hệ mới thông qua một biểu mẫu Web. Sau đó nó sử dụng thư viện Zend để xây dựng nên các gói POST tương ứng và lưu dữ liệu vào máy chủ:
Liệt kê 10: Bổ sung các liên hệ mới
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Adding new contacts</title>
<style>
body {
font-family: Verdana;
}
</style>
</head>
<body>
<h2>Add Contact</h2>
<?php if (!isset($_POST['submit'])) { ?>
<form method="post"
action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>">
Name: <br/>
<input name="name" type="text" size="15" /><p/>
Email address(es): <br/>
<textarea name="email" type="text"></textarea><p/>
Organization: <br/>
<input name="org" type="text" size="15" /><p/>
<input name="submit" type="submit" value="Save" />
</form>
<?php
} else {
// check for required input
if (empty($_POST['name'])) {
die('ERROR: Missing name');
}
if (empty($_POST['email'])) {
die('ERROR: Missing email address');
}
if (empty($_POST['org'])) {
die('ERROR: Missing organization');
}
// sanitize input and save to array
$inputData['name'] = htmlentities($_POST['name']);
$inputData['email'] = htmlentities($_POST['email']);
$inputData['org'] = htmlentities($_POST['org']);
// load Zend Gdata libraries
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_Feed');
// set credentials for ClientLogin authentication
$user = "user@gmail.com";
$pass = "guessme";
try {
// perform login and set protocol version to 3.0
$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'cp');
$gdata = new Zend_Gdata($client);
$gdata->setMajorProtocolVersion(3);
// create new entry
$doc = new DOMDocument();
$doc->formatOutput = true;
$entry = $doc->createElement('atom:entry');
$entry->setAttributeNS('http://www.w3.org/2000/xmlns/' ,
'xmlns:atom', 'http://www.w3.org/2005/Atom');
$entry->setAttributeNS('http://www.w3.org/2000/xmlns/' ,
'xmlns:gd', 'http://schemas.google.com/g/2005');
$doc->appendChild($entry);
// add name element
$name = $doc->createElement('gd:name');
$entry->appendChild($name);
$fullName = $doc->createElement('gd:fullName', $inputData['name']);
$name->appendChild($fullName);
// add email elements
$arr = explode(',', $inputData['email']);
foreach ($arr as $a) {
$email = $doc->createElement('gd:email');
$email->setAttribute('address', $a);
$email->setAttribute('rel' ,'http://schemas.google.com/g/2005#work');
$entry->appendChild($email);
}
// add org name element
$org = $doc->createElement('gd:organization');
$org->setAttribute('rel' ,'http://schemas.google.com/g/2005#work');
$entry->appendChild($org);
$orgName = $doc->createElement('gd:orgName', $inputData['org']);
$org->appendChild($orgName);
// insert entry
$entryResult = $gdata->insertEntry($doc->saveXML(),
'http://www.google.com/m8/feeds/contacts/default/full');
echo 'The ID of the new entry is: ' . $entryResult->id;
} catch (Exception $e) {
die('ERROR:' . $e->getMessage());
}
}
?>
</body>
</html>
|
Liệt kê 10 thực tế gồm có hai phần: một biểu mẫu Web, và mã PHP xử lý đầu vào được nộp qua biểu mẫu này. Hình 5 minh họa biểu mẫu này trông như thế nào.
Hình 5. Một biểu mẫu Web để bổ sung một liên hệ mới
Khi người sử dụng gõ nhập tên, địa chỉ thư điện tử, và tổ chức của một liên hệ vào biểu mẫu này và gửi nó đi, nửa thứ hai của kịch bản lệnh xoay chuyển thành hành động. Đầu tiên, một khách HTTP được khởi tạo và dùng để mở một kết nối đã được xác thực đến API dữ liệu của Google Contacts. Tiếp theo, dữ liệu đầu vào đã nhập trong biểu mẫu Web được xác nhận hợp lệ, và một đối tượng DOMDocument mới được khởi tạo để nắm giữ dữ liệu dành cho mục nhập mới.
Các phương thức DOM trong PHP sau đó xây dựng theo phương thức động một
<entry>, mới, và phương thức
insertEntry() ghi lưu thực sự mục nhập vào các
máy chủ Google. Khi mục đó được bổ sung, API sẽ trả về mã nhận dạng duy
nhất của nó, và sẽ hiển thị cho người sử dụng để chứng tỏ một hoạt động
thành công.
Hình 6 minh họa kết quả xuất ra sau khi bổ sung thành công một mục mới.
Hình 6. Kết quả xuất sau khi bổ sung một liên hệ mới
Trong hình chụp màn hình ở Hình 6, một số trường bị giấu
đi trong thông báo xác nhận từ Google. Thông báo ở định dạng:
The ID of the new entry
is http://www.google.com/m8/feeds/contacts/USER_ID/base/CONTACT_ID.
Trong bài này, bạn đã qua một bài học về cách làm thế nào tích hợp dữ liệu từ API dữ liệu của Google Contacts vào một ứng dụng PHP bằng cách sử dụng một kết hợp giữa SimpleXML và thư viện khách Zend. Các thí dụ trong bài này đã giới thiệu cho bạn biết về định dạng nguồn nạp Google Contacts; chỉ cho bạn cách lấy ra các liệt kê liên hệ; bổ sung, sửa đổi, và xoá các liên hệ; và xây dựng nên một giao diện tùy chỉnh với dữ liệu thông tin liên hệ lưu trữ trong một Tài khoản Google của người sử dụng.
Như các thí dụ này minh họa, API dữ liệu của Google Contacts là một công cụ mạnh mẽ và linh hoạt cho các nhà phát triển tìm kiếm cách xây dựng nên các ứng dụng mới có tính sáng tạo về quản trị liên hệ. Hãy thỉnh thoảng đến với nó, và xem những gì bạn nghĩ!
| Mô tả | Tên | Kích thước | Phương thức tải |
|---|---|---|---|
| Archive of the final code example | contacts-example-app.zip | 4KB | HTTP |
Học tập
- Tài liệu Hướng dẫn cho các Nhà Phát triển và Hướng dẫn Tham khảo: Tìm hiểu thêm về API dữ liệu của Google
Contacts.
- Sổ tay
hướng dẫn Khung làm việc Zend: Xem xét kỹ hơn về các lớp Gdata của
Zend.
- Diễn đàn
chính thức về API dữ liệu của Google Contacts: Bàn luận về phát
triển Google Contacts.
- Blog của API dữ liệu của
Google: Đọc các tin tức về API Google.
- Tìm hiểu về phát triển ứng dụng với các
sản phẩm Google khác, bao gồm YouTube, Picasa, và Google Notebook:
- Sử dụng API YouTube với PHP (Vikram Vaswani, developerWorks, 04/2008): Xử lý và tích hợp dữ liệu từ YouTube vào ứng dụng PHP của bạn với phần mở rộng SimpleXML trong PHP.
- Phát triển các ứng dụng PHP với Albums Web Picasa (Vikram Vaswani, developerWorks, 09/2008): Tích hợp dữ liệu từ Picasa Web Albums vào một ứng dụng PHP tùy chỉnh.
- Xử lý và tích hợp dữ liệu Google Notebook với PHP (Vikram Vaswani, developerWorks, 05/2008): Sử dụng API REST của Google Notebook để xây dựng các ứng dụng khách dựa trên PHP.
- Chứng nhận XML
của IBM: Tìm ra cách làm thế nào để bạn có thể trở thành một Nhà
phát triển được IBM chứng nhận về XML và các công nghệ liên
quan.
- Thư viện kỹ thuật XML: Xem vùng XML của developerWorks để có
nhiều bài viết và mách nước về kỹ thuật, các hướng dẫn, tiêu chuẩn, và các
Sách đỏ của IBM..
- Các sự kiện và phát tin kỹ thuật
của developerWorks: Theo sát công nghệ trong các phiên
này.
-
Hiệu sách công nghệ: Duyệt tìm các sách về chủ đề này và các chủ
đề kỹ thuật khác.
- Các bài phát thanh trên mạng của
developerWorks: Nghe các bài phỏng vấn và thảo luận thú vị dành
cho các nhà phát triển phần mềm.
Lấy sản phẩm và công nghệ
- Thư viện Gdata của
Zend: Tải về mọi thứ bạn cần để truy cập các API dữ liệu của
Google từ ứng dụng PHP 5 của bạn.
-
Các phiên bản đánh giá sản phẩm
của IBM: Tải về hoặc khám phá dùng thử trực tuyến trong
Sandbox SOA của IBM và bắt tay thực hành các công cụ phát triển
ứng dụng và các sản phẩm phần giữa từ DB2®, Lotus®,
Rational®, Tivoli®, và WebSphere®.
Thảo luận
- Các diễn đàn thảo luận vùng XML: Tham gia vào bất kỳ cuộc thảo
luận nào liên quan đến XML.
- Các blog của developerWorks:
Xem các blog này và tham gia vào cộng đồng
developerWorks.