Hướng đối tượng (OOP) trong PHP

Từ PHP5, bạn đã có thể viết mã PHP theo kiểu hướng đối tượng. Lập trình hướng đối tượng thì nhanh hơn và dễ thực hiện hơn.

Hướng đối tượng (OOP) trong PHP là gì?

OOP là viết tắt của object-oriented programming (Lập trình hướng đối tượng).

Nếu như lập trình thủ tục tập trung vào việc viết các thủ tục hoặc hàm thì lập trình hướng đối tượng tập trung vào việc tạo các đối tượng chứa cả dữ liệu và hàm.

Lập trình hướng đối tượng có một số lợi thế so với lập trình thủ tục:

  • OOP nhanh hơn và dễ thực hiện hơn.
  • OOP cung cấp một cấu trúc rõ ràng cho các chương trình.
  • OOP giúp giữ mã PHP DRY "Don't Repeat Yourself" và làm cho mã dễ dàng duy trì, sửa đổi và gỡ lỗi.
  • OOP cho phép tạo các ứng dụng có thể tái sử dụng đầy đủ với ít mã hơn và thời gian phát triển ngắn hơn
Mẹo: Nguyên tắc DRY là về việc giảm sự lặp lại của mã. Bạn nên chuyển những phần mã được sử dụng phổ biến trong ứng dụng vào các hàm và sử dụng lại chúng thay vì lặp lại nó.

Lớp và đối tượng trong PHP là gì?

Các lớp và các đối tượng là hai khía cạnh chính của lập trình hướng đối tượng.

Nhìn vào hình minh họa sau để thấy sự khác biệt giữa lớp và các đối tượng:

class objects
fruit apple
mango
banana

Một ví dụ khác:

class objects
car vinfast
audi
toyota

Vì vậy, một lớp là một khuôn mẫu cho các đối tượng và một đối tượng là một thể hiện của một lớp.

Khi các đối tượng riêng lẻ được tạo, chúng kế thừa tất cả các thuộc tính và hành vi từ lớp, nhưng mỗi đối tượng sẽ có các giá trị khác nhau cho các thuộc tính.

Như ở ví dụ trên trái cây có thể có các thuộc tính như name, color, weight, v.v. Chúng ta có thể định nghĩa lớp fruit có các biến như $name, $color và $weight để lưu trữ các giá trị của các thuộc tính này.

Khi các đối tượng riêng lẻ như: apple, mango, banana, v.v được tạo, chúng kế thừa tất cả các thuộc tính và hành vi từ lớp fruit, nhưng mỗi đối tượng sẽ có các giá trị khác nhau cho các thuộc tính.

Tạo lớp trong PHP

Một lớp được định nghĩa bằng cách sử dụng từ khóa class, theo sau là tên của lớp và một cặp dấu ngoặc nhọn ({}). Tất cả các thuộc tính và phương thức của nó đặt ở bên trong cặp dấu ngoặc nhọn:

<?php
    class Fruit {
      // code goes here...
    }
?>

Dưới đây chúng tôi khai báo một lớp có tên Fruit bao gồm hai thuộc tính ($name và $color) và hai phương thức set_name() và get_name() để thiết lập và trả về giá trị của thuộc tính $name:

<?php
    class Fruit {
        // Properties
        public $name;
        public $color;

        // Methods
        function set_name($name) {
            $this->name = $name;
        }
        
        function get_name() {
            return $this->name;
        }
    }
?>
Lưu ý: Trong một lớp, các biến được gọi là thuộc tính và hàm được gọi là phương thức!

Tạo đối tượng trong PHP

Các lớp không là gì nếu không có đối tượng! Chúng ta có thể tạo nhiều đối tượng từ một lớp. Mỗi đối tượng sẽ có tất cả các thuộc tính và phương thức được định nghĩa trong lớp, nhưng chúng sẽ có các giá trị thuộc tính khác nhau.

Các đối tượng của một lớp được tạo bằng cách sử dụng từ khóa new.

Trong ví dụ dưới đây, $apple và $banana là các thể hiện của lớp Fruit:

<?php
    class Fruit {
        // Properties
        public $name;
        public $color;

        // Methods
        function set_name($name) {
            $this->name = $name;
        }
        
        function get_name() {
            return $this->name;
        }
    }

    $apple = new Fruit();
    $banana = new Fruit();
    $apple->set_name('Apple');
    $banana->set_name('Banana');

    echo $apple->get_name();
    echo "<br>";
    echo $banana->get_name();
?>

Đây là kết quả:

Apple
Banana

Trong ví dụ dưới đây, chúng tôi thêm hai phương thức nữa vào lớp Fruit, để thiết lập và trả về giá trị của thuộc tính $color:

<?php
    class Fruit {
        // Properties
        public $name;
        public $color;

        // Methods
        function set_name($name) {
            $this->name = $name;
        }
        
        function get_name() {
            return $this->name;
        }
        
        function set_color($color) {
            $this->color = $color;
        }
        
        function get_color() {
            return $this->color;
        }
    }

    $apple = new Fruit();
    $apple->set_name('Apple');
    $apple->set_color('Red');
    echo "Name: " . $apple->get_name();
    echo "<br>";
    echo "Color: " . $apple->get_color();
?>

Đây là kết quả:

Name: Apple
Color: Red

Từ khóa $this trong PHP

Từ khóa $this dùng để chỉ đối tượng hiện tại và chỉ có sẵn trong các phương thức.

Hãy xem ví dụ sau:

<?php
    class Fruit {
        public $name;
    }
    
    $apple = new Fruit();
?>

Vậy, chúng ta có thể thay đổi giá trị của thuộc tính $name ở đâu? Có hai cách:

1. Bên trong lớp (bằng cách thêm phương thức set_name() và sử dụng $this):

<?php
    class Fruit {
        public $name;
        
        function set_name($name) {
            $this->name = $name;
        }
    }
    
    $apple = new Fruit();
    $apple->set_name("Apple");
?>

2. Bên ngoài lớp (bằng cách thay đổi trực tiếp giá trị của thuộc tính):

<?php
    class Fruit {
        public $name;
    }
    
    $apple = new Fruit();
    $apple->name = "Apple";
?>

Từ khóa instanceof trong PHP

Bạn có thể sử dụng từ khóa instanceof để kiểm tra xem một đối tượng có thuộc về một lớp cụ thể không:

<?php
    $apple = new Fruit();
    var_dump($apple instanceof Fruit);
?>

Đây là kết quả:

bool(true)

Hàm khởi tạo __construct trong PHP

Hàm khởi tạo (constructor) cho phép bạn gán giá trị cho các thuộc tính của đối tượng khi khởi tạo tạo đối tượng.

Nếu bạn tạo một hàm __construct(), PHP sẽ tự động gọi hàm này khi bạn tạo một đối tượng từ một lớp. Lưu ý rằng hàm khởi tạo bắt đầu bằng hai dấu gạch dưới (__).

Ví dụ dưới đây minh họa việc sử dụng hàm khởi tạo sẽ giúp chúng ta không cần phải gọi phương thức set_name() làm giảm số lượng mã cần phải viết:

<?php
    class Fruit {
        public $name;
        public $color;

        function __construct($name) {
            $this->name = $name;
        }
        
        function get_name() {
            return $this->name;
        }
    }

    $apple = new Fruit("Apple");
    echo $apple->get_name();
?>

Đây là kết quả:

Apple

Một ví dụ khác:

<?php
    class Fruit {
        public $name;
        public $color;

        function __construct($name, $color) {
            $this->name = $name;
            $this->color = $color;
        }
        function get_name() {
            return $this->name;
        }
        function get_color() {
            return $this->color;
        }
    }

    $apple = new Fruit("Apple", "red");
    echo $apple->get_name();
    echo "<br>";
    echo $apple->get_color();
?>

Đây là kết quả:

Apple
red

Hàm hủy __destruct trong PHP

Một hàm hủy (destructor) được gọi khi đối tượng bị hủy hoặc tập lệnh bị dừng hoặc thoát.

Nếu bạn tạo một hàm __destruct(), PHP sẽ tự động gọi hàm này ở cuối tập lệnh PHP. Lưu ý rằng hàm hủy bắt đầu bằng hai dấu gạch dưới (__).

Ví dụ dưới đây có hàm __construct() được gọi tự động khi bạn tạo một đối tượng từ lớp Fruit và hàm __destruct() được gọi tự động ở cuối tập lệnh PHP:

<?php
    class Fruit {
        public $name;
        public $color;

        function __construct($name) {
            $this->name = $name;
        }
        
        function __destruct() {
            echo "The fruit is {$this->name}.";
        }
    }

    $apple = new Fruit("Apple");
?>

Đây là kết quả:

The fruit is Apple.

Một ví dụ khác:

<?php
    class Fruit {
        public $name;
        public $color;

        function __construct($name, $color) {
            $this->name = $name;
            $this->color = $color;
        }
        
        function __destruct() {
            echo "The fruit is {$this->name} and the color is {$this->color}.";
        }
    }

    $apple = new Fruit("Apple", "red");
?>

Đây là kết quả:

The fruit is Apple and the color is red.
Tip: Vì các hàm khởi tạo và hàm hủy giúp giảm số lượng mã nên chúng rất hữu ích!

Bộ chỉ thị truy cập trong PHP

Các thuộc tính và phương thức có thể có các chỉ thị truy cập để kiểm soát nơi chúng có thể được truy cập. Có ba chỉ thị truy cập sau:

  • public - thuộc tính hoặc phương thức có thể được truy cập ở bất cứ đâu. Đây là mặc định.
  • protected - thuộc tính hoặc phương thức có thể được truy cập trong lớp và bởi các lớp kế thừa từ lớp đó.
  • private - thuộc tính hoặc phương thức CHỈ có thể được truy cập trong lớp.

Trong ví dụ sau, chúng tôi đã thêm ba chỉ thị truy cập khác nhau vào ba thuộc tính. Ở đây, nếu bạn cố gắng gán giá trị cho thuộc tính $name thì nó sẽ hoạt động tốt (vì thuộc tính tên là public).

Tuy nhiên, nếu bạn cố gắng gán giá trị cho thuộc tính $color hoặc $weight, nó sẽ dẫn đến lỗi nghiêm trọng (vì thuộc tính $color hoặc $weight có chỉ thị truy cập là protectedprivate):

<?php
    class Fruit {
        public $name;
        protected $color;
        private $weight;
    }

    $mango = new Fruit();
    $mango->name = 'Mango'; // OK
    $mango->color = 'Yellow'; // ERROR
    $mango->weight = '300'; // ERROR
?>

Đây là kết quả:

Fatal error: Uncaught Error: Cannot access protected property Fruit::$color ...

Trong ví dụ tiếp theo, chúng tôi đã thêm các sửa đổi truy cập vào hai phương thức. Ở đây, nếu bạn cố gắng gọi hàm set_color() hoặc hàm set_ weight(), nó sẽ dẫn đến một lỗi nghiêm trọng (vì hai hàm này có chỉ thị truy cập là protectedprivate), ngay cả khi tất cả các thuộc tính đều là public:

<?php
    class Fruit {
        public $name;
        public $color;
        public $weight;

        function set_name($n) {  // a public function (default)
            $this->name = $n;
        }
        
        protected function set_color($n) { // a protected function
            $this->color = $n;
        }
        
        private function set_weight($n) { // a private function
            $this->weight = $n;
        }
    }

    $mango = new Fruit();
    $mango->set_name('Mango'); // OK
    $mango->set_color('Yellow'); // ERROR
    $mango->set_weight('300'); // ERROR
?>

Đây là kết quả:

Fatal error: Uncaught Error: Call to protected method Fruit::set_color() from context ...

Hằng số lớp trong PHP

Hằng số không thể thay đổi một khi nó được khai báo và gán giá trị.

Các hằng số lớp có thể hữu ích nếu bạn cần định nghĩa một số dữ liệu không đổi trong một lớp.

Một hằng số lớp được khai báo bên trong một lớp với từ khóa const.

Các hằng số lớp thì phân biệt chữ hoa chữ thường. Tuy nhiên, theo quy ước nên đặt tên hằng số là các chữ cái viết hoa.

Chúng ta có thể truy cập một hằng số từ bên ngoài lớp bằng cách sử dụng tên lớp theo sau là toán tử phân giải phạm vi (::) rồi đến tên hằng, như ở đây:

<?php
    class Goodbye {
        const LEAVING_MESSAGE = "Thank you for visiting tech.comdy.vn!";
    }

    echo Goodbye::LEAVING_MESSAGE;
?>

Đây là kết quả:

Thank you for visiting tech.comdy.vn!

Hoặc, chúng ta có thể truy cập một hằng số từ bên trong lớp bằng cách sử dụng từ khóa self theo sau là toán tử phân giải phạm vi (::) rồi đến tên hằng, như ở đây:

<?php
    class Goodbye {
        const LEAVING_MESSAGE = "Thank you for visiting tech.comdy.vn!";
        public function byebye() {
            echo self::LEAVING_MESSAGE;
        }
    }

    $goodbye = new Goodbye();
    $goodbye->byebye();
?>

Đây là kết quả:

Thank you for visiting tech.comdy.vn!
Lập Trình PHP
Bài Viết Liên Quan:
Hướng dẫn lập trình PHP toàn tập
Trung Nguyen 08/05/2020
Hướng dẫn lập trình PHP toàn tập

Hướng dẫn lập trình PHP toàn tập sẽ giúp bạn từng bước tìm hiểu và nắm vững ngôn ngữ lập trình PHP.

Truy xuất dữ liệu MySQL trong PHP
Trung Nguyen 07/05/2020
Truy xuất dữ liệu MySQL trong PHP

Hướng dẫn cách truy xuất, lọc, sắp xếp dữ liệu MySQL trong PHP sử dụng MySQLi và PDO.

MySQL prepared statements trong PHP
Trung Nguyen 07/05/2020
MySQL prepared statements trong PHP

MySQL prepared statements trong PHP rất hữu ích để chống lại các cuộc tấn công SQL Injection.

Thêm dữ liệu vào MySQL trong PHP
Trung Nguyen 07/05/2020
Thêm dữ liệu vào MySQL trong PHP

Hướng dẫn này sẽ giúp bạn tìm hiểu cách thêm dữ liệu vào MySQL sử dụng MySQLi và PDO trong PHP.