Breaking

Friday, January 18, 2013

Cách dùng PHP Property Accessor, hướng dẫn sử dụng trình truy cập thuộc tính trong PHP

Từ phiên bản PHP 5.5 mới phát hành. PHP sẽ hỗ trợ Accessor cho các thuộc tính. Accessor là gì thì nếu bạn nào lập trình trên nên tảng .Net (VD: C#, VB.Net ...) thì chắc đã biết về Accessor rồi.


Hướng dẫn viết PHP Property Accessor
Tuy nhiên, để bài viết này dễ hiểu hơn, mình sẽ sơ lược lại về Accessor ở mức đơn giản dễ hiểu nhất

Accessor dịch sang tiếng Việt là trình truy cập Property Accessor là trình truy cập thuộc tính. Mình lấy ví dụ:

Bạn có class ThoiGian, Bạn muốn lấy thời gian hiện tại thông qua thuộc tính hienTai chẳng hạn (Lấy qua thuộc tính chứ không phải phương thức).

VD:

$thoigian=new ThoiGian();
$hienTai=$thoigian->hienTai; 
Như vậy:
+ hienTai là một thuộc tính, bạn phải khai báo thuộc tính hienTai khi định nghĩa class ThoiGian => Người dùng có thể gán nội dung bậy bạ cho thuộc tính hienTai mà không đúng là thời gian hiện tại
+ hienTai là một thuộc tính cố định, như vậy nội dung của thuộc tính này sẽ thay đổi khi bạn gán nội dung cho biến hoặc gọi 1 phương thức trước khi lấy nội dung của biến để gán thời gian hiện tại của hệ thống cho biến hienTai.=> Rườm rà khi muốn lấy 1 giá trị cứ phải gọi phương thức trước khi lấy.

=> Bạn muốn lấy thời gian hiện tại qua thuộc tính hienTai là điều không thể. Ở các version cũ của PHP bạn có thể dùng magic method, nhưng magic method lại có 1 số nhược điểm ở một số trường hợp nên bản PHP 5.5 này, PHP đưa thêm Accessor vào phần lập trình hướng đối tượng.

Accessor sẽ giúp bạn truy cập 1 thuộc tính cho dù bạn không cần khai báo thuộc tính đó khi định nghĩa class. Khi gọi đến nội dung của thuộc tính đó, bạn có thể làm 1 điều gì đó trước khi trả về nội dùng (hay giá trị) của thuộc tính đó.

Bây giờ, mình sẽ giải quyết bài toán trên bằng việc sử dụng PHP Property Accessor.

class ThoiGian{
public $hienTai
{
get { return date('d-m-Y, h:i:s A');}
}
}
$thoigian=new ThoiGian();
echo 'Hiên tại là: '.$thoigian->hienTai;
Khi định nghĩa class như trên, khi bạn truy cập đến thuộc tính hienTai, hàm get() sẽ được gọi. Giá trị hàm get() trả về sẽ được coi là gái trị của thuộc tính hienTai.

Chắc tới đây các bạn đã hiểu được accessor là gì rồi đúng không


PHP cho chúng ta định nghĩa 4 phương thức accessor.
  1. get - Là phương thức cho chúng ta lấy giá trị của thuộc tính
  2. set - là phương thức cho chúng ta thay đổi giá trị thuộc tính
  3. isset - là phương thức cho chúng ta kiểm tra thuộc tính có tồn tại hay không ? (Khi gọi hàm isset)
  4. unset - là phương thức cho chúng ta hủy giá trị thuộc tính (khi gọi hàm unset và truyền vào thuộc tính)


Dưới đây, mình sẽ ví dụ 1 class dùng 4 phương thức Accessor trên.

<?php
class ChuyenDoi
{
private $_seconds=0; //-- Số giây
public function __construct($second=0)
{
$this->Giay=$second;
}
//--Đổi giây ra giờ
public $Gio
{
get {return $this->_seconds/3600;}
}
//-- Đổi giây ra phút
public $Phut
{
get {return $this->_seconds/60;}
}
public $Giay
{
get {return $this->_seconds;} //1
set { //2
$second=intval($value); //--Giá trị gán vào ở biến $value
if($second<0)
$second=0;
$this->_seconds=$second;
}
isset {return isset($this->_seconds);} //2
unset {unset($this->_seconds);} //3
}
}
//Ví dụ:
$chuyendoi=new ChuyenDoi(3600);
echo "{$chuyendoi->Giay} giây={$chuyendoi->Gio} giờ";
// Kết quả: 3600 giây=1 giờ
echo '<br />'; //xuống dòng
echo $chuyendoi->Giay; // Gọi 1
$chuyendoi->Giay=120; // Gọi 2
if(isset($chuyendoi->Giay)) // Gọi 3
echo $chuyendoi->Giay;
unset($chuyendoi->Giay); // Gọi 4
$chuyendoi->Gio=230; //Lỗi, vì không định nghĩa set cho Gio

Tạm thời chỉ viết nhiêu đó để giới thiệu với mọi người, Lần sau có thời gian mình sẽ viết sâu hơn về vấn đề này cũng như magic method. Lưu ý là bài này phải test trên PHP 5.5 nhé

Mình lấy ví dụ,

Class TinTuc
{
public $newsId; //--ID bản tin
public function getContent() //Lấy nội dung bản tin
{
$sql='SELECT * FROM news WHERE newsId='.$this->newsId;
///.....
}
}
Chuyện gì sảy ra nếu
$tintuc=new TinTuc();
$tintuc->newsId=$_GET['newsId'];
//$_GET['newsId'] hiện có giá trị là 0 UNION SELECT username,password,1,2,3 FROM admin WHERE userid=1
=> Dính SQL Injection
Đấy là 1 ví dụ nho nhỏ thôi, ứng dụng thì còn nhiều lắm. Nếu đối với lập trình viên thông thường thì chắc họ ko hay để ý đến nhưng với những người xây dựng framework cho người khác dùng (VD: vbulletin,xenforo,joomla...) thì đây là những công cụ cực kỳ hữu ích
Thanks: Vũ Thanh Lai Of sinhvienit.net

No comments:

Post a Comment