Trong lập trình hướng đối tượng (OOP) của PHP, ngoài phương thức tĩnh (static methods), còn có thuộc tính tĩnh (static properties). Static properties là các thuộc tính được khai báo bằng từ khóa static và thuộc về class chứ không phải đối tượng. Điều này có nghĩa là các thuộc tính tĩnh có thể được truy cập mà không cần tạo đối tượng, và tất cả các đối tượng của class đó sẽ chia sẻ cùng một giá trị cho thuộc tính tĩnh.

Trong bài viết này, chúng ta sẽ tìm hiểu về thuộc tính tĩnh trong PHP, cách khai báo và sử dụng chúng, cùng với các tình huống nên áp dụng.

1. Static properties là gì?

Thuộc tính tĩnh (static properties) là các biến được khai báo bên trong class nhưng không thuộc về một đối tượng cụ thể. Thay vào đó, thuộc tính tĩnh tồn tại ở mức class, và tất cả các đối tượng của class đó đều chia sẻ cùng một thuộc tính tĩnh.

  • Khác với thuộc tính thông thường: Mỗi đối tượng có các bản sao riêng của thuộc tính thông thường, nhưng thuộc tính tĩnh được chia sẻ giữa tất cả các đối tượng.
  • Truy cập thông qua class: Bạn có thể truy cập thuộc tính tĩnh mà không cần khởi tạo đối tượng bằng cú pháp ClassName::$property.

Cú pháp khai báo static properties

php
<?php

class ClassName {
    public static $propertyName = value;
}
  • static: Từ khóa được sử dụng để khai báo thuộc tính tĩnh.
  • $propertyName: Tên của thuộc tính tĩnh.
  • value: Giá trị khởi tạo của thuộc tính tĩnh (tùy chọn).

2. Ví dụ về static properties

Dưới đây là một ví dụ về cách khai báo và sử dụng thuộc tính tĩnh trong PHP:

php
<?php

class Car {
    public static $count = 0;  // Thuộc tính tĩnh

    public function __construct() {
        self::$count++;  // Tăng giá trị của thuộc tính tĩnh khi một đối tượng mới được tạo
    }

    public static function getCount() {
        return self::$count;  // Truy cập thuộc tính tĩnh từ phương thức tĩnh
    }
}

$car1 = new Car();
$car2 = new Car();
$car3 = new Car();

echo Car::getCount();  // Output: 3

Giải thích:

  • Thuộc tính tĩnh count được khai báo với giá trị ban đầu là 0.
  • Mỗi khi một đối tượng mới của class Car được tạo ra, giá trị của thuộc tính tĩnh count sẽ được tăng lên.
  • Thuộc tính tĩnh count được truy cập thông qua tên class Car::getCount() và hiển thị kết quả là 3, cho biết đã có ba đối tượng Car được tạo.

3. Truy cập static properties từ bên trong và bên ngoài class

Truy cập static properties từ bên trong class

Khi bạn muốn truy cập thuộc tính tĩnh từ bên trong class, bạn phải sử dụng từ khóa self:: thay vì $this->, vì thuộc tính tĩnh không thuộc về đối tượng cụ thể mà thuộc về class.

php
<?php

class MathHelper {
    public static $pi = 3.1416;

    public static function getPi() {
        return self::$pi;  // Truy cập thuộc tính tĩnh
    }
}

echo MathHelper::getPi();  // Output: 3.1416

Truy cập static properties từ bên ngoài class

Bạn có thể truy cập trực tiếp thuộc tính tĩnh từ bên ngoài class mà không cần khởi tạo đối tượng, bằng cách sử dụng cú pháp ClassName::$property.

php
echo MathHelper::$pi;  // Output: 3.1416

Ví dụ chi tiết:

php
<?php

class BankAccount {
    public static $bankName = "ABC Bank";

    public static function displayBankName() {
        echo self::$bankName;
    }
}

// Truy cập thuộc tính tĩnh từ bên ngoài class
echo BankAccount::$bankName;  // Output: ABC Bank

// Truy cập thông qua phương thức tĩnh
BankAccount::displayBankName();  // Output: ABC Bank

4. Kế thừa và static properties

Trong PHP, khi một class con kế thừa từ class cha, các thuộc tính tĩnh của class cha cũng được kế thừa. Tuy nhiên, nếu class con thay đổi giá trị của thuộc tính tĩnh, điều này sẽ ảnh hưởng đến tất cả các class con và class cha vì thuộc tính tĩnh được chia sẻ ở mức class.

Ví dụ về kế thừa với static properties:

php
<?php

class ParentClass {
    public static $value = 100;
}

class ChildClass extends ParentClass {}

// Truy cập thuộc tính tĩnh từ class con
echo ChildClass::$value;  // Output: 100

// Thay đổi giá trị của thuộc tính tĩnh từ class con
ChildClass::$value = 200;

echo ParentClass::$value;  // Output: 200  (Class cha cũng bị ảnh hưởng)

Giải thích:

  • Class ChildClass kế thừa thuộc tính tĩnh $value từ class ParentClass.
  • Khi thay đổi giá trị của $value từ class con, giá trị của thuộc tính tĩnh cũng thay đổi trong class cha do thuộc tính tĩnh được chia sẻ ở cấp class.

5. Static properties và Instance properties

Thuộc tính tĩnh (Static Properties)Thuộc tính đối tượng (Instance Properties)
Thuộc về class, không thuộc về đối tượng cụ thể.Thuộc về mỗi đối tượng cụ thể.
Chia sẻ giữa tất cả các đối tượng của class.Mỗi đối tượng có bản sao riêng.
Được truy cập thông qua class (ClassName::$property).Được truy cập thông qua đối tượng ($this->property).
Có thể truy cập mà không cần khởi tạo đối tượng.Chỉ có thể truy cập sau khi khởi tạo đối tượng.

Ví dụ so sánh:

php
<?php

class Example {
    public static $staticProperty = "I am static!";
    public $instanceProperty = "I am an instance property!";
}

$example1 = new Example();
$example2 = new Example();

// Truy cập thuộc tính đối tượng
echo $example1->instanceProperty;  // Output: I am an instance property!
echo $example2->instanceProperty;  // Output: I am an instance property!

// Truy cập thuộc tính tĩnh
echo Example::$staticProperty;  // Output: I am static!

6. Khi nào nên sử dụng Static properties?

Static properties hữu ích trong các trường hợp sau:

  • Quản lý các giá trị dùng chung: Khi bạn cần lưu trữ các giá trị dùng chung giữa tất cả các đối tượng của một class, như thông tin cấu hình, số lượng đối tượng, hoặc các hằng số liên quan đến class.Ví dụ: Lưu trữ tên của một ngân hàng hoặc số lượng người dùng đã đăng ký.
php
<?php

class User
{
    public static $userCount = 0;

    public function __construct()
    {
        self::$userCount++;
    }
}

$user1 = new User();
$user2 = new User();
echo User::$userCount; // Output: 2
  • Tối ưu hóa bộ nhớ: Trong trường hợp bạn không cần mỗi đối tượng lưu trữ bản sao của một thuộc tính, thuộc tính tĩnh sẽ giúp tiết kiệm bộ nhớ vì chỉ có một bản sao của thuộc tính được lưu cho toàn bộ class.
  • Truy cập dữ liệu mà không cần khởi tạo đối tượng: Khi bạn chỉ muốn lưu trữ một giá trị mà không cần tạo đối tượng để truy cập giá trị đó, thuộc tính tĩnh sẽ giúp đơn giản hóa quá trình.

7. Hạn chế của static properties

  • Không thể sử dụng $this: Trong các phương thức tĩnh, bạn không thể sử dụng từ khóa $this để truy cập thuộc tính đối tượng, vì $this chỉ khả dụng khi làm việc với một đối tượng cụ thể.
  • Thiếu tính kế thừa động: Khi bạn thay đổi giá trị của thuộc tính tĩnh trong một class con, sự thay đổi đó có thể ảnh hưởng đến tất cả các class con và class cha, điều này có thể gây ra những thay đổi ngoài ý muốn.

Kết luận

Static properties trong PHP là một tính năng mạnh mẽ, cho phép bạn lưu trữ và chia sẻ dữ liệu ở mức class thay vì mức đối tượng. Chúng đặc biệt hữu ích trong các trường hợp cần quản lý các giá trị chung hoặc khi bạn không cần khởi tạo đối tượng để truy cập dữ liệu. Tuy nhiên, cần sử dụng chúng một cách cẩn thận để tránh những thay đổi không mong muốn khi sử dụng thuộc tính tĩnh trong các class kế thừa.

Static properties, khi được sử dụng kết hợp với static methods, có thể giúp tổ chức mã của bạn trở nên rõ ràng và hiệu quả hơn, đặc biệt trong những tình huống yêu cầu tính năng và hiệu suất cao.