PHP: как заставить свойство метода быть целым числом?

Мой текущий способ:

class A {
    public function function_b($myint) {
        if (!is_numeric($myint)) return false;

        // code ...
    }
}

Я хотел бы отказаться от функции is_numeric() следующим образом:

public function function_b(Integer $myint) {
    // code ...
}

Он работает с массивами следующим образом:

public function function_c(Array $arr) {
    // only executes following code if $arr is an array / instance of Array!
}

Примечание: функция должна возвращать false, если значение не является числом (int)! Я не хочу бросать это.

Как бы вы сократили мой текущий код? Заранее спасибо!


person Mr. B.    schedule 07.12.2012    source источник


Ответы (4)


Вы не можете форсировать строгие типы в прототипах функций в PHP по своей сути, потому что это не строго типизированный язык. PHP — язык со слабой типизацией, и во многих ситуациях попытка пойти против течения только навредит вам. Кроме того, is_numeric не гарантирует, что ваше значение имеет тип int (как оно того стоит).

Что вы можете сделать, так это проанализировать свои потребности, почему вы считаете, что этот подход необходим в первую очередь, и решить, как лучше всего реализовать его, не создавая возможности для ошибок.

Например, возьмем следующий сценарий, в котором ваш метод ожидает идентификатор для запроса к базе данных.

class MyClass {
    public function getUser($id) {
        if (!is_int($id)) {
            throw new Exception("Invalid argument supplied. Expecting (int), but argument is of type (" . gettype($id) . ").");
        }
        // Otherwise continue
        $db = new PDO($dsn);
        $stmt = $db->prepare("SELECT username FROM users WHERE user_id = ?");
        $stmt->execute(array($id));
        $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
        return $result;
    }
}

$MyObject = new MyClass;
$result = $MyObject->getUser($_POST['id']);
/* The problem here is $_POST will always be of type string. */

Это должно сказать вам, что здесь нет смысла принудительно проверять типы, поскольку PHP сделал бы для вас правильную вещь, если бы вы просто оставили его в покое.

Вы должны задать себе вопрос не "Как мне принудительно ввести строгую типизацию?", а скорее "Зачем мне вообще принудительно применять строгую типизацию?".

person Sherif    schedule 07.12.2012
comment
Ваш пример показывает мой сценарий 1:1! К сожалению, кажется, что я не могу отказаться от is_int() или is_numeric(). - person Mr. B.; 07.12.2012
comment
Почему это? Вам нужно объяснить свой вариант использования, иначе я могу только догадываться, что вы пытаетесь сделать. По моему опыту, в PHP нет необходимости принудительно проверять типы. В этом сценарии, если я никогда не проверяю тип, в коде все равно не будет абсолютно ничего плохого, и он будет работать так, как я ожидаю, независимо от того, является ли тип значения строкой, int или чем-то еще. Код сделает все правильно. - person Sherif; 07.12.2012
comment
В PHP 7 добавлена ​​необязательная строгая типизация для скаляров. - person OCDev; 10.02.2016

Вы должны изучить приведение типов:

Просто используйте (int) при доступе к значению, чтобы привести его к целому числу.

person cryptic ツ    schedule 07.12.2012
comment
Спасибо за ваш ответ! Приведение типов - это не то, что мне нужно, я объяснил свою проблему ответом ниже. - person Mr. B.; 07.12.2012

Вы можете просто ввести его:

public function function_b($myint) {
    $myint = (int) $myint;
}

Или еще лучше добавьте общедоступный сеттер к class A, который будет делать это за вас каждый раз, когда вы устанавливаете значение:

class A
{
    public function setMyInt($myInt)
    {
        $this->myInt = (int) $myInt;
    }
}

-- Обновление (на основе комментария) --

class A
{
    public function doSomethingWithAnArray(array $array)
    {
        ....
    }
}

Обратите внимание на ключевое слово array в сигнатуре метода doSomethingWithAnArray, теперь, если вы не передадите массив этой функции, PHP выдаст фатальную ошибку и прекратит выполнение кода. Это известно как подсказка типов и может применяться и к объектам.

person Mike Purcell    schedule 07.12.2012
comment
Спасибо за ваш ответ. Я знаю о приведении, но, кажется, забыл упомянуть, что мой метод должен возвращать false, когда значение не является целым числом. function(Array $myarr = array()), если $myarr не является массивом или экземпляром Array. Надеюсь, вы понимаете, что я имею в виду. Спасибо! :) - person Mr. B.; 07.12.2012
comment
Вы ничего не упомянули о массивах, вы можете указывать массивы. Обновленный пост. - person Mike Purcell; 07.12.2012
comment
Извините, я забыл несколько слов в своем последнем ответе - слишком много кофе, слишком мало сна. Я обновил пост. Спасибо и еще раз извините! - person Mr. B.; 07.12.2012

function needsInteger($int) {
    if (((int) $int) != $int) return false;
    // ...
}

Преимущество здесь в том, что вы по-прежнему можете принимать нестрогие типизированные параметры, но нестрогая проверка на равенство приведенному значению даст приемлемый результат.

person Dan Lugg    schedule 07.12.2012