---
description: >-
  https://freetuts.net/thuoc-tinh-va-phuong-thuc-tinh-trong-lap-trinh-huong-doi-tuong-php-170.html
---

# Sử dụng từ khóa static (ok)

## Bài 14: Thuộc tính và phương thức tĩnh trong lập trình hướng đối tượng php <a href="#main_title" id="main_title"></a>

Đăng bởi: TheHalfHeart- Vào ngày: 05-10-2014- View: 29559

Như ta biết mỗi đối tượng luôn có các thuộc tính, phương thức và muốn sử dụng được nó ta phải khởi tạo đối tượng đó gán vào một biến sau đó gọi đến. Nhưng giả sử chúng ta tạo hai hai biến cùng một đối tượng đó thì các thao tác xử lý trên hai biến đó (thực chất là 2 object) không ảnh hưởng lẫn nhau. Và nếu bạn đã đọc qua bài hàm và khai báo hàm trong php thì sẽ có khái niệm **biến cục bộ** và **biến toàn cục**, với ví dụ trên thì ta có thể hiểu mỗi thao tác chỉ ảnh hưởng trên chính biến đó chứ không ảnh hưởng qua các biến khác nên có thể gọi là cục bộ. Nhưng trong thực tế đôi lúc ta muốn bất kỳ thao tác nào đều được lưu lại trên đối tượng đó (dạng toàn cục) thì kiểu dữ liệu tĩnh chính là mấu chốt của vấn đề này.

Nội dung chính

* [1. Khái niệm dữ liệu tĩnh](https://freetuts.net/thuoc-tinh-va-phuong-thuc-tinh-trong-lap-trinh-huong-doi-tuong-php-170.html#goto-h2-0)
* [3. Các vấn đề thông dụng khi sử dụng thành viên tĩnh](https://freetuts.net/thuoc-tinh-va-phuong-thuc-tinh-trong-lap-trinh-huong-doi-tuong-php-170.html#goto-h2-1)
  * [Truy xuất trực tiếp không cần khởi tạo object](https://freetuts.net/thuoc-tinh-va-phuong-thuc-tinh-trong-lap-trinh-huong-doi-tuong-php-170.html#goto-h3-0)
  * [Gọi các hàm tĩnh trong nội bộ của class](https://freetuts.net/thuoc-tinh-va-phuong-thuc-tinh-trong-lap-trinh-huong-doi-tuong-php-170.html#goto-h3-1)
  * [Không sử dụng từ khóa $this](https://freetuts.net/thuoc-tinh-va-phuong-thuc-tinh-trong-lap-trinh-huong-doi-tuong-php-170.html#goto-h3-2)
  * [Kế thừa khi sử dụng static](https://freetuts.net/thuoc-tinh-va-phuong-thuc-tinh-trong-lap-trinh-huong-doi-tuong-php-170.html#goto-h3-3)
* [3. Lợi hại khi sử dụng thành viên tĩnh static](https://freetuts.net/thuoc-tinh-va-phuong-thuc-tinh-trong-lap-trinh-huong-doi-tuong-php-170.html#goto-h2-2)
* [4. Lời kết](https://freetuts.net/thuoc-tinh-va-phuong-thuc-tinh-trong-lap-trinh-huong-doi-tuong-php-170.html#goto-h2-3)

### 1. Khái niệm dữ liệu tĩnh <a href="#goto-h2-0" id="goto-h2-0"></a>

[![codegym](https://freetuts.net/public/codegym/content_1.gif)](https://bit.ly/2vKoM1c)

Trong lập trình hướng đối tượng ta có thể hiểu dữ liệu tĩnh là loại dữ liệu được sử dụng ở dạng toàn cục, dù nó được xử lý ở bất kỳ file nào trong cùng một chương trình đều được lưu lại trong lớp, ta có thể gọi chúng là thành viên tĩnh. Mỗi thành viên đều có [các mức truy cập private, public và protected](https://freetuts.net/cac-muc-truy-cap-private-protected-va-public-31.html) bình thường.

**Ví dụ 1:** chương trình ở phần mở đầu.

| 123456789101112131415161718192021222324 | `// Lớp động vậtclass` `Animal{    protected` `$_name` `=` `'Chưa có tên';` `function` `setName($name){        $this->_name =` `$name;    }` `function` `getName(){        return` `$this->_name;    }}` `// Phần 1: Con Vịt$con_vit` `=` `new` `Animal();$con_vit->setName('Con Vịt');echo` `$con_vit->getName();// Kết quả: Con Vịt` `// Phần 2: Con Heo$con_heo` `=` `new` `Animal();echo` `$con_heo->getName();// Kết quả: Chưa có tên` |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

Ta thấy ở Phần 1 tôi đã tạo object `$con_vit` và thiết lập tên cho nó là 'Con Vịt'. Tiếp theo tôi tạo một object `$con_heo` và tôi không có thiết lập tên cho nó, khi xuất tên ra màn hình thì Phần 1 xuất hiện chữ 'Con Vịt' còn Phần 2 thì xuất hiện chữ 'Chưa có tên'. Như vậy rõ ràng các thao tác trên biến `$con_vit` không ảnh hưởng qua biến `$con_heo`.

**Ví dụ 2:** chương trình dùng dạng thành viên tĩnh

| 123456789101112131415161718192021222324 | `// Lớp động vậtclass` `Animal{    protected` `static` `$_name` `=` `'Chưa có tên';` `public` `static` `function` `setName($name){        Animal::$_name` `=` `$name;    }` `public` `static` `function` `getName(){        return` `Animal::$_name;    }}` `// Phần 1: Con Vịt$con_vit` `=` `new` `Animal();$con_vit->setName('Con Vịt');echo` `$con_vit->getName();// Kết quả: Con Vịt` `// Phần 2: Con Heo$con_heo` `=` `new` `Animal();echo` `$con_heo->getName();// Kết quả: Con Vịt` |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

Trong ví dụ này khác ở ví dụ 1 là các phương thức và thuộc tính tôi khai báo dạng tĩnh (_có từ khóa static_) và kết quả hoàn toàn khác với ví dụ 1. Ở cả Phần 1 và Phần 2 đều xuất ra màn hình là 'Con Vịt', lý do là tôi sử dụng dạng tĩnh và khi có thao tác thay đổi dữ liệu thì nó đều lưu vào trong class Animal nên khi khởi tạo thêm biến nó đều bị ảnh hưởng theo.

Qua hai ví dụ này có lẽ các bạn cũng đã hình dung được phần nào rồi, ta sẽ tiếp tục tìm hiểu sâu hơn nữa nhé.

### 3. Các vấn đề thông dụng khi sử dụng thành viên tĩnh <a href="#goto-h2-1" id="goto-h2-1"></a>

Như đã trình bày ở trên các thành viên tĩnh đều có các mực truy cập bình thường. Và để khai báo các mức truy cập thì ta sử dụng cú pháp sau:

**Cú pháp**:

* Thuộc tính: `[private|public|protected] static $name`, ví dụ **public static $name**
* Phương thức: `[private|public|protected] static function functionname(){}`, ví dụ **public static function setName()**

Bây giờ ta sẽ thảo luận đến một số vấn đề khi sử dụng thành viên tĩnh.

#### Truy xuất trực tiếp không cần khởi tạo object <a href="#goto-h3-0" id="goto-h3-0"></a>

| 1234567891011121314151617 | `// Lớp động vậtclass` `Animal{    protected` `static` `$_name` `=` `'Chưa có tên';` `public` `static` `function` `setName($name){        Animal::$_name` `=` `$name;    }` `public` `static` `function` `getName(){        return` `Animal::$_name;    }}` `Animal::setName('Con Vịt');echo` `Animal::getName();// Kết quả: Con Vịt` |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

#### Gọi các hàm tĩnh trong nội bộ của class <a href="#goto-h3-1" id="goto-h3-1"></a>

| 123456789101112131415161718192021 | `// Lớp động vậtclass` `Animal{    protected` `static` `$_name` `=` `'Chưa có tên';` `public` `static` `function` `setName($name){        Animal::$_name` `=` `$name;    }` `public` `static` `function` `getName(){        return` `Animal::$_name;    }` `public` `static` `function` `all($name){        Animal::setName($name);        echo` `Animal::getName();    }}` `Animal::all('Con Vịt');// Kết quả: Con Vịt` |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

Các bạn để ý trong ví dụ này tôi đã gọi các thành viên tĩnh nội bộ lẫn nhau trong chính đối tượng đó thông qua cú pháp hai dấu chấm (::). Tương tự khi sử dụng ở ngoài lớp ta vẫn dùng hai dấu chấm thay vì dấu mũi tên. Có một lưu ý rằng khi gọi đến thuộc tính tĩnh thì thông thường ta dùng `$this->name`, nhưng trong thành viên tĩnh thì khác ta dùng thêm dấu $ nữa, ví dụ `Anmal::`**`$`**`name`

#### Không sử dụng từ khóa `$this` <a href="#goto-h3-2" id="goto-h3-2"></a>

Vì các thuộc tính và phương thức tĩnh ở dạng toàn cục, được gọi mà không cần khởi tạo nên nếu bạn dùng từ khóa `$this` để gọi đến một hàm nào đó trong chính lớp đó thì sẽ bị báo sai. Từ đây ta rút ra kết luận trong phương thức tĩnh chỉ gọi được những thuộc tính và phương thức cùng class ở dạng tĩnh. Ngoài cách gọi trực tiếp tên class ta có thể dùng từ khóa **self** để thay thế, ví dụ `self::$_name`

| 12345678910111213141516171819202122 | `// Lớp động vậtclass` `Animal{    protected` `$_age` `=` `'';` `protected` `static` `$_name` `=` `'Chưa có tên';` `public` `static` `function` `setInfo($name,` `$age)    {        // Đúng        Animal::$_name` `=` `$name;` `// Sai vì $this không tồn tại        $this->_name =` `$name;` `// Sai vì $this không tồn tại        $this->_age =` `$age;` `// Sai vì thuộc tính $_age không phải là tĩnh        Animal::$_age` `=` `$age;    }}` |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

#### Kế thừa khi sử dụng static <a href="#goto-h3-3" id="goto-h3-3"></a>

Về [tính kế thừa](https://freetuts.net/tinh-ke-thua-trong-php-30.html) thì nó hoàn toàn bình thường không có gì đặc biệt, chỉ khác một điều là dùng hai dấu chấm (::) để truy xuất đến hàm tĩnh của lớp cha.

| 123456789101112131415161718192021222324252627 | `// Lớp động vậtclass` `Animal{    protected` `static` `$_name` `=` `'';` `public` `static` `function` `setName($name)    {        Animal::$_name` `=` `$name;    }` `public` `static` `function` `getName(){        return` `Animal::$_name;    }}` `class` `ConHeo` `extends` `Animal{` `public` `static` `function` `setName($name) {        parent::setName($name);    }` `}` `ConHeo::setName('Con Heo');echo` `ConHeo::getName();// Kết quả: COn Heo` |
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

### 3. Lợi hại khi sử dụng thành viên tĩnh static <a href="#goto-h2-2" id="goto-h2-2"></a>

Việc sử dụng các hàm và thuộc tính ở dạng tĩnh có ưu điểm là ta có thể thay đổi dữ liệu toàn cục cho đối tượng đó, không cần khởi tạo đối tượng mới vẫn sử dụng được. Tuy nhiên nó có khuyết điểm là nếu ta khai báo tĩnh thì chương trình sẽ xử lý lưu trữ toàn cục nên sẽ tốn bộ nhớ hơn.

### 4. Lời kết <a href="#goto-h2-3" id="goto-h2-3"></a>

Trong thực tế các thuộc tính phương thức tĩnh được sử dụng rất nhiều trong lập trình hướng đối tượng, nó là một phần không thể thiếu trong OOP nên chắc chắn ban phải nắm vững rồi :D
