Lập trình hướng đối tượng (OOP) trong PHP là một phương pháp mạnh mẽ và linh hoạt để tổ chức mã nguồn. Các khái niệm cơ bản của OOP trong PHP bao gồm:
1. Lớp (Class)
Lớp là một bản thiết kế (blueprint) cho các đối tượng. Nó định nghĩa các thuộc tính và phương thức mà các đối tượng của lớp sẽ có.
1 2 3 4 5 6 |
class <Tên_lớp>{ // Your code is here … } |
Ví dụ
1 2 3 4 5 6 |
class foo { const BAR = "Hello World"; } echo foo::BAR; |
Cú pháp khai báo lớp kế thừa:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class a { function test(){ echo "a::test called";} function func(){echo "a::func called";} } class b extends a { function test(){echo "b::test called";} } class c extends b { function test(){parent::test();} } class d extends c { function test(){b::test();} } |
Cú pháp xác định lớp đối tượng:
1 2 3 4 5 |
if ($obj instanceof MyClass) { echo "$obj is an instance of MyClass"; } |
Cú pháp tạo đối tượng:
1 2 3 |
$myClassInstance = new myClass(); |
Lưu ý: các đối tượng trong PHP được sử dụng theo dạng tham chiếu
1 2 3 4 5 |
$myClassInstance = new myClass(); $copyInstance = $myClassInstance(); // Cả 2 biến $myInstance và $copyInstance cùng trỏ tới một đối tượng thuộc myClass. |
1 2 3 4 5 6 7 8 9 10 |
<html> <head><title>Test include</title></head> <body> <?php require("require_include.php"); echo "Hello you"; ?> </body> </html> |
1 2 3 4 5 6 7 8 9 10 |
<html> <head><title>Test include</title></head> <body> <?php include("require_include.php"); echo "Hello you"; ??> </body> </html> |
Phương thức và thuộc tính:
1 2 3 4 5 6 7 8 9 10 |
class myClass { function myFunction() { echo "You called myClass::myFunction"; } } // Access methods of class myClass $obj = new myClass(); $obj -> myFunction(); |
Con trỏ $this:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class myClass { function myFunction($data) { echo "The value is $data"; } function callMyFunction($data) { // Call myFunction() $this->myFunction($data); } } $obj = new myClass(); $obj->callMyFunction(123); |
Cú pháp hàm khởi tạo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class foo { function __construct() { // PHP 5 new style constructor echo __METHOD__; } function foo() { // PHP 4 style constructor } } new foo(); |
Cú pháp hàm hủy:
1 2 3 4 5 |
abstract class <class_name>{ [properties … ] abstract function func_name(…); public function func_name(…); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class foo { function __construct() { echo __METHOD__ . PHP_EOL; } function __destruct() { echo __METHOD__; } } new foo(); |
Cú pháp hàm hủy:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class foo { function __construct() { echo __METHOD__ . PHP_EOL; } function __destruct() { echo __METHOD__; } } new foo(); |
Trong lập trình hướng đối tượng (OOP) trong PHP, các từ khóa public, protected, private, và final đều được sử dụng để kiểm soát quyền truy cập và hành vi của các thuộc tính và phương thức trong lớp. Dưới đây là giải thích chi tiết cho từng từ khóa:
1. Public
public là phạm vi truy cập mặc định trong PHP. Các thuộc tính và phương thức được khai báo là public có thể được truy cập từ bất kỳ đâu: bên trong lớp, từ các lớp kế thừa, và từ bên ngoài lớp.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class Animal { public $name; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } } $dog = new Animal(); $dog->setName("Dog"); echo $dog->getName(); // Output: "Dog" |
2. Protectedprotected
Chỉ cho phép truy cập từ bên trong lớp khai báo nó hoặc từ các lớp kế thừa (subclasses). Nó không thể truy cập trực tiếp từ bên ngoài lớp.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
class Animal { protected $type; public function setType($type) { $this->type = $type; } protected function getType() { return $this->type; } } class Dog extends Animal { public function describe() { return "This is a " . $this->getType(); } } $dog = new Dog(); $dog->setType("Mammal"); echo $dog->describe(); // Output: "This is a Mammal" // Không thể truy cập trực tiếp $dog->type từ bên ngoài lớp |
3. Private
private chỉ cho phép truy cập từ bên trong lớp khai báo nó. Không thể truy cập từ lớp con hoặc từ bên ngoài lớp.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
class Animal { private $species; public function setSpecies($species) { $this->species = $species; } private function getSpecies() { return $this->species; } public function describe() { return "This is a " . $this->species; } } $cat = new Animal(); $cat->setSpecies("Cat"); echo $cat->describe(); // Output: "This is a Cat" // Không thể truy cập $cat->species hoặc $cat->getSpecies() từ bên ngoài |
4. Final
final ngăn không cho lớp hoặc phương thức bị ghi đè (override) bởi các lớp kế thừa. Nếu một phương thức hoặc một lớp được khai báo là final, các lớp con không thể ghi đè phương thức đó, và lớp không thể được kế thừa.
Final Method:
Khi một phương thức được khai báo là final, nó không thể bị ghi đè trong lớp con.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class Animal { final public function makeSound() { echo "Animal sound"; } } class Dog extends Animal { // Không thể override phương thức makeSound() // Sẽ gây lỗi nếu thực hiện // public function makeSound() { // echo "Bark"; // } } |
Final Class:
Khi một lớp được khai báo là final, nó không thể bị kế thừa bởi lớp khác.
1 2 3 4 5 6 7 8 9 10 11 |
final class Bird { public function fly() { echo "Flying"; } } // Sẽ gây lỗi nếu thực hiện kế thừa lớp final // class Eagle extends Bird { // // Không thể kế thừa lớp Bird // } |
Tóm tắt sự khác biệt:
public: Truy cập từ bất kỳ đâu (bên trong lớp, lớp con, bên ngoài lớp).
protected: Truy cập từ bên trong lớp và lớp con, không thể truy cập từ bên ngoài lớp.
private: Chỉ có thể truy cập từ bên trong lớp, không thể truy cập từ lớp con hoặc bên ngoài lớp.
final: Ngăn lớp hoặc phương thức bị ghi đè hoặc kế thừa.
1 2 3 4 5 6 7 8 9 10 11 |
final class Bird { public function fly() { echo "Flying"; } } // Sẽ gây lỗi nếu thực hiện kế thừa lớp final // class Eagle extends Bird { // // Không thể kế thừa lớp Bird // } |
Cú pháp khai báo biến và phương thức tĩnh:
1 2 3 4 5 6 7 8 |
class foo { static $bar = "bat"; static public function baz(){ echo "Hello World"; } } echo foo::$bar."<br />"; foo::baz(); |
Cú pháp khai báo hằng trong lớp:
1 2 3 4 |
class foo { const BAR = "Hello World"; } echo foo::BAR; |
Lớp trừu tượng
– Khái niệm
– Lớp trừu tượng là một lớp cha cho tất cả các lớp có cùng bản chất. Do đó mỗi lớp dẫn xuất (lớp con) chỉ có thể kế thừa từ một lớp trừu tượng.
– Lớp trừu tượng không cho phép tạo instance (không thể tạo được các đối tượng thuộc lớp đó).
– Cú pháp khai báo lớp trừu tượng
Ví dụ:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
abstract class DataStore_Adapter { private $id; abstract function insert(); abstract function update(); public function save(){ if (!is_null($this->id)){ $this->update(); } else { $this->insert(); } } } class PDO_DataStore_Adapter extends DataStore_Adapter { public __construct($dsn){ // ... } function insert(){ // ... } function update(){ // ... } } |
Lớp interface
– Khái niệm
Lớp interface được xem như một mặt nạ cho tất cả các lớp cùng cách thức hoạt động nhưng có thể khác nhau về bản chất.
Lớp dẫn xuất có thể kế thừa từ nhiều lớp interface để bổ sung đầy đủ cách thức hoạt động của mình (đa kế thừa – Multiple inheritance).
– Cú pháp khai báo lớp interface
1 2 3 |
interface class <class_name>{ … } |
1 2 3 4 5 6 7 8 9 10 11 12 |
interface DataStore_Adapter { public function insert(); public function update(); public function save(); public function newRecord($name = null); } class PDO_DataStore_Adapter implements DataStore_Adapter { public function insert(){ // ... } public function update(){ // ... } public function save(){ // ... } public function newRecord($name = null){ } } |
Công dụng
– Giống nhau:
Chèn file vào file hiện tại, nếu file được chèn có lỗi thì hiện thông báo lỗi
– Khác nhau:
+ Khi file được chèn bằng lệnh require() có lỗi thì trình biên dịch sẽ dừng lại, không dịch nữa và sẽ xuất hiện thông báo lỗi.
+ Khi file được chèn bằng lệnh include() có lỗi thì trình biên dịch vẫn tiếp tục dịch cho đến hết, đồng thời cũng xuất hiện warning để cảnh báo file đó bị lỗi.
Ví dụ
Giả sử 2 đoạn chương trình sau cùng sử dụng tập tin require_include.php không tồn tại như sau:
Hàm include_once và require_once
– Là 2 hàm biến đổi của hàm include và require nhằm mục đích nếu tập tin đã được chèn trước đó thì không chèn nữa.
– Ví dụ: giả sử có tập tin require_include_once.php như sau:
1 2 3 4 |
<?php // Tập tin require_include_once.php echo "Hello you <br>"; ?> |
1 2 3 4 5 6 7 8 9 10 |
<!– Tập tin test_require_include_once.php --> <html> <head><title>Test include_once</title></head> <body> <?php include_once('require_include_once.php'); include_once('require_include_once.php'); ?> </body> </html> |