У меня есть класс:
class FetchMode { const FetchAll = 0; const FetchOne = 1; const FetchRow = 2;}
и функция:
function getRecordSet(FetchMode $FetchMode){ some switch cases }
Я хотел бы использовать $ FetchMode в качестве критерия ключа коммутатора, но получаю ошибку: Catchable fatal error: Аргумент, переданный getRecordSet (), должен быть экземпляром FetchMode, целочисленным заданным
так я называю функцию:
getRecordSet(FetchMode::FetchOne);
Я хотел бы предложить список возможных вариантов вызова функции. Возможно ли это в php?
Вы намекали, что PHP ожидает экземпляр FetchMode
(как и в сообщении об ошибке), но FetchMode::FETCH*
передает постоянное значение . Вам нужно будет использовать какой-то экземпляр Enum (который у нас нет на языке PHP. (Ну, есть SplEnum
но кто это использует?)) Или измените подпись метода, чтобы исключить typehint.
Однако вместо коммутатора / случая вы можете легко решить это с помощью полиморфизма и шаблона стратегии , например, вместо того, чтобы делать что-то вроде
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: } }
который увеличит Cylcomatic Complexity вашего класса и заставит изменения в этом классе и FetchMode
всякий раз, когда вам нужно добавить дополнительные FetchModes, вы можете сделать:
public function getRecordSet(FetchMode $fetchModeStrategy) { return $fetchModeStrategy->fetch(); }
и затем иметь интерфейс для защиты вариации
interface FetchMode { public function fetch(); }
и добавьте конкретные классы FetchMode
для каждого поддерживаемого FetchMode
class FetchOne implements FetchMode { public function fetch() { // code to fetchOne } } class FetchAll … class FetchRow …
Таким образом, вам больше не придется касаться класса с помощью этого метода getRecordSet
потому что он будет работать для любого класса, реализующего эту FetchMode
FetchMode. Таким образом, всякий раз, когда у вас есть новые FetchModes, вы просто добавляете новый класс, который в конце концов гораздо удобнее обслуживать.
Я не знаю, что вы подразумеваете под
хотел бы предложить список возможных вариантов вызова функции. Возможно ли это в php?
но для части ошибки: представьте, что у вас есть var, например $foo
. Когда вы выполняете echo $foo
вы не получаете имя var, а его значение. Это связано с тем, что var имеет имя и указывает на значение. Каждый доступ к var в основном возвращает значение, на которое указывает. То же самое с константами; Вы помещаете там постоянное имя, но в основном вы указываете на свое сохраненное значение. Что означает getRecordSet(FetchMode::FetchOne);
и getRecordSet(1);
та же.
Таким образом, getRecordSet(FetchMode $FetchMode)
рейз must be an instance of FetchMode
потому что FetchMode::FetchOne
указывает на целое число.
Чтобы исправить это, вам нужно использовать getRecordSet(int $FetchMode)
.