2009-04-24 26 views

Trả lời

48

Nếu bạn đang sử dụng PHP5 (và bạn nên làm), hãy xem các lớp học SPL ArrayObject. Các tài liệu không phải là quá tốt, nhưng tôi nghĩ rằng nếu bạn mở rộng ArrayObject, bạn sẽ có mảng "giả" của bạn.

EDIT: Đây là ví dụ nhanh của tôi; Tôi e rằng tôi không có trường hợp sử dụng có giá trị mặc dù:

class a extends ArrayObject { 
    public function offsetSet($i, $v) { 
     echo 'appending ' . $v; 
     parent::offsetSet($i, $v); 
    } 
} 

$a = new a; 
$a[] = 1; 
+4

Không chỉ là câu trả lời hữu ích mà là câu trả lời đúng. Tôi sử dụng ArrayObjects tất cả các thời gian, và đó là một cách thanh lịch không chỉ ghi đè lên mảng nhưng để mở rộng toàn bộ mô hình đối tượng và làm cho PHP đá một số mông nghiêm trọng. – AlexanderJohannesen

+11

Không phải là câu trả lời hữu ích hoặc câu trả lời đúng. Câu hỏi đặt ra là về quá tải toán tử, không phải là một thư viện có đối tượng được gọi là ArrayObject tồn tại hay không. – fijiaaron

+55

-1 Sử dụng giao diện ArrayAccess. Không mở rộng ArrayObject.Bạn đang thừa hưởng rất nhiều logic của bạn có lẽ không cần và mở rộng thêm ArrayObject là không thể đoán trước trong nhiều khía cạnh, bởi vì có quá nhiều ma thuật liên quan. – NikiC

19

Khái niệm về quá tải và khai thác của PHP (xem OverloadingArray Operators) không giống như khái niệm của C++. Tôi không tin rằng nó có thể quá tải nhà khai thác như +, -, [], vv

Giải pháp có thể

+1

Tốt hơn so với các Iterator là SPL ArrayObject, mà tôi đã liên kết bên dưới. Nó cung cấp toàn bộ hàng loạt chức năng mảng. – cbeer

2

Dường như đây không phải là tính năng của ngôn ngữ, hãy xem số bug này. Tuy nhiên, có vẻ như có một package cho phép bạn thực hiện một số loại quá tải.

+0

Nhìn vào gói, có vẻ như không tương thích với bất kỳ php> 5.5 và chưa được cập nhật kể từ 2013 – Benubird

0

Đặt đơn giản, không; và tôi đề nghị rằng nếu bạn nghĩ rằng bạn cần C++ - quá tải kiểu, bạn có thể cần phải suy nghĩ lại giải pháp cho vấn đề của bạn. Hoặc có thể xem xét không sử dụng PHP.

Để diễn giải Jamie Zawinski, "Bạn có vấn đề và suy nghĩ, 'Tôi biết! Tôi sẽ sử dụng toán tử quá tải!' Bây giờ bạn có hai vấn đề. "

+4

-1 câu trả lời đơn giản là không chính xác, vì nó có thể quá tải toán tử []. Ngoài ra, có khả năng @Chad không cố gắng giải quyết vấn đề với quá tải nhà điều hành, nhưng giữ mã của mình gọn gàng và gọn gàng. – Josiah

+1

Đó là lý do tại sao tôi nói "Đặt đơn giản, không" thay vì "Không". Tôi không muốn giải thích rằng bạn làm điều đó bằng cách mở rộng các lớp nhất định theo cách kỳ lạ, bởi vì 1) quá tải toán tử là một ý tưởng tồi tệ ngay cả khi cú pháp để làm nó sạch và 2) cú pháp để thực hiện nó trong PHP isn không sạch. – dirtside

+4

Cần phải suy nghĩ lại về thiết kế của tôi? Vì vậy, nếu tôi muốn làm số học ngày hoặc số học phức tạp, tôi phải sử dụng các cuộc gọi hàm thay vì các toán tử? Kinh quá. –

22

Trên thực tế, các giải pháp tối ưu là để thực hiện bốn phương pháp của giao diện ArrayAccess: http://php.net/manual/en/class.arrayaccess.php

Nếu bạn cũng muốn sử dụng đối tượng của bạn trong bối cảnh 'foreach', bạn sẽ phải thực hiện các Giao diện 'Iterator': http://www.php.net/manual/en/class.iterator.php

+1

+1. Để thực hiện giao diện ArrayAccess là câu trả lời hợp lệ duy nhất cho vấn đề của OP. Tất cả các khác là tối ưu. – hijarian

8

Để có giải pháp đơn giản và sạch trong PHP 5.0+, bạn cần thực hiện bù đắp bù đắp bù đắp, bù đắp, bù đắpBộ lọc. Bây giờ bạn có thể sử dụng đối tượng như một mảng.

Ví dụ:

<?php 
class A implements ArrayAccess { 
    private $data = array(); 

    public function offsetGet($offset) { 
     return isset($this->data[$offset]) ? $this->data[$offset] : null; 
    } 

    public function offsetSet($offset, $value) { 
     if ($offset === null) { 
      $this->data[] = $value; 
     } else { 
      $this->data[$offset] = $value; 
     } 
    } 

    public function offsetExists($offset) { 
     return isset($this->data[$offset]); 
    } 

    public function offsetUnset($offset) { 
     unset($this->data[$offset]); 
    } 
} 

$obj = new A; 
$obj[] = 'a'; 
$obj['k'] = 'b'; 
echo $obj[0], $obj['k']; // print "ab" 
+1

Đây là câu trả lời hay nhất (chính xác nhất) liên quan đến câu hỏi OP. Nếu bạn đơn giản muốn sử dụng toán tử '[]' trên đối tượng của mình, việc thực hiện giao diện 'ArrayAccess' là cách để đi. –

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