2011-12-07 32 views
7

Chúc mọi người vui vẻ!PHP: Thuộc tính chỉ đọc tĩnh trong lớp

Vấn đề của tôi là: Tôi cần quá tải chuẩn và đặt cho các biến tĩnh trong lớp ... nhưng không có chức năng nào được cung cấp trong php ... nó được hỏi vào năm 2008 và vẫn chưa được triển khai ... ...

Câu hỏi của tôi: có cách nào để tạo thuộc tính tĩnh có thể đọc được từ bên ngoài, nhưng được bảo vệ khỏi sửa đổi không?

echo aaa::$qwe; //<--- echoes value of $qwe 
aaa::$qwe = '666'; //<--- throws an error because variable is protected from modification 

Tôi không thể sử dụng const vì một số biến chứa mảng.

Có thể có một số cách giải quyết?

Yeah, tôi biết tôi có thể làm cho nó như aaa :: Nhận ('qwe') nhưng đó là không tốt ...

+2

Tại sao nó không tốt? – Artefacto

+0

Bởi vì tôi sẽ cần phải thay đổi 2MB của cơ sở mã hiện có, và cũng không sạch sẽ, cộng với có những lý do khác không phụ thuộc vào tôi :) – NewProger

+1

Tại sao không sử dụng một hằng số lớp? Hoặc biến sẽ được sửa đổi nội bộ? – mAu

Trả lời

1

Nếu giá trị không bao giờ thay đổi, bạn có thể sử dụng const để thay thế. Nếu không, không có cách nào thỏa mãn các hạn chế của bạn (thiếu các hàm gọi hàm trong PHP thông qua phần mở rộng, nhưng thậm chí bạn cần phải thay đổi các truy cập biến tĩnh của bạn thành các cuộc gọi hàm; nếu không, bạn phải vá PHP).

Tất nhiên, rất đáng ngờ rằng những gì ứng dụng của bạn đang làm là thiết kế tốt. Dựa vào việc thay đổi các thuộc tính tĩnh ít nhiều giống như dựa vào các biến toàn cầu.

+0

Vâng, đó là những gì tôi phải sống với :) Hiện tại codebase ... Và tiếc là tôi không thể sử dụng const vì một số biến lưu trữ mảng ... – NewProger

+1

Nếu thiết kế cho phép thay đổi như vậy, bạn có thể lưu các mảng dưới dạng CSV, hoặc có thể được mã hóa JSON: 'const $ qwe = '[" 666 "]'' – KingCrunch

+0

Hm, đó thực sự là ý tưởng thú vị! – NewProger

4

Trả lời trực tiếp câu hỏi của bạn: Không, bạn không thể đánh dấu các thuộc tính thông thường là chỉ đọc. Nếu bạn muốn thiết lập các kiểu dữ liệu (trừ array), rằng sẽ không bao giờ thay đổi, bạn nên sử dụng hằng

const QWE = '666'; 

Điều đó không làm việc cho các đối tượng và mảng. Tôi thấy hai (cho phép nói) "giải pháp"

  1. Sử dụng Getter

    private $qwe; 
    public function getQwe() { return $this->qwe; } 
    protected function setQwe($value) { $this->qwe = $value; } 
    

    tôi không thích họ rất nhiều ("Properties xác định trạng thái, không phải hành vi, như phương pháp làm") . Bạn luôn nhận được gấp đôi các phương thức bổ sung như các thuộc tính và nếu bạn có nhiều thuộc tính, điều này sẽ vô cùng phá hủy lớp của bạn. Tuy nhiên, nó như xa như tôi có thể thấy cách duy nhất để thực hiện những gì bạn muốn đạt được.

  2. Tin tưởng người dùng của bạn;) Bình luận thuộc tính của bạn và nói điều gì đó như "Nếu bạn thay đổi giá trị này, có thể sẽ có sự cố và lỗi của chính bạn".

    /** 
    * QWE 
    * 
    * This property should be treatened as "readonly". If you change this value 
    * something scary will happen to you. 
    * 
    * @readonly 
    * @var string 
    */ 
    public $qwe = '666'; 
    

    Không tuyệt vời, nhưng ít nhất bạn có thể nói "Tôi đã nói với bạn".

+0

Chỉ có tùy chọn 2 là có thể :) Nhưng để lại các biến rất quan trọng như vậy là không tốt :) – NewProger

+0

Tin tưởng người dùng của bạn ... (Hãy đọc tiếp)!? (Chờ một phút dahell tôi vừa đọc ??!) .. (Facepalm) .Đó là điều thú vị nhất mà tôi đã đọc cả ngày !! – Sebastien

+0

@Sebastien Tôi không biết ... whats the funny part? Bạn biết đấy, rằng với "người dùng" tôi có nghĩa là các nhà phát triển khác và không phải là khách truy cập của ứng dụng? Và bạn biết đấy, rằng nếu họ "không đáng tin cậy" thì họ tự bắn vào chân mình. Không có gì bạn phải quan tâm;) – KingCrunch

0

Đây là một chút dễ dàng hơn:

class aaa{ 
private static $qwe='rty'; 
public static function qwe() { return self::$qwe; } 
} 

Nó không cho phép thay đổi, và vẫn còn dễ dàng để truy cập:

aaa::$qwe = 'something'; // fails 
echo aaa::qwe(); // success 

Tôi biết nó không phải là lý tưởng, nhưng bạn có thể thay thế tất cả

aaa::$qwe 

với

aaa::$qwe() 
+1

-1 Bạn không thể sử dụng '$ this' trong ngữ cảnh đối tượng. – Leri

+0

Cảm ơn Leri, đã sửa đoạn mã đầu tiên từ '$ this-> qwe;' thành 'self :: $ qwe'. xin vui lòng đánh giá lại câu trả lời của tôi nếu bạn cảm thấy nó tốt hơn. –

Các vấn đề liên quan