Truy cập thuộc tính động PHP

Các tính năng này được thực hiện thông qua các tính năng Magic Methods của PHP 5, cho phép các nhà phát triển cung cấp các phương thức đặc biệt để xử lý các lệnh gọi phương thức hoặc truy cập thuộc tính không xác định trên một đối tượng PHP và chuyển đổi chuỗi tự động, trong số những thứ khác

Tính khả dụng của các phương thức ma thuật chỉ được đảm bảo kể từ khi WordPress bắt đầu yêu cầu PHP 5 kể từ phiên bản 3. 2 – MasterPress tận dụng tối đa yêu cầu cơ bản mới này

Hiểu được lợi ích mà các phương pháp ma thuật mang lại được minh họa rõ nhất bằng một ví dụ. Giả sử chúng ta có một loại bài đăng có tên là “ô tô” để gói gọn thông tin chi tiết về ô tô và loại bài đăng này được thiết lập trong MasterPress để có một trường được đặt chi tiết với .

Hình 1. Bộ trường chi tiết

Truy cập thuộc tính động PHP

Bây giờ, hãy xem mã mà chúng ta có thể sử dụng để đưa thông tin này vào một mẫu duy nhất cho loại bài đăng này, ví dụ: đây có thể là một khối mã bên trong  xe đơn. tệp mẫu php .

ví dụ 1. Mã chủ đề cho bộ trường chi tiết ô tô

Có một số điều cần lưu ý ở đây

  • Đầu tiên, $wf->the sử dụng WOOF. phương thức lấy bài đăng hiện tại (dòng 1 và 3), trả về đối tượng WOOF_Post.
  • $wf->the là một lệnh gọi phương thức, nhưng không có dấu ngoặc nhọn “ () . API của chúng tôi cho phép điều này bằng cách định tuyến quyền truy cập thuộc tính trên “the” đến phương thức “the”. Tương tự như vậy đối với lệnh gọi “title”, đây cũng là một phương thức (dòng 1). Điều này là hoàn toàn tùy chọn, nhưng nó làm cho mã rất dễ đọc.
  • “details” (dòng 3) chắc chắn không phải là thuộc tính của the , là một WOOF_Post, nhưng nó thực sự sẽ truy xuất trường của chúng ta . Điều này có thể thực hiện được nhờ phương pháp ma thuật của PHP, định tuyến quyền truy cập thuộc tính đó vào tập trường của chúng tôi.
  • Tương tự như vậy đối với ảnh (dòng 5), làm . year (line 9), detailed_description (line 12), and other_models (line 16) – none of these are declared or assigned properties of $details ( a MEOW_FieldSetCollection ) but they will give us our field objects.
  • Phương pháp thay đổi kích thước của ảnh (dòng 5) . Đây là công việc của phương thức kỳ diệu của PHP, mà WOOF_Image triển khai để chuyển đổi hình ảnh thành thẻ HTML.
  • ảnh , năm , detailed_description, other_models, are MEOW_Field objects, but echoing these gives us their string content – again, __toString is the magic behind this.

Để so sánh, hãy viết mã này một lần nữa với các lời gọi phương thức rõ ràng hơn, điều này sẽ minh họa nhiều hơn về điều kỳ diệu xảy ra đằng sau hậu trường

ví dụ 2. Mã chủ đề chi tiết hơn cho bộ trường chi tiết ô tô

Một điểm quan trọng cần lưu ý về các thuộc tính động là bạn luôn có thể dự phòng gọi các phương thức một cách rõ ràng để lấy thông tin mình muốn và có một tình huống cụ thể mà bạn sẽ cần…

báo trước. Chuyển đổi chuỗi và biến

Như chúng ta đã thảo luận, phương thức kỳ diệu của PHP được sử dụng để tự động chuyển đổi các đối tượng trường và hình ảnh thành dạng chuỗi phù hợp hơn khi lặp lại chúng vào các mẫu của bạn. Tuy nhiên, điều quan trọng là, chuyển đổi chuỗi tự động trong PHP sẽ chỉ được thực hiện khi đối tượng được sử dụng trong ngữ cảnh yêu cầu chuyển đổi thành chuỗi – thực tế, thường là khi lặp lại một giá trị

Giả sử rằng bạn cần viết mã sử dụng giá trị của một trường trong một thao tác khác – ví dụ: giả sử bạn có một mảng giá trị kết hợp và bạn muốn sử dụng giá trị của trường có tên là “khóa” trong một tập hợp trường có tên . Bạn có thể muốn viết mã như thế này

ví dụ 3. __toString không phải lúc nào cũng được gọi

Điều này sẽ không thực sự làm những gì bạn nghĩ, vì $key không bao giờ được coi là một chuỗi trong mã này, nó là một đối tượng MEOW_Field. PHP không thể tự động chuyển đổi nó, vì nó không thực sự biết ý định của bạn là gì và sẽ cho rằng bạn đang cố sử dụng đối tượng làm đối tượng ở đây. Thay vào đó, những gì bạn cần làm là

PHP8. 2 có những gì có khả năng là một sự phản đối cực kỳ gây rối của các thuộc tính động. Điều này được sử dụng thông qua lõi và có khả năng gây ra nhiều vấn đề. Rõ ràng là việc không dùng nữa không _break_ các trang web nhưng chúng sẽ đưa ra các cảnh báo vào môi trường nhà phát triển để nắm bắt các lỗi không dùng nữa và chặn hỗ trợ cho PHP 9, nơi chúng sẽ có lỗi

https. //wiki. php. net/rfc/deprecate_dynamic_properties

Các bước tái sản xuất

Bạn có thể biên dịch php 8. 2 và chạy một trang web và thấy một số thông báo không dùng nữa. Cuối năm 2022 php 8. 2 sẽ được phát hành và chúng ta sẽ thấy chúng trong phpstan và trong quá trình chạy testbot

nghị quyết đề xuất

Danh sách phải có vấn đề để bắt đầu vượt qua bài kiểm tra

- #2839195. Xác định 'bản gốc' là thuộc tính trên đối tượng thực thể

Xong
- #3308744. Khắc phục quyền truy cập thuộc tính kết nối ma thuật từ \Drupal\Core\FileTransfer\FileTransfer. __get()
- #2531564. Khắc phục giải pháp lập số sê-ri vùng chứa bị rò rỉ và dễ gãy
- #3298731. Sử dụng ConstraintViolation. lỗi $array PropertyPath trên PHP 8. 2
- #3274474. Sửa lỗi 'Truy cập vào thuộc tính không xác định' PHPStan L0 - để vượt qua phpstan

Và có thể có (có thể được gia hạn)
- #3299855. [META] Loại bỏ thuộc tính #[\Allow Dynamic Properties] - rất nhiều vấn đề phụ để xác định tất cả các thuộc tính

Các bản sửa lỗi sẽ khác nhau. Đối với các đối tượng dữ liệu, chúng ta có thể thêm thuộc tính #[AllowDynamicProperties] vào lớp hoặc có một cách hack đơn giản mà chúng ta có thể áp dụng để hỗ trợ


  /**
   * Raw row data.
   *
   * @var array
   */
  private array $data = [];

  /**
   * Implements the magic method for getting object properties.
   *
   * @param $name
   *   Property name.
   *
   * @return mixed
   *   The property value.
   */
  public function &__get($name) {
    return $this->data[$name];
  }

  /**
   * Implements the magic method to determines whether a property is set.
   *
   * @param $name
   *   Property name.
   *
   * @return bool
   *   True if property is set.
   */
  public function __isset($name) {
    return isset($this->data[$name]);
  }

  /**
   * Implements the magic method to set a property.
   *
   * @param $name
   *   Property name.
   * @param mixed $value
   *   The property value.
   */
  public function __set($name, $value) {
    $this->data[$name] = $value;
  }

  /**
   * Implements the magic method to unset a property.
   *
   * @param $name
   *   Property name.
   */
  public function __unset($name) {
    unset($this->data[$name]);
  }

Một số thứ không còn hoạt động nữa #2531564. Khắc phục giải pháp lập số sê-ri công-te-nơ dễ gãy và rò rỉ

nhiệm vụ còn lại

  • Tạo nhiệm vụ cho các vấn đề
  • Sửa chữa các vấn đề

Thay đổi giao diện người dùng

không có. Điều này chỉ ảnh hưởng đến giao diện mã

thay đổi API

Hầu hết các thay đổi phải dành cho các đối tượng dữ liệu hoặc chỉ thiếu các thuộc tính nên hy vọng sẽ hạn chế. Tôi hy vọng điều này sẽ tạo ra một số mùi mã có thể dẫn đến việc không dùng nữa. Ngoài ra, chúng tôi có thể tìm thấy những thay đổi khó khăn khác như bộ chứa dịch vụ của chúng tôi yêu cầu các bản sửa lỗi phức tạp