2012-03-02 39 views
6

Tôi có một lớp:cách sử dụng hằng số từ lớp như một định nghĩa đối số trong hàm php?

class FetchMode 
{ 
const FetchAll = 0; 
const FetchOne = 1; 
const FetchRow = 2;} 

và một chức năng:

function getRecordSet(FetchMode $FetchMode){ some switch cases } 

Tôi muốn sử dụng $ FetchMode như tiêu chí trường hợp chuyển đổi nhưng nhận một lỗi: catchable lỗi nghiêm trọng: Đối số truyền cho getRecordSet() phải là một thể hiện của FetchMode, số nguyên được cho là

đây là cách tôi gọi một hàm:

getRecordSet(FetchMode::FetchOne); 

Tôi muốn cung cấp danh sách các lựa chọn có thể có khi gọi một hàm. Có thể trong php không?

+0

FetchMode :: FetchOne giải quyết thành 1, vì vậy bạn thực sự chuyển 1 cho hàm, chứ không phải đối tượng của loại FetchMode. Tôi không biết bạn muốn đạt được điều gì, nhưng hãy nhớ rằng bạn phải truyền một đối tượng kiểu FetchMode đến hàm của bạn, vì vậy bạn cần một số loại '' $ fm = new FetchMode(); '' – Sgoettschkes

Trả lời

8

Bạn đã hinted PHP để mong đợi một thể hiện của FetchMode (giống như nó nói trong thông báo lỗi), nhưng FetchMode::FETCH* đi hằng giá trị. Bạn sẽ phải sử dụng một số loại Enum instance (mà chúng ta không có trong PHP. (Oh well, có SplEnum nhưng ai sử dụng nó?)) Hoặc thay đổi chữ ký phương thức để loại trừ typehint.

Tuy nhiên, thay vì Switch/Case, bạn có thể solve this more easily via PolymorphismStrategy pattern, ví dụ: thay vì làm một cái gì đó giống như

public function getRecordSet($mode) 
{ 
    switch ($mode) { 
     case FetchMode::ALL: 
      // code to do a fetchAll 
      break; 
     case FetchMode::ONE: 
      // code to do a fetchOne 
      break; 
     default: 
    } 
} 

đó sẽ làm tăng Cylcomatic Complexity của lớp và các lực lượng của bạn thay đổi lớp đó và FetchMode bất cứ khi nào bạn cần phải thêm FetchModes bổ sung, bạn có thể làm:

public function getRecordSet(FetchMode $fetchModeStrategy) 
{ 
    return $fetchModeStrategy->fetch(); 
} 

và sau đó đã một bê tông FetchMode lớp interface để protect the variation

interface FetchMode 
{ 
    public function fetch(); 
} 

và thêm es cho mỗi hỗ trợ FetchMode

class FetchOne implements FetchMode 
{ 
    public function fetch() 
    { 
     // code to fetchOne 
    } 
} 
class FetchAll … 
class FetchRow … 

Bằng cách này, bạn sẽ không bao giờ phải chạm vào lớp với phương thức getRecordSet một lần nữa bởi vì nó sẽ làm việc cho bất kỳ lớp thực hiện mà FetchMode inteface.Vì vậy, bất cứ khi nào bạn có FetchModes mới, bạn chỉ cần thêm một lớp mới, đó là nhiều hơn nữa duy trì trong thời gian dài.

0

Tôi không biết những gì bạn có ý nghĩa bởi

would like to offer a list of possible choices in calling a function. Is it possible in php?

nhưng đối với một phần lỗi: Hãy tưởng tượng bạn có một var, ví dụ $foo. Khi bạn làm echo $foo bạn không nhận được tên của var nhưng giá trị của nó. Điều này là do một var có một tên và các điểm cho một giá trị. Mỗi truy cập vào var về cơ bản trả về giá trị nó trỏ tới. Nó giống với hằng số; Bạn đặt tên hằng số trong đó, nhưng về cơ bản bạn đang trỏ đến giá trị được lưu trữ của bạn. Có nghĩa là getRecordSet(FetchMode::FetchOne);getRecordSet(1); là giống nhau.

Vì vậy, getRecordSet(FetchMode $FetchMode) tăng must be an instance of FetchModeFetchMode::FetchOne trỏ đến số nguyên.

Để khắc phục điều này, bạn cần sử dụng getRecordSet(int $FetchMode).

+0

Tôi không ' Tôi muốn buộc các nhà phát triển khác phải biết lựa chọn nào có giá trị nào. Đó là lý do tại sao tôi đang cố gắng sử dụng functionname (FetchMode :: FetchOne) thay vì functionname (1) – dllhell

+1

họ không cần phải biết. Bạn vẫn có thể sử dụng 'FetchMode :: FetchOne' nhưng khai báo hàm của bạn vẫn nhận' int' và không phải là 'FetchMode' làm đối số (vì đối số của bạn trỏ tới' int' và không phải là một thể hiện 'FetchMode') trừ khi bạn đang sử dụng một số mẫu chiến lược như Gordon giải thích trong câu trả lời của mình. – pduersteler

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