พฤศจิกายน 2007
วัตถุประสงค์
เว็บนี้เต็มไปด้วยชุมชนที่เน้นภูมิศาสตร์ และความสนใจ กล่าวคือ ผู้ที่ชอบพิพิธภัณฑ์ อาสนวิหารยุโรป สวนสาธารณะของรัฐ ฯลฯ ระบบนักพัฒนาซอฟต์แวร์ (เช่นคุณ) จึงมีความจําเป็นในการสร้างระบบที่ผู้ใช้สามารถร่วมให้ข้อมูลเกี่ยวกับตําแหน่งทางภูมิศาสตร์ลงในแผนที่ได้ และนี่คือสิ่งที่เราทําที่นี่ ในส่วนท้ายของบทความนี้ คุณจะมีระบบที่ผู้ใช้สามารถลงทะเบียน เข้าสู่ระบบ และเพิ่มสถานที่ที่ติดแท็กทางภูมิศาสตร์ได้ ระบบจะใช้ AJAX สําหรับส่วนหน้า, PHP สําหรับการเขียนสคริปต์ฝั่งเซิร์ฟเวอร์ และสเปรดชีต Google สําหรับพื้นที่เก็บข้อมูล หากคุณคุ้นเคยกับการใช้ฐานข้อมูล MySQL สําหรับพื้นที่เก็บข้อมูล ก็แก้ไขโค้ดได้ง่ายๆ ที่นี่เพื่อใช้แบ็กเอนด์ของฐานข้อมูล MySQL แทน
บทความนี้แบ่งเป็นขั้นตอนต่อไปนี้
- การตั้งค่าสเปรดชีต
- การทํางานกับเฟรมเวิร์ก Zend Gdata
- การสร้างฟังก์ชันส่วนกลาง
- การลงทะเบียนผู้ใช้ใหม่
- การเข้าสู่ระบบเป็นผู้ใช้
- การอนุญาตให้ผู้ใช้เพิ่มสถานที่ในแผนที่
- การสร้างแผนที่
- สรุป
การตั้งค่าสเปรดชีต
เราจะใช้ Google สเปรดชีตเพื่อจัดเก็บข้อมูลทั้งหมดสําหรับระบบนี้ ข้อมูลที่เราต้องจัดเก็บมี 2 ประเภท ได้แก่ ข้อมูลบัญชีผู้ใช้และสถานที่ที่ผู้ใช้เพิ่ม ดังนั้นเราจะสร้างเวิร์กชีต 1 ไฟล์สําหรับข้อมูลแต่ละประเภท เราจะโต้ตอบกับเวิร์กชีตโดยใช้ฟีดข้อมูลซึ่งต้องอาศัยแถวแรกในเวิร์กชีตที่มีป้ายกํากับคอลัมน์ และแต่ละแถวต่อมาที่มีข้อมูล
ไปที่ docs.google.com แล้วสร้างสเปรดชีตใหม่ เปลี่ยนชื่อเวิร์กชีตเริ่มต้นเป็น "ผู้ใช้" และสร้างคอลัมน์ชื่อ "ผู้ใช้" "รหัสผ่าน" และ "เซสชัน" จากนั้นเพิ่มชีตใหม่ เปลี่ยนชื่อเป็น "สถานที่ตั้ง" และสร้างคอลัมน์ชื่อ "ผู้ใช้" "สถานะ" "ลาติน" "lng" และ "วันที่" หรือหากคุณรู้สึกว่าการทํางานด้วยตนเองไม่ที่จําเป็น ให้ดาวน์โหลดเทมเพลตนี้แล้วนําเข้าไปยัง Google สเปรดชีตผ่านคําสั่ง File->Import
ข้อมูลบัญชีผู้ใช้จะต้องเก็บไว้เป็นส่วนตัว (ปรากฏเฉพาะกับเจ้าของสเปรดชีต) ส่วนสถานที่ที่ผู้ใช้เพิ่มจะแสดงบนแผนที่ที่เปิดเผยต่อสาธารณะ แต่โชคดีที่ Google สเปรดชีตอนุญาตให้คุณเลือกเวิร์กชีตในสเปรดชีตเป็นแบบสาธารณะ และสเปรดชีตที่ควรจะเป็นแบบส่วนตัว (ค่าเริ่มต้น) หากต้องการเผยแพร่เวิร์กชีต "ตําแหน่ง" ให้คลิกแท็บ "เผยแพร่เลย" เลือกช่องทําเครื่องหมาย "เผยแพร่อีกครั้งโดยอัตโนมัติ" จากนั้นเลือกช่อง "ส่วนใด" ในเมนูแบบเลื่อนลง "เฉพาะส่วนใด" ตัวเลือกที่ถูกต้องจะแสดงในภาพหน้าจอด้านล่าง

การทํางานกับ Zend GData Framework
Googleสเปรดชีต API มีอินเทอร์เฟซ HTTP สําหรับการดําเนินการ CRUD เช่น การดึงข้อมูลแถว การแทรกแถว การอัปเดตแถว และลบแถว Zend Framework มี Wrapper ของ PHP ที่ด้านบนสุดของ API (และ GData API อื่นๆ) เพื่อให้คุณไม่ต้องกังวลเรื่องการใช้การดําเนินการ HTTP ดิบ Zend Framework ต้องใช้ PHP 5
ดาวน์โหลดเฟรมเวิร์ก Zend แล้วอัปโหลดไปยังเซิร์ฟเวอร์ของคุณหากยังไม่มี ดูกรอบงานได้ที่นี่ http://framework.zend.com/download/gdata
คุณควรแก้ไข PHPinclude_path ให้รวมไลบรารี Zend การดําเนินการดังกล่าวทําได้หลายวิธี โดยขึ้นอยู่กับระดับสิทธิ์ของการดูแลระบบที่คุณมีในเซิร์ฟเวอร์ วิธีหนึ่งคือการเพิ่มบรรทัดนี้เหนือคําสั่งที่ต้องระบุในไฟล์ PHP ใดก็ตามโดยใช้ไลบรารีนี้
ini_set("include_path", ".:/usr/lib/php:/usr/local/lib/php:../../../library/");
หากต้องการทดสอบ ให้เรียกใช้การสาธิตสเปรดชีตด้วยการป้อนการสาธิตที่บรรทัดคําสั่งในโฟลเดอร์เดโม/Zend/Gdata
php Spreadsheet-ClientLogin.php --user=YourGMailUsername --pass=YourPassword
หากทํางานได้ คุณจะเห็นรายการสเปรดชีตที่แสดง หากได้รับข้อผิดพลาด ให้ตรวจสอบว่าคุณตั้งค่าเส้นทางรวมอย่างถูกต้อง และได้ติดตั้ง PHP 5 แล้ว
การสร้างฟังก์ชันส่วนกลาง
สคริปต์ PHP ทั้งหมดที่เราจะเขียนสําหรับแผนที่ชุมชนจะใช้การรวม ตัวแปร และการทํางานที่พบได้ทั่วไปซึ่งเราจะใส่ไว้ในไฟล์เดียว
ที่จุดเริ่มต้นของไฟล์ เราจะมีคําสั่งที่จําเป็นให้รวมและโหลดไลบรารี Zend ซึ่งนํามาจากตัวอย่างสเปรดชีต-ClientLogin.php
จากนั้นเราจะกําหนดค่าคงที่ที่จะใช้ทั่วไฟล์ ได้แก่ คีย์สเปรดชีตและรหัสเวิร์กชีต 2 รายการ หากต้องการดูข้อมูลในสเปรดชีต ให้เปิดข้อมูลนั้น แล้วคลิก "แท็บเผยแพร่" แล้วคลิก "ตัวเลือกการเผยแพร่เพิ่มเติม" เลือก "ATOM" จากรายการเมนูแบบเลื่อนลงของรูปแบบไฟล์ แล้วคลิก "สร้าง URL" คุณจะเห็นข้อมูลดังนี้
http://spreadsheets.google.com/feeds/list/o16162288751915453340.4016005092390554215/od6/public/basic
คีย์สเปรดชีตคือสตริงที่เป็นตัวอักษรและตัวเลขคละกันแบบยาวหลัง "/list/" และรหัสเวิร์กชีตเป็นสตริงยาว 3 อักขระหลังจากนั้น หากต้องการค้นหารหัสเวิร์กชีตอื่น ให้เลือกชีตอื่นจากเมนูแบบเลื่อนลง "ชีตใด"
จากนั้นเราจะสร้างฟังก์ชัน 3 อย่าง ได้แก่ setupClient, getWkshtListFeed และ PrintFeed ใน setupClient เราจะตั้งค่าชื่อผู้ใช้และรหัสผ่าน GMail ของเรา ตรวจสอบสิทธิ์ด้วย ClientLogin และแสดงออบเจ็กต์ Zend_Gdata_spreadsheets ใน getWkshtListFeed เราจะแสดงฟีดรายการสเปรดชีตสําหรับคีย์สเปรดชีตและรหัสเวิร์กชีตที่ระบุ พร้อมการค้นหาสเปรดชีต (ลิงก์) ที่ไม่บังคับ ฟังก์ชัน PrintFeed จะนํามาจากตัวอย่างสเปรดชีต-ClientLogin.php และอาจเป็นประโยชน์ในการแก้ไขข้อบกพร่อง ซึ่งจะอยู่ในออบเจ็กต์ฟีดแล้วพิมพ์ลงในหน้าจอ
PHP ที่แสดงด้านล่างนี้ (communitymap_globals.php):
<?php ini_set("include_path", ".:/usr/lib/php:/usr/local/lib/php:../../../library/"); require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata'); Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); Zend_Loader::loadClass('Zend_Gdata_Spreadsheets'); Zend_Loader::loadClass('Zend_Http_Client'); define("SPREADSHEET_KEY", "o16162288751915453340.4016005092390554215"); define("USER_WORKSHEET_ID", "od6"); define("LOC_WORKSHEET_ID", "od7"); function setupClient() { $email = "your.name@gmail.com"; $password = "yourPassword"; $client = Zend_Gdata_ClientLogin::getHttpClient($email, $password, Zend_Gdata_Spreadsheets::AUTH_SERVICE_NAME); $gdClient = new Zend_Gdata_Spreadsheets($client); return $gdClient; } function getWkshtListFeed($gdClient, $ssKey, $wkshtId, $queryString=null) { $query = new Zend_Gdata_Spreadsheets_ListQuery(); $query->setSpreadsheetKey($ssKey); $query->setWorksheetId($wkshtId); if ($queryString !== null) { $query->setSpreadsheetQuery($queryString); } $listFeed = $gdClient->getListFeed($query); return $listFeed; } function printFeed($feed) { print "printing feed"; $i = 0; foreach($feed->entries as $entry) { if ($entry instanceof Zend_Gdata_Spreadsheets_CellEntry) { print $entry->title->text .' '. $entry->content->text . "\n"; } else if ($entry instanceof Zend_Gdata_Spreadsheets_ListEntry) { print $i .' '. $entry->title->text .' '. $entry->content->text . "\n"; } else { print $i .' '. $entry->title->text . "\n"; } $i++; } } ?>
การลงทะเบียนผู้ใช้ใหม่
ในการลงทะเบียนผู้ใช้ใหม่ เราจําเป็นต้องมีหน้า HTML ที่ผู้ใช้เห็นพร้อมช่องข้อความและปุ่มส่ง และสคริปต์แบ็กเอนด์ PHP ที่จะเพิ่มผู้ใช้ในสเปรดชีต
ในสคริปต์ PHP เราจะใส่สคริปต์ส่วนกลางก่อน จากนั้นจะได้รับชื่อผู้ใช้และรหัสผ่านจากตัวแปร GET จากนั้นเราจะตั้งค่าไคลเอ็นต์สเปรดชีต และขอฟีดข้อมูลรายการเวิร์กชีตของผู้ใช้ด้วยสตริงการค้นหาเพื่อจํากัดผลลัพธ์ไว้เฉพาะแถวที่มีคอลัมน์ชื่อผู้ใช้เท่ากับชื่อผู้ใช้ที่ส่งเข้ามาในสคริปต์ หากไม่พบแถวในผลการค้นหาฟีด เราสามารถดําเนินการต่อได้อย่างปลอดภัยที่จะทราบว่าชื่อผู้ใช้ที่ส่งมานั้นไม่ซ้ํากัน ก่อนแทรกแถวในฟีดรายการ เราจะสร้างอาร์เรย์ที่เชื่อมโยงของค่าคอลัมน์ ได้แก่ ชื่อผู้ใช้ การเข้ารหัสของรหัสผ่านโดยใช้ฟังก์ชัน sha1 ของ PHP และอักขระตัวเติมสําหรับเซสชัน จากนั้น เราจะเรียกแทรกแถวในไคลเอ็นต์สเปรดชีต โดยส่งผ่านในอาร์เรย์การเชื่อมโยง คีย์สเปรดชีต และรหัสเวิร์กชีต หากออบเจ็กต์ที่แสดงผลคือ ListFeedEntry เราจะส่งข้อความ Success!
PHP ที่แสดงด้านล่างนี้ (communitymap_newuser.php):
<?php require_once 'communitymap_globals.php'; $username = $_GET['username']; $password = $_GET['password']; $gdClient = setupClient(); $listFeed = getWkshtListFeed($gdClient, SPREADSHEET_KEY, USER_WORKSHEET_ID, ('user='.$username)); $totalResults = $listFeed->totalResults; if ( $totalResults != "0") { // Username already exists exit; } $rowArray["user"] = $username; $rowArray["password"] = sha1($password); $rowArray["session"] = "a"; $entry = $gdClient->insertRow($rowArray, SPREADSHEET_KEY, USER_WORKSHEET_ID); if ($entry instanceof Zend_Gdata_Spreadsheets_ListEntry) { echo "Success!"; } ?>
ในหน้าการลงทะเบียน เราจะสามารถรวม Maps API เพื่อให้เราสามารถใช้ฟังก์ชัน Wrapper XMLHttpRequest ที่เรียกว่า GDownloadUrl ได้ เมื่อผู้ใช้คลิกปุ่มส่ง เราจะขอชื่อผู้ใช้และรหัสผ่านจากช่องข้อความ สร้างสตริงพารามิเตอร์จากค่า และเรียกใช้ GDownloadUrl ใน URL และพารามิเตอร์ของสคริปต์ เนื่องจากเรากําลังส่งข้อมูลที่ละเอียดอ่อน เราจึงใช้ GDownloadUrl เวอร์ชัน HTTP POST (โดยส่งพารามิเตอร์เป็นอาร์กิวเมนต์ที่ 3 แทนการเพิ่ม URL เหล่านั้น) ในฟังก์ชันเรียกกลับ เราจะตรวจหาการตอบกลับที่สําเร็จและส่งข้อความที่เหมาะสมให้กับผู้ใช้
ภาพหน้าจอและโค้ดจะแสดงอยู่ด้านล่างสําหรับตัวอย่างการลงทะเบียน (communitymap_register.htm)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title> Community Map - Register/Login </title> <script src="http://maps.google.com/maps?file=api&v=2&key=abcdef" type="text/javascript"></script> <script type="text/javascript"> function register() { var username = document.getElementById("username").value; var password = document.getElementById("password").value; var url = "communitymap_newuser.php?"; var params = "username=" + username + "&password=" + password; GDownloadUrl(url, function(data, responseCode) { if (data.length > 1) { document.getElementById("message").innerHTML = "Successfully registered." + "<a href='communitymap_login.htm'>Proceed to Login</a>."; } else { document.getElementById("message").innerHTML = "Username already exists. Try again."; } }, params); } </script> </head> <body> <h1>Register for Community Map</h1> <input type="text" id="username"> <input type="password" id="password"> <input type="button" onclick="register()" value="Register"> <div id="message"></div> </body> </html>
การเข้าสู่ระบบเป็นผู้ใช้
หากต้องการให้ผู้ใช้ลงชื่อเข้าใช้ระบบของเรา เรากําหนดให้หน้า HTML ที่แสดงต่อผู้ใช้แสดงข้อความให้ป้อนชื่อผู้ใช้และรหัสผ่าน และใช้สคริปต์ PHP เพื่อยืนยันข้อมูลการเข้าสู่ระบบ สร้างรหัสเซสชัน และกลับไปที่หน้าเข้าสู่ระบบเพื่อตั้งค่าคุกกี้ ผู้ใช้จะลงชื่อเข้าสู่ระบบผ่านคุกกี้ของเซสชันในหน้าต่อไป
ในสคริปต์ PHP เราจะใส่สคริปต์ส่วนกลางก่อน จากนั้นจะได้รับชื่อผู้ใช้และรหัสผ่านจากตัวแปร GET จากนั้นเราจะตั้งค่าไคลเอ็นต์สเปรดชีต และขอฟีดข้อมูลรายการเวิร์กชีตของผู้ใช้ด้วยสตริงการค้นหาเพื่อจํากัดผลลัพธ์ไว้เฉพาะแถวที่มีคอลัมน์ชื่อผู้ใช้เท่ากับชื่อผู้ใช้ที่ส่งเข้ามาในสคริปต์
ในแถวที่แสดงผล เราจะตรวจสอบว่าแฮชของรหัสผ่านที่ส่งไปนั้นตรงกับแฮชที่เก็บไว้ในสเปรดชีต หากใช่ เราจะสร้างรหัสเซสชันโดยใช้ฟังก์ชัน md5, uniqid และ rand จากนั้นเราจะอัปเดตแถวในสเปรดชีตด้วยเซสชัน และแสดงผลลัพธ์ไปยังหน้าจอหากการอัปเดตแถวสําเร็จ
PHP ที่แสดงด้านล่างนี้ (communitymap_loginuser.php)
<?php require_once 'communitymap_globals.php'; $username = $_POST['username']; $password = $_POST['password']; $gdClient = setupClient(); $listFeed = getWkshtListFeed($gdClient, SPREADSHEET_KEY, USER_WORKSHEET_ID, ('user='.$username)); $password_hash = sha1($password); $row = $listFeed->entries[0]; $rowData = $row->getCustom(); foreach($rowData as $customEntry) { if ($customEntry->getColumnName()=="password" && $customEntry->getText()==$password_hash) { $updatedRowArray["user"] = $username; $updatedRowArray["password"] = sha1($password); $updatedRowArray["session"] = md5(uniqid(rand(), true)); $updatedRow = $gdClient->updateRow($row, $updatedRowArray); if ($updatedRow instanceof Zend_Gdata_Spreadsheets_ListEntry) { echo $updatedRowArray["session"]; } } } ?>
ในหน้าการเข้าสู่ระบบ เราสามารถรวม Maps API อีกครั้งเพื่อให้เราสามารถใช้ฟังก์ชัน XMLHttpRequest Wrapper ที่เรียกว่า GDownloadUrl ได้ เมื่อผู้ใช้คลิกปุ่มส่ง เราจะขอชื่อผู้ใช้และรหัสผ่านจากช่องข้อความ สร้าง URL สคริปต์ที่มีพารามิเตอร์การค้นหา และเรียกใช้ GDownloadUrl ใน URL ของสคริปต์ ในฟังก์ชันเรียกกลับ เราจะตั้งค่าคุกกี้ที่มีรหัสเซสชันที่แสดงผลโดยสคริปต์ หรือแสดงผลลัพธ์ข้อความแสดงข้อผิดพลาดหากไม่มีการส่งคืน ฟังก์ชัน setCookie มาจาก cookie.js ที่อิงตามบทแนะนํา JavaScript ของ w3c: http://www.w3schools.com/js/js_cookies.asp
ภาพหน้าจอและโค้ดจะแสดงด้านล่างสําหรับหน้าการเข้าสู่ระบบตัวอย่าง (communitymap_login.htm)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Community Map - Login</title> <script src="http://maps.google.com/maps?file=api&v=2&key=abcdef" type="text/javascript"></script> <script src="cookies.js" type="text/javascript"></script> <script type="text/javascript"> function login() { var username = document.getElementById("username").value; var password = document.getElementById("password").value; var url = "communitymap_loginuser.php?username=" + username + "&password=" + password; GDownloadUrl(url, function(data, responseCode) { if (data.length > 1) { setCookie("session", data, 5); } else { document.getElementById("nessage").innerHTML = "Error. Try again."; } }); } </script> </head> <body> <h1>Login for Community Map</h1> <input type="text" id="username"> <input type="password" id="password"> <input type="button" onclick="login()" value="Login"> <div id="message"></div> </body> </html>
การอนุญาตให้ผู้ใช้เพิ่มสถานที่ในแผนที่
เพื่อให้ผู้ใช้สามารถเพิ่มสถานที่ลงในแผนที่ของเรา เราต้องการหน้า HTML ที่แสดงต่อผู้ใช้ เพื่อบอกข้อมูลเกี่ยวกับตําแหน่งและสคริปต์ PHP 2 สคริปต์ และอีกชุดหนึ่งเพื่อตรวจสอบว่าผู้ใช้เหล่านั้นเข้าสู่ระบบผ่านคุกกี้ที่เราตั้งค่า และอีกหน้าหนึ่งเพื่อเพิ่มตําแหน่งลงในเวิร์กชีตของสถานที่
ในสคริปต์ PHP แรกที่ตรวจสอบว่าผู้ใช้เข้าสู่ระบบก่อน เราจะใส่สคริปต์ร่วมนั้นก่อน แล้วจะได้รับค่าเซสชันจากตัวแปร GET จากนั้น เราจะตั้งค่าไคลเอ็นต์สเปรดชีตและขอฟีดข้อมูลรายการเวิร์กชีตของผู้ใช้ด้วยสตริงการค้นหา เพื่อจํากัดผลลัพธ์เฉพาะแถวที่มีคอลัมน์เซสชันเท่ากับค่าเซสชันที่ส่งไปยังสคริปต์ จากนั้น เราจะทําซ้ํารายการที่กําหนดเองของฟีดนั้น (รายการที่ตรงกับส่วนหัวของคอลัมน์) และพิมพ์ชื่อผู้ใช้ที่เกี่ยวข้องสําหรับเซสชันนั้น (หากมี)
PHP ที่แสดงด้านล่างนี้ (communitymap_checksession.php)
<?php require_once 'communitymap_globals.php'; $session = $_GET['session']; $gdClient = setupClient(); $listFeed = getWkshtListFeed($gdClient, SPREADSHEET_KEY, USER_WORKSHEET_ID, ('session='.$session)); if ( count($listFeed->entries) > 0) { $row = $listFeed->entries[0]; $rowData = $row->getCustom(); foreach($rowData as $customEntry) { if ($customEntry->getColumnName()=="user") { echo $customEntry->getText(); } } } ?>
เราจะคัดลอกโค้ดจาก Communitymap_checksession.php ในสคริปต์ PHP ที่ 2 ที่ช่วยให้ผู้ใช้เพิ่มตําแหน่งได้ เพื่อตรวจสอบว่าผู้ใช้ยังลงชื่อเข้าสู่ระบบและถูกต้อง จากนั้นเมื่อเราได้รับชื่อผู้ใช้ที่ถูกต้องจากชีตผู้ใช้ คุณจะได้รับค่าสถานที่ แลต และ lng จากตัวแปร GET เราใส่ค่าเหล่านั้นทั้งหมดลงในอาร์เรย์การเชื่อมโยง และเรายังเพิ่มค่า "date" โดยใช้ฟังก์ชัน date() ของ PHP เพื่อให้ผู้ใช้ทราบเมื่อผู้ใช้เพิ่มสถานที่ เราส่งอาร์เรย์การเชื่อมโยง ค่าคงที่ของสเปรดชีต และรหัสเวิร์กชีตสําหรับค่าคงที่ของตําแหน่ง ลงในฟังก์ชันแทรกแถว จากนั้นเราจะแสดงผลลัพธ์ "สําเร็จ" หากมีการเพิ่มแถวสําหรับสถานที่ตั้งใหม่ลงในสเปรดชีต หากคุณได้รับข้อผิดพลาดในขั้นตอนนี้ อาจเป็นเพราะชื่อส่วนหัวของคอลัมน์ไม่ตรงกัน คีย์ในอาร์เรย์การเชื่อมโยงต้องตรงกับส่วนหัวคอลัมน์ในเวิร์กชีตที่ระบุโดยคีย์สเปรดชีตและรหัสเวิร์กชีต
PHP ที่แสดงด้านล่างนี้ (communitymap_addlocation.php)
<?php require_once 'communitymap_globals.php'; $session = $_GET['session']; $gdClient = setupClient(); $listFeed = getWkshtListFeed($gdClient, SPREADSHEET_KEY, USER_WORKSHEET_ID, ('session='.$session)); if ( count($listFeed->entries) > 0) { $row = $listFeed->entries[0]; $rowData = $row->getCustom(); foreach($rowData as $customEntry) { if ($customEntry->getColumnName()=="user") { $user = $customEntry->getText(); } } $place = $_GET['place']; $lat = $_GET['lat']; $lng = $_GET['lng']; $rowArray["user"] = $user; $rowArray["place"] = $place; $rowArray["lat"] = $lat; $rowArray["lng"] = $lng; $rowArray["date"] = date("F j, Y, g:i a"); $entry = $gdClient->insertRow($rowArray, SPREADSHEET_KEY, LOC_WORKSHEET_ID); if ($entry instanceof Zend_Gdata_Spreadsheets_ListEntry) { echo "Success!\n"; } } ?>
ในหน้าเพิ่มสถานที่ตั้ง เราสามารถรวม Maps API เพื่อให้เราใช้ GDownloadUrl และสร้างแผนที่ได้ หลังจากโหลดหน้าเว็บแล้ว เราใช้ฟังก์ชัน getCookie จาก cookie.js เพื่อดึงค่าเซสชัน หากสตริงเซสชันเป็นค่าว่างหรือว่างเปล่า เราจะแสดงข้อความแสดงข้อผิดพลาด หากไม่ได้เชื่อมโยง เราจะเรียกใช้ GDownloadUrl ใน map.checksession.php ซึ่งเป็นการส่งในเซสชัน หากวิธีนี้แสดงชื่อผู้ใช้สําเร็จ เราจะแสดงข้อความต้อนรับแก่ผู้ใช้ แสดงแบบฟอร์มสถานที่ และโหลดแผนที่ แบบฟอร์มนี้ประกอบด้วยช่องข้อความที่อยู่ แผนที่ และช่องข้อความสําหรับชื่อสถานที่ ละติจูด และลองจิจูด หากผู้ใช้ไม่ทราบละติจูด/ลองจิจูดของสถานที่ ก็สามารถใส่พิกัดทางภูมิศาสตร์ได้โดยป้อนที่อยู่ของตนในแบบฟอร์มแล้วกด "ส่ง" โดยระบบจะส่งการเรียกไปยัง GClientGeocoder ของ Maps API ซึ่งจะวางเครื่องหมายบนแผนที่หากพบที่อยู่ และป้อนข้อมูลช่องข้อความละติน/อัตโนมัติโดยอัตโนมัติ
เมื่อผู้ใช้พอใจ ก็สามารถกดปุ่ม "เพิ่มสถานที่ตั้ง" ได้ จากนั้นใน JavaScript เราจะเผยแพร่ค่าสําหรับผู้ใช้ สถานที่ แลต และ lng แล้วส่งค่าเหล่านี้ไปยังสคริปต์ Communitymap_addlocation.php ด้วย GDownloadUrl
หากสคริปต์ดังกล่าวส่งคืนสําเร็จ เราจะแสดงข้อความความสําเร็จไปยังหน้าจอ
ภาพหน้าจอและโค้ดจะแสดงตัวอย่างด้านล่างสําหรับหน้าเพิ่มสถานที่ตั้ง (communitymap_addlocation.htm)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> <title>Community Map - Add a Place!</title> <script src="http://maps.google.com/maps?file=api&v=2.x&key=abcdef" type="text/javascript"></script> <script src="cookies.js" type="text/javascript"></script> <script type="text/javascript"> //<![CDATA[ var map = null; var geocoder = null; var session = null; function load() { session = getCookie('session'); if (session != null && session != "") { url = "communitymap_checksession.php?session=" + session; GDownloadUrl(url, function(data, responseCode) { if (data.length > 0) { document.getElementById("message").innerHTML = "Welcome " + data; document.getElementById("content").style.display = "block"; map = new GMap2(document.getElementById("map")); map.setCenter(new GLatLng(37.4419, -122.1419), 13); geocoder = new GClientGeocoder(); } }); } else { document.getElementById("message").innerHTML = "Error: Not logged in."; } } function addLocation() { var place = document.getElementById("place").value; var lat = document.getElementById("lat").value; var lng = document.getElementById("lng").value; var url = "communitymap_addlocation.php?session=" + session + "&place=" + place + "&lat=" + lat + "&lng=" + lng; GDownloadUrl(url, function(data, responseCode) { GLog.write(data); if (data.length > 0) { document.getElementById("message").innerHTML = "Location added."; } }); } function showAddress(address) { if (geocoder) { geocoder.getLatLng( address, function(point) { if (!point) { alert(address + " not found"); } else { map.setCenter(point, 13); var marker = new GMarker(point, {draggable:true}); document.getElementById("lat").value = marker.getPoint().lat().toFixed(6); document.getElementById("lng").value = marker.getPoint().lng().toFixed(6); map.addOverlay(marker); GEvent.addListener(marker, "dragend", function() { document.getElementById("lat").value = marker.getPoint().lat().toFixed(6); document.getElementById("lng").value = marker.getPoint().lng().toFixed(6); }); } } ); } } //]]> </script> </head> <body onload="load()" onunload="GUnload()"> <div id="message"></div> <div id="content" style="display:none"> <form action="#" onsubmit="showAddress(this.address.value); return false"> <p> <input type="text" size="60" name="address" value="1600 Amphitheatre Pky, Mountain View, CA" /> <input type="submit" value="Geocode!" /> </form> </p> <div id="map" style="width: 500px; height: 300px"></div> Place name: <input type="text" size="20" id="place" value="" /> <br/> Lat: <input type="text" size="20" id="lat" value="" /> <br/> Lng: <input type="text" size="20" id="lng" value="" /> <br/> <input type="button" onclick="addLocation()" value="Add a location" /> </form> </div> </body> </html>
การสร้างแผนที่
เนื่องจากคุณทําให้เวิร์กชีตดังกล่าวเป็นแบบสาธารณะในขั้นตอนแรก จึงไม่ต้องมีการเขียนโปรแกรมฝั่งเซิร์ฟเวอร์เพื่อสร้างแผนที่ จริงๆ แล้ว ไม่จําเป็นต้องเขียนโปรแกรมเลย คุณสามารถใช้สเปรดชีต -> วิซาร์ดแผนที่นี้ แล้วจะสร้างโค้ดทั้งหมดที่จําเป็นสําหรับแผนที่ขึ้นมา วิซาร์ดจะดาวน์โหลดรายการเวิร์กชีตในหน้าเว็บโดยต่อท้ายแท็กสคริปต์ที่ชี้ไปยังเอาต์พุต JSON สําหรับฟีด และระบุฟังก์ชันเรียกกลับที่มีการเรียกเมื่อ JSON ดาวน์โหลดแล้ว ดูข้อมูลเพิ่มเติมได้ที่นี่
ดูตัวอย่างโค้ด HTML สําหรับการดําเนินการดังกล่าวได้ที่นี่ mainmap.htm ภาพหน้าจอแสดงอยู่ด้านล่าง

บทสรุป
เราหวังว่าคุณจะมีระบบแผนที่ที่ผู้ใช้ร่วมให้ข้อมูลของคุณเองซึ่งทํางานอยู่บนเซิร์ฟเวอร์ของคุณ บทความนี้จะให้โค้ดที่จําเป็นอย่างยิ่งสําหรับแง่มุมที่สําคัญของระบบนี้ แต่เมื่อคุณคุ้นเคยกับไลบรารีสเปรดชีต Zend แล้ว คุณควรจะขยายระบบให้สอดคล้องกับความต้องการเฉพาะของคุณได้ หากคุณพบข้อผิดพลาดระหว่างทาง คุณสามารถใช้คําสั่ง echo
ใน PHP หรือ GLog.write()
ของ Map API ใน JavaScript เพื่อแก้ไขข้อบกพร่อง รวมทั้งสามารถโพสต์ในฟอรัมนักพัฒนาซอฟต์แวร์ Maps API หรือ spreadsheets API ได้ทุกเมื่อเพื่อขอความช่วยเหลือเพิ่มเติม