Làm cách nào để bạn gọi một phương thức riêng tư từ một lớp trong php?

Tuần trước, Caleb đã tweet về một chức năng tiện lợi có tên là

invade($myClass)->privateProperty; // returns 'private value'
0 - mà anh ấy đã tạo ra để dễ dàng làm việc với các thuộc tính và phương thức riêng tư

😈 Bạn nghĩ gì về phương pháp trợ giúp yêu thích mới của tôi?

Thuộc tính/phương pháp đó được bảo vệ hay riêng tư? . Twitter. com/HqMXKKpRsJ

– Caleb Porzio (@calebporzio) ngày 11 tháng 2 năm 2022

Anh ấy đã thêm chức năng

invade($myClass)->privateProperty; // returns 'private value'
0 đó vào Livewire. Vì tôi có thể thấy mình đang sử dụng điều này trong các dự án không phải của Laravel, nên tôi đã đóng gói chức năng này trong một gói mới có tên là spatie/invade

Sử dụng gói

Hãy tưởng tượng bạn đã định nghĩa lớp này có thuộc tính và phương thức riêng

class MyClass 
{
    private string $privateProperty = 'private value';

    private function privateMethod(): string
    {
        return 'private return value';
    }
}

$myClass = new Myclass();

Đây là cách bạn có thể lấy giá trị của thuộc tính riêng bằng cách sử dụng hàm

invade($myClass)->privateProperty; // returns 'private value'
0

invade($myClass)->privateProperty; // returns 'private value'

Hàm

invade($myClass)->privateProperty; // returns 'private value'
0 cũng cho phép bạn thay đổi các giá trị riêng tư

invade($myClass)->privateProperty = 'changed value';
invade($myClass)->privateProperty; // returns 'changed value

Sử dụng

invade($myClass)->privateProperty; // returns 'private value'
0, bạn cũng có thể gọi các chức năng riêng tư

invade($myClass)->privateMethod(); // returns 'private return value'

Cách gói hoạt động dưới mui xe

Truy cập các thuộc tính và phương thức riêng có vẻ kỳ diệu, nhưng nó khá dễ đạt được bằng cách sử dụng sự phản chiếu. Trên các lớp phản chiếu của nó, PHP có một phương thức

invade($myClass)->privateProperty; // returns 'private value'
0 có thể công khai những thứ riêng tư trong thời gian chạy

Hàm

invade($myClass)->privateProperty; // returns 'private value'
0 sẽ truyền đối tượng đã cho vào lớp
invade($myClass)->privateProperty; // returns 'private value'
2. Lớp kẻ xâm lược đó có các phương thức
invade($myClass)->privateProperty; // returns 'private value'
3,
invade($myClass)->privateProperty; // returns 'private value'
4 và
invade($myClass)->privateProperty; // returns 'private value'
5 ma thuật sẽ thực thi trên mỗi tương tác với đối tượng đã cho. Trước khi chuyển tiếp cuộc gọi đến đối tượng, nó sẽ được truy cập

Mã nguồn rất nhỏ nên tôi có thể chia sẻ nó đầy đủ trong bài viết này

namespace Spatie\Invade;

use ReflectionClass;

class Invader
{
    public object $obj;
    public ReflectionClass $reflected;

    public function __construct(object $obj)
    {
        $this->obj = $obj;
        $this->reflected = new ReflectionClass($obj);
    }

    public function __get(string $name): mixed
    {
        $property = $this->reflected->getProperty($name);

        $property->setAccessible(true);

        return $property->getValue($this->obj);
    }

    public function __set(string $name, mixed $value): void
    {
        $property = $this->reflected->getProperty($name);

        $property->setAccessible(true);

        $property->setValue($this->obj, $value);
    }

    public function __call(string $name, array $params = []): mixed
    {
        $method = $this->reflected->getMethod($name);

        $method->setAccessible(true);

        return $method->invoke($this->obj, ...$params);
    }
}

Và đó là tất cả để có nó

Bạn có nên sử dụng cái này không?

Tôi không nghĩ bạn nên sử dụng mã này trong mã của các dự án thông thường. Trong bối cảnh đó, bạn sẽ phải thiết kế mã của mình theo cách sao cho mọi thứ nên được gọi đều có thể gọi được dễ dàng

Tôi nghĩ đến ba tình huống mà tôi có thể thấy

invade($myClass)->privateProperty; // returns 'private value'
0 đang được sử dụng

  1. Các gói bên trong bổ sung hành vi kỳ diệu, cụ thể, như Livewire
  2. Bên trong một gói để kiểm tra một số hành vi của chính nó mà không thể truy cập công khai. Ví dụ đầu tiên xuất hiện trong đầu là các phương thức không công khai bên trong một nhà cung cấp dịch vụ trọn gói (mặc dù có thể lập luận rằng cũng nên công khai một phương thức như vậy)
  3. Bên trong bộ thử nghiệm của gói hoặc dự án nơi bạn cần kết nối với trạng thái/hành vi riêng tư của các gói khác. Trong trường hợp này, bạn cũng nên tạo sự cố trên gói khác đó, yêu cầu người bảo trì làm cho trạng thái/hành vi có thể truy cập được theo cách thông thường

Mặc dù bạn có thể tranh luận rằng làm như vậy không phải là một ý tưởng hay, nhưng thật tuyệt khi PHP cho phép tạo các hàm như

invade($myClass)->privateProperty; // returns 'private value'
0

Làm cách nào để gọi phương thức riêng tư từ một lớp khác trong php?

Trình chỉ định truy cập "riêng tư" có nghĩa là chỉ khả dụng trong lớp mà nó được định nghĩa, bạn không thể gọi nó từ bên ngoài lớp mà nó được định nghĩa, kể cả từ một lớp con . Thay vào đó, bạn có thể sử dụng trình xác định quyền truy cập "được bảo vệ" sẽ có sẵn cho các lớp con nhưng không có sẵn cho các lớp khác. . You can maybe use the "protected" access specifier instead which will be available to the child classes as well but not the other classes.

Làm cách nào để sử dụng phương thức riêng tư trong php?

Từ khóa riêng tư là công cụ sửa đổi quyền truy cập. Nó đánh dấu một thuộc tính hoặc phương thức là riêng tư. Các thuộc tính và phương thức riêng chỉ có thể được sử dụng bởi lớp mà thuộc tính hoặc phương thức đó được định nghĩa . Các lớp dẫn xuất và mã bên ngoài không thể sử dụng chúng.

Chúng ta có thể gọi một phương thức riêng tư từ một đối tượng của một lớp không?

Bạn có thể gọi phương thức riêng từ bên ngoài lớp bằng cách thay đổi hành vi thời gian chạy của lớp .

Làm cách nào tôi có thể gọi phương thức riêng tư?

Chúng ta có thể gọi phương thức riêng của một lớp từ một lớp khác trong Java (được định nghĩa bằng công cụ sửa đổi truy cập riêng trong Java). Chúng ta có thể làm điều này bằng cách thay đổi hành vi thời gian chạy của lớp bằng cách sử dụng một số phương thức được xác định trước của Java . Để truy cập phương thức riêng tư của lớp khác, chúng tôi sẽ sử dụng Reflection API.