Viblo CTF
+10

Tạo một RESTful API đơn giản với PHP và MySQL

Tớ là một mobile dev. Việc một mobile dev muốn viết 1 backend cho riêng mình không phải điều gì quá mới mẻ, nhưng đó là với những bạn đã làm, trong khi còn đâu đó những anh em muốn được bắt tay vào làm 1 backend kết hợp với frontend(mobile app) của chính anh em. Như tiêu đều, bài hôm nay tớ sẽ giới thiệu cho các bạn cách xây dựng 1 backend đơn giản với PHP và MySQL.

Mô hình phổ biến hiện nay là các tác vụ,chức năng,lưu trữ,xử lý,đa nhiệm… sẽ được đưa toàn bộ lên Cloud – Server. Nghĩa là ứng dụng của bạn viết ra để làm cầu nối (đúng theo cả nghĩa đen và nghĩa bóng) vô cùng tuyệt vời giữa Cloud – Server và End Users. Kiểu kiểu như này:

Hôm nay tớ sẽ chia sẻ chút về 3 cái cục www màu xanh và vô số cục đên xì có gắn mác Server Stack.

Như ở trên tớ đã nói về nhiệm vụ của Server rồi,giờ sẽ chỉ nói về Webservice(có thể gọi là backend) – thao tác với Database server,xử lý các tác vụ mà client mobile gửi đến rồi sau đó phản hồi lại dưới dạng các cấu trúc NoSQL như JSON,BJSON hay XML. Ở đây tớ lựa chọn ngôn ngữ PHP vì những lý do sau:

– Dễ tiếp cận.

– Dễ hiểu cho những bạn newbie như tớ. Còn về performance hay multi-tasks thì có lẽ Node.js là sự lựa chọn tối ưu?

Bắt đầu với việc chạy một PHP page trên server thật thì trước mắt cần run-test loop trên server giả lập(localhost) cái đã. Có rất nhiều tools cho phép bạn làm điều này, ví dụ như trên window có:

Wamp Server - XAMPP

Cái tớ đang sử dụng là AMPPS đang chạy trên nền tảng MacOS. Link tải và introduction ở đây: http://www.ampps.com

Về configuration thì cũng khá đơn giản, bạn cần đưa toàn bộ source vào thư mục: /Applications/AMPPS/www Xong xuôi thì các bạn chạy ứng dụng: Tiếp theo click vào nút Start bên Apache để kích hoạt localhost và nút Start bên MySQL để kích hoạt db server nhé. Sau khi đã start thì các bạn vào trình duyệt và gõ http://localhost sẽ list ra toàn bộ thư mục của bạn đã được giả lập như nằm trên server như này: Tớ tạo 1 thư mục có tên là testExample,trong đó tớ tạo tiếp 1 sub folder với tên là config và sau cùng là 1 PHP file với tên là systemConfig.php. File này có nhiệm vụ mở cổng giao tiếp với MySQL và định nghĩa các HTTP statu codes trả về khi bạn thao tác với server (link tham khảo về chúng đây: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes)

OK,cứ tạm thời tạo ra thư mục và file như vậy.Giờ là lên xem MySQL server thế nào đã. Với các bạn đã có kinh nghiệm lập trình web thì chẳng xa lạ gì nữa rồi. Các bạn gõ lên trình duyệt link: http://localhost/phpmyadmin

Các bạn sẽ thao tác trên đó để tạo DB,tạo bảng,insert dữ liệu, sử dụng SQL statements để truy vấn…blah,blah, những cái này chắc khỏi cần guide nữa. Ảnh trên tớ tạo 1 db tên là xxx, 1 table đơn giản cũng tên xxx với 2 trường đơn giản gồm: image_id (lưu id,tự động tăng) và image_url(lưu url của image lấy từ trên Google về). Viết 1 câu lệnh SQL statement đơn giản: Select * from xxx thì nó trả ra như này: OK, giờ viết code nào 🙂

PHP vs MySQL

Các bạn vẫn nhớ file systemConfig.php tớ vừa tạo chứ?? Tớ tạo 1 class với 1 biến dbConnect như sau:

<?php

class systemConfig {
var $dbConnect;

}

>

Tiếp theo là viết các hàm contructor và distructor ( cả 2 đều optional nhé)

function __construct(){

}

function __destruct() {
$this->dbConnect->close();
}

function connectDB(){
$this->dbConnect = new mysqli(‘localhost’, ‘root’, ‘mysql’, ‘xxx’);
if($this->dbConnect->connect_errno){
return null; 
}else{
return $this->dbConnect;
}
}

Viết tiếp 1 function có tên connectDB() để kết nối đến database với các thông số:

‘localhost’: tên IP cần trỏ đến, ở đây chính là localhost.

‘root’, ‘mysql’: user và pass try cập vào MySQL (default của php myAdmin).

‘xxx’: tên database bạn tạo.

Next, viết hàm định nghĩa HTTP status codes với tham số truyền vào là status code,đầu ra là status description:

function getStatusCodeMeeage($status){
$codes = Array(
100 => ‘Continue’,
101 => ‘Switching Protocols’,
200 => ‘OK’,
201 => ‘Created’,
202 => ‘Accepted’,
203 => ‘Non-Authoritative Information’,
204 => ‘No Content’,
205 => ‘Reset Content’,
206 => ‘Partial Content’,
300 => ‘Multiple Choices’,
301 => ‘Moved Permanently’,
302 => ‘Found’,
303 => ‘See Other’,
304 => ‘Not Modified’,
305 => ‘Use Proxy’,
306 => ‘(Unused)’,
307 => ‘Temporary Redirect’,
400 => ‘Bad Request’,
401 => ‘Unauthorized’,
402 => ‘Payment Required’,
403 => ‘Forbidden’,
404 => ‘Not Found’,
405 => ‘Method Not Allowed’,
406 => ‘Not Acceptable’,
407 => ‘Proxy Authentication Required’,
408 => ‘Request Timeout’,
409 => ‘Conflict’,
410 => ‘Gone’,
411 => ‘Length Required’,
412 => ‘Precondition Failed’,
413 => ‘Request Entity Too Large’,
414 => ‘Request-URI Too Long’,
415 => ‘Unsupported Media Type’,
416 => ‘Requested Range Not Satisfiable’,
417 => ‘Expectation Failed’,
500 => ‘Internal Server Error’,
501 => ‘Not Implemented’,
502 => ‘Bad Gateway’,
503 => ‘Service Unavailable’,
504 => ‘Gateway Timeout’,
505 => ‘HTTP Version Not Supported’
);

return (isset($codes[$status])) ? $codes[$status] : ”;
}

Hàm trả về response khi client request:

function sendResponse($status = 200, $body = ”, $content_type = ‘text/html’)
{
$status_header = ‘HTTP/1.1 ‘ . $status . ‘ ‘ . $this->getStatusCodeMeeage($status);
header($status_header);
header(‘Content-type: ‘ . $content_type);
echo $body;
}

Vậy là xong việc configuration,bước tiếp theo là viết code để thao tác thực sự với db. Tớ viết thêm 1 class có tên là imageResourcesDAO.php,class có nhiệm vụ lấy ra các bản ghi ở table xxx trong db và trả ra dưới dạng JSON:

<?php

include(“../testExample/config/systemConfig.php”);
class imageResources {
private $dbReference;
var $dbConnect;
var $result;

/**
*
*/
function __construct(){

}

function __destruct(){

}

//get images
function getAllImageResource(){
$this->dbReference = new systemConfig();
$this->dbConnect = $this->dbReference->connectDB();
if ($this->dbConnect == NULL) {
$this->dbReference->sendResponse(503,'{“error_message”:’.$this->dbReference->getStatusCodeMeeage(503).’}’);
}else{

$sql = “SELECT * FROM xxx”;
$number_per_page = $_POST[“number_per_page”];
$page = ($_POST[“page”]-1)*$number_per_page +1;
$page_next = $_POST[“page”]*$number_per_page;
//echo “$page”;

if ($page != NULL && $number_per_page != NULL) {
//echo “viva for”;
$sql = “SELECT * FROM xxx WHERE image_id BETWEEN $page AND $page_next”;
}/*else{
echo “0 results”;
return;
}*/
$this->result = $this->dbConnect->query($sql);
if($this->result->num_rows > 0){
// output data of each row
$resultSet = array();
while($row = $this->result->fetch_assoc()) {
$resultSet[] = $row;
}
$this->dbReference->sendResponse(200,'{“items”:’.json_encode($resultSet).’}’);
}else{
//echo “0 results”;
$this->dbReference->sendResponse(200,'{“items”:null}’);
}

}
}
}

>

$_POST[“number_per_page”] và $_POST[“page”] là 2 tham số gửi data lên server theo dạng POST. Về làm việc với POST hay GET các bạn tham khảo ở đây nhé: http://stackoverflow.com/questions/3477333/what-is-the-difference-between-post-and-get

Ngắn gọn thì có 2 cách để pass data lên web service:

– GET: params là 1 phần của URL hay còn gọi là query string.

– POST: params là 1 phần của body request.

Chú ý đến câu lệnh sql: SELECT * FROM xxx WHERE image_id BETWEEN $page AND $page_next –> câu lệnh này trả ra số lượng items theo số page và số item trên 1 page, sử dụng để load more trên ứng dụng mobile sau này. Mọi dòng code đều rất trong sáng và dễ hiểu phải không? 😉

Các bạn có thể mở rộng hơn db bằng cách thêm các table và viết các hàm để truy vấn,insert,update,delete nhé,ở tut này tớ chỉ code đơn giản demo thôi.

Almost done! Cuối cùng tạo thêm 1 class để gọi các functions strong class DAO kia thôi. Tạo class có tên imageRequest.php với nội dung:

<?php

include(“../testExample/imageResourcesDAO.php”);
$viva = new imageResources();
$viva->getAllImageResource();

>

Giờ là lúc các bạn test sản phẩm của mình. Với tớ thì tớ hay sử dụng REST – plugin của Chrome cho phép send request theo cả POST or GET đến server. Đây là các thao tác nhé, bạn sẽ nhìn thấy 2 tham số được đưa lên theo phương thức POST (lấy 20 bản ghi ở page 1):

Nói thêm chút về việc đưa lên môi trường thật.

– Về db thì bạn có thể export ra dạng file .sql rồi import lên hosting bạn đăng ký nhé.

– Về config lại một số thông tin như tên IP, user- pass SQL server, include page… thì cũng không khó lắm đâu, vọc 1 tẹo là được thôi, thay đổi trong systemConfig.php là OK.

Kết

Trên đây là một sample nhỏ về xây dựng RESTful API dưới bàn tay của 1 newbie vốn đã quen với việc lập trình mobile. Các bạn có gì đóng góp xin cứ comment ở dưới.


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.