Đặc điểm php là gì và làm thế nào để bạn sử dụng chúng?

Trong các blog trước đây của tôi Giải thích về giao diện PHP và Giải thích về các lớp trừu tượng PHP, hôm nay tôi sẽ giải thích về Đặc điểm PHP

Trong PHP, một lớp con chỉ có thể kế thừa từ một lớp cha duy nhất. Điều này cho phép một lớp sử dụng lại các phương thức từ hệ thống phân cấp theo chiều dọc bằng cách mở rộng một lớp Trừu tượng

Nếu bạn muốn sử dụng lại các phương thức trong nhiều lớp khác nhau theo thứ bậc theo chiều ngang, chúng tôi sử dụng Traits. Các đặc điểm được sử dụng để nhóm các phương thức và triển khai trong nhiều lớp. Các đặc điểm không thể tự khởi tạo giống như một lớp bình thường có thể

Ví dụ

Giả sử chúng ta muốn kiểm tra xem một người dùng có quyền truy cập vào nhiều lớp hay không

trait Access
{
    public function hasAccess(string $username): bool
    {
        //..Check if $username has access
    }
}

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Mọi người có thể truy cập Tệp đều được phép tải xuống. Để sử dụng Đặc điểm này vào lớp học của chúng tôi

class File
{
    use Access;

    public function download(string $username): Response
    {
        if ($this->hasAccess($username)) {
            //..Download file x
        }
    }
}

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Bất cứ nơi nào bạn triển khai Đặc điểm của mình bằng cách sử dụng Access; . Mà trong trường hợp này chỉ là hasAccess()

đa thừa kế

Điều gì sẽ xảy ra nếu bạn cần nhiều kế thừa để sử dụng lại các phương thức khác nhau trong nhiều lớp khác nhau theo phân cấp theo chiều ngang?

Điều này được thực hiện dễ dàng, hãy tạo một cái khác

trait Ability
{
    public function canUpload(string $username): bool
    {
        //..Check if $username can upload
    }
}

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Chúng tôi muốn kiểm tra xem $username của chúng tôi có thể truy cập các tệp và cũng được phép tải lên không

class File
{
    use Access, Ability;

    public function upload(string $username): Response
    {
        if ($this->hasAccess($username) && $this->canUpload($username)) {
            //..Upload file
        }
    }
}

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Tadaa. Như bạn có thể thấy, các Đặc điểm được triển khai dễ dàng và được sử dụng tự do ở mọi nơi bạn muốn trong dự án của mình

Một đặc điểm PHP cho phép bạn lưu trữ một tập hợp các phương thức thuộc tính để dễ dàng sử dụng lại trong các lớp có thể cần đến chúng. Thuật ngữ "đặc điểm" có thể được hiểu theo nghĩa đen, vì nó được sử dụng để xác định một 'đặc điểm' được chia sẻ giữa nhiều lớp

Điều này không có nghĩa là mọi thứ đều phù hợp với một đặc điểm. Tôi đã suy nghĩ về chủ đề này trong vài tháng và tôi vẫn chưa quyết định hoàn toàn về cách sử dụng chúng tốt nhất. Nhưng, có vẻ như, ít nhất, một cách sử dụng phù hợp là để xác định các phương pháp ma thuật

Ví dụ: có thể bạn đang định nghĩa các phương thức ma thuật như __get hoặc __set cho nhiều lớp; . Điều này là tốt DRY (Đừng lặp lại chính mình)

Dưới đây là một đặc điểm ví dụ đơn giản mà tôi đã tạo để ngăn việc thêm các thuộc tính vào các thể hiện của lớp

namespace doorkeeper\lib\class_traits;
trait no_set {
    public function __set($name, $value) {
      throw new \Exception("Adding new properties is not allowed on " . __CLASS__);
    }
}

Để sử dụng đặc điểm trong các lớp khác

class some_class {
  public $message = 'hallo';
  public function show_message() {
    echo $this->$message;exit();
  }
  use \doorkeeper\lib\class_traits\no_set;
}

Cố gắng tạo một thuộc tính mới thông qua $some_class->some_new_property = 'value';, sau khi khởi tạo lớp, giờ đây sẽ kích hoạt một ngoại lệ; . Tôi. e. $some_class->message = 'tạm biệt';

Thừa kế vs Đặc điểm

Cá nhân tôi có xu hướng sử dụng Dependency Injection để chia sẻ mã giữa các lớp và tránh sử dụng tính kế thừa và đặc điểm;

Nếu bạn không sở hữu mã, bạn có thể cân nhắc sử dụng phần mở rộng, ít nhất là vì một vài lý do

  1. Việc mở rộng một lớp có thể dễ dàng hơn là sửa đổi toàn bộ quá trình triển khai
  2. Nó giữ cho mã của riêng bạn tách biệt rõ ràng với mã trong lớp mà bạn đang mở rộng
  3. Nếu lớp được cập nhật, mã của bạn sẽ hiếm khi ngừng hoạt động và nếu có, việc sửa lỗi sẽ dễ dàng hơn
  4. Hiếm khi mở rộng mã của riêng bạn khi bạn có thể làm việc trực tiếp với nó

Bạn không nên sử dụng các đặc điểm để thay đổi mã của những người khác, vì nó sẽ yêu cầu thực hiện các sửa đổi đối với lớp ban đầu—thay vào đó, hãy sử dụng các phần mở rộng để "mở rộng" mã của họ

Không sử dụng các đặc điểm như một cách sao chép mã có mục đích chung thường được sử dụng lại. Cân nhắc xem mã có phù hợp hơn trong một lớp chuyên dụng mà bạn có thể sử dụng lại và khởi tạo độc lập hay không—sau đó cung cấp mã này thông qua DI khi cần

Tiêm phụ thuộc vs Đặc điểm

Tôi không thực sự nghĩ rằng có một sự cạnh tranh. Bất cứ khi nào tôi cân nhắc sử dụng các đặc điểm cho một thứ gì đó, tôi luôn kết thúc việc tái cấu trúc nó thành DI sau đó. Lý do chính của tôi là thường có một lợi ích to lớn trong việc có thể khởi tạo mã một cách độc lập

Tất cả những khai báo sử dụng đó cũng là một vấn đề tái cấu trúc đang chờ xảy ra. Nếu một đặc điểm được di chuyển, bạn sẽ cần cập nhật tất cả các lớp sử dụng nó. Với DI, bạn chỉ cần chuyển đối tượng từ một vị trí trung tâm, chẳng hạn như gốc thành phần của bạn—việc di chuyển tệp lớp gốc sẽ không làm hỏng ứng dụng của bạn ở nơi khác

Nhiều người không thích DI vì họ cần chuyển qua danh sách dài các phụ thuộc; . Nếu dự án của bạn phát triển đủ lớn, thì bạn có thể thấy rằng một số đối tượng thực tế được sử dụng "toàn cầu" trong suốt dự án của bạn;

Một tùy chọn khác là tạo các lớp xuất xưởng để tạo các đối tượng của bạn. Bên trong chúng, bạn có thể tạo các phụ thuộc trực tiếp bằng cách sử dụng từ khóa mới. Như đã nói, nói chung không nên tạo các phụ thuộc bên trong các lớp phụ thuộc vào chúng, vì nếu có gì đó thay đổi, bạn có thể cần phải cập nhật tất cả các lớp sử dụng các phụ thuộc đó—khi thực hiện bên trong lớp xuất xưởng thì lại là một vấn đề khác,

Ghi chú. "Nhà máy" chỉ là một thuật ngữ được sử dụng để mô tả chức năng của một lớp PHP thông thường. Ví dụ: không có từ khóa "nhà máy" trong PHP. Một nhà máy chỉ đơn giản là một đối tượng được sử dụng để tạo ra các đối tượng khác

Các đặc điểm có thể vẫn có một số công dụng, tôi chưa thực sự tìm thấy chúng. Hiện tại chỉ có một tình huống mà tôi đang sử dụng các đặc điểm và đó là khi thay đổi hành vi của một số phương thức ma thuật nhất định do PHP triển khai. Tôi nghĩ rằng nên ngăn người dùng sửa đổi các đối tượng được khởi tạo của chúng tôi và vì mục đích này, tôi đã tạo một đặc điểm mà tôi sử dụng trong các lớp mà tôi không muốn thay đổi

trait no_set {
    public function __set($name, $value) {
      throw new Exception("Adding new properties is not allowed on " . __CLASS__);
    }
}

Theo cách này, các đặc điểm có thể là một cách rất hữu ích để tránh lặp lại khi mã hóa. Tuy nhiên, trong hầu hết các trường hợp, bạn có thể sẽ được hưởng lợi nhiều hơn khi sử dụng DI (Tiêm phụ thuộc) trong thời gian dài hơn

Đặc điểm là cách nó được sử dụng trong PHP là gì?

Trong PHP, một đặc điểm là một cách cho phép các nhà phát triển sử dụng lại các phương thức của các lớp độc lập tồn tại trong các hệ thống phân cấp thừa kế khác nhau . Nói một cách đơn giản, các đặc điểm cho phép bạn tạo các phương thức mong muốn trong cài đặt lớp, sử dụng từ khóa đặc điểm. Sau đó, bạn có thể kế thừa lớp này thông qua từ khóa sử dụng.

Khi nào tôi nên sử dụng trait trong PHP?

Nếu bạn muốn sử dụng lại một số mã giữa nhiều lớp, sử dụng một đặc điểm là một cách thay thế để mở rộng lớp. .
Một đặc điểm có thể giúp bạn tiết kiệm một số thao tác sao chép/dán thủ công bằng cách cung cấp tính năng sao chép/dán thời gian biên dịch thay thế

Khi nào bạn có thể sử dụng các đặc điểm?

Khi nào nên sử dụng Đặc điểm? . Rốt cuộc đó không phải là hành vi có thể tái sử dụng. Nếu nó có thể được sử dụng lại trong nhiều lớp không liên quan, hãy biến nó thành một đặc điểm. If the behavior will not be reused, then make it a concrete class. It is not reusable behavior after all. If it might be reused in multiple, unrelated classes, make it a trait.

Đặc điểm PHP có tốt không?

Các đặc điểm PHP là tốt . Thay vào đó, các giao diện được cung cấp thay thế và một giao diện không thành công ở đó. Các giao diện không nhằm mục đích sử dụng theo cách này, thay vào đó hoạt động như các hợp đồng buộc bất kỳ lớp nào triển khai nó cung cấp chức năng của nó.