2013-02-11 12 views
10

Có thể cho phép một Array hoặc một đối tượng triển khai ArrayAccess không?Loại PHP gợi ý cho phép Array hoặc ArrayAccess

Ví dụ:

class Config implements ArrayAccess { 
    ... 
} 

class I_Use_A_Config 
{ 
    public function __construct(Array $test) 
    ... 
} 

Tôi muốn để có thể vượt qua trong hoặc một mảng hoặc ArrayAccess.

Có cách nào sạch để thực hiện việc này ngoài cách kiểm tra kiểu tham số theo cách thủ công không?

Trả lời

10

Không, không có cách "làm sạch".

Loại arraykiểu nguyên thủy. Các đối tượng triển khai giao diện ArrayAccess dựa trên các lớp, còn được gọi là loại hỗn hợp . Không có gợi ý loại nào bao gồm cả hai.

Vì bạn đang sử dụng ArrayAccess làm mảng bạn có thể truyền. Ví dụ:

$config = new Config; 
$lol = new I_Use_A_Config((array) $config); 

Nếu đó không phải là một lựa chọn (bạn muốn sử dụng các đối tượng Config vì nó là) sau đó chỉ cần loại bỏ các kiểu gợi ý và kiểm tra xem nó là một trong hai một mảng hoặc một ArrayAccess. Tôi biết bạn muốn tránh điều đó nhưng nó không phải là một vấn đề lớn. Nó chỉ là một vài dòng và, khi tất cả được nói và làm, không quan trọng.

+0

Không phải câu trả lời tôi hy vọng nhưng việc truyền tới một mảng thực sự là một ý tưởng hay. Cảm ơn – Supericy

+0

Đây là một thực tế không tốt, một khách hàng không nên làm những gì thư viện có thể làm. – danidacar

+0

Việc đưa một đối tượng vào mảng không quan tâm ArrayAccess có được triển khai hay không. AFAIK điều duy nhất sẽ thay đổi chức năng đúc là phân lớp lớp ArrayObject. Hy vọng rằng https://wiki.php.net/rfc/union_types làm cho nó trong một ngày nào đó (không liên quan đến đúc rõ ràng, nhưng với câu hỏi của OP);) –

-3

Cũng hỗ trợ php Loại gợi ý cho mảng/đối tượng. Vì vậy, Array sẽ hoạt động tốt. Tuy nhiên, việc truyền một đối tượng ArrayAccess vào phương thức chỉ được phép cho kiểu mảng có thể ném lỗi. ArrayAccess được sử dụng chủ yếu cho mục đích lặp lại đối tượng ArrayAccess theo cách giống như mảng như sử dụng trong foreach.

-1

Chúng có giải pháp thực sự trong PHP 7.1.

http://php.net/manual/en/migration71.new-features.php#migration71.new-features.iterable-pseudo-type

Các iterable pseudo-type là những gì bạn muốn. Bất kỳ mảng hoặc kiểu Traversable nào, (là giao diện cơ bản cho Iterator) sẽ vượt qua kiểm tra này.

Bây giờ, để làm rõ điều này cho bất kỳ ai muốn có siêu sâu, có, sẽ có các trường hợp cạnh. Bạn nên suy nghĩ về những trường hợp cạnh và tự giải quyết chúng, nhưng nếu bạn muốn chắc chắn rằng nếu ai đó vượt qua trong một yếu tố đi qua không thể truy cập thông qua một khóa, bạn có thể làm điều này.

http://php.net/manual/en/function.iterator-to-array.php

Bây giờ bất kể những gì họ vượt qua trong các loại-gợi ý, bạn sẽ có một mảng, nhưng điều này có thể loại bỏ những lợi ích của việc sử dụng một máy phát điện để giảm bộ nhớ. Nó nên rõ ràng, nhưng rõ ràng nó không phải là, vì vậy ở đây nó được. Bạn, lập trình viên, chịu trách nhiệm tìm ra các trường hợp sử dụng cụ thể của bạn cho mã và cách bạn đang lập kế hoạch sử dụng mã đó và trường hợp sử dụng thích hợp là gì đối với mã.

Vì điều này vẫn chưa đủ rõ ràng, giả sử bạn đang cố truyền đạt thứ gì đó có thể gợi ý và mong đợi một phương thức hoặc biến cụ thể tồn tại, khi đó bạn đang lập trình kém. Bạn nên triển khai hợp đồng có loại trả về bạn đang tìm và chuyển loại đó thay vì loại chung. Nếu bạn chỉ muốn làm một cái gì đó chung chung như looping, đó là những gì các loại iterable được cho. Gợi ý có trong tên: Iterate.

+0

Đó không phải là câu trả lời hoàn toàn chính xác. Giao diện lặp đi lặp lại không ngụ ý rằng đối tượng đã cho triển khai thực hiện ArrayAccess (ví dụ: các mục có thể được truy cập bằng khóa). Bạn vẫn cần thực hiện kiểm tra loại bổ sung trong mã của mình. – mancze

+0

Câu hỏi đặt ra là: 'cho phép một Mảng hoặc một đối tượng triển khai ArrayAccess' Có, điều này sẽ cho phép điều đó. Và có, nó sẽ cho phép bạn truy cập nó thông qua một khóa cho bất kỳ loại giả lặp nào. Bất kỳ thành viên nào của Iterator đều có thể được truy cập thông qua. Chìa khóa. Đó là định nghĩa: http://php.net/manual/en/class.iterator.php Gợi ý: Đó là tên gọi là 'khóa'. –

+0

1) Nếu bạn giải thích câu hỏi theo cách này thì không có khai báo kiểu nào cũng phù hợp với câu trả lời (nó cho phép 'mảng' hoặc' ArrayAccess') nhưng chắc chắn không phải là câu trả lời dự định vì nó cho phép nhiều hơn thế. Tương tự cho 'iterable'. 2) Hãy cẩn thận - gợi ý loại 'lặp lại 'có nghĩa là' mảng' hoặc 'Traversable', không phải' Iterator'. Ví dụ 'Generator' là' Traversable' nhưng không thể truy cập các giá trị thông qua khóa. Và nếu bạn nhìn vào ví dụ - ý định là chỉ định khai báo kiểu cho các cấu hình nơi truy cập thông qua khóa có thể là khả năng dự kiến ​​của tham số đã cho. – mancze