Нормально ли проверять одни и те же данные по десять раз?

Доброй ночи.
При разработке, когда имеет место быть внедрение зависимости через аргументы функции или метода, я стараюсь всегда проверить переданные данные и, в случае чего, вернуть false или null. Однако порой один и тот же объект \ массив \ коллекция поочередно пробрасывается через несколько функций, и, соответственно, проверяется в каждой из них. Я в принципе понимаю, что это избыточно, но проверить данные только один раз в точке входа, а в остальном коде полагаться на то, что проверка уже была произведена, совесть не позволяет: что, если кто-то (или я) потом использует метод в обход точки входа, и схватит какой-нибудь fatal error? Очень грубый и натянутый пример того, что я имею в виду.
function a($array) {
    if(!is_array($array) OR !count($array)) return null;
    // code
}
function b($array) {
    if(!is_array($array) OR !count($array)) return null;
    // code
}
function main() {
    $array = get_array();
    // Проверили данные сразу после получения
    if(!is_array($array) OR !count($array)) return null;

    $result1 = a($array); // тут тоже проверка
    $result2 = b($array); // и тут - в принципе, можно бы и выкинуть, т.к. проверка есть выше
}


Стоит ли продолжать заморачиваться с проверкой передаваемых данных в каждой функции?
Спасибо.
  • Вопрос задан
  • 864 просмотра
Решения вопроса 1
index0h
@index0h
PHP, Golang. https://github.com/index0h
Проверять данные в каждом методе - это вполне отличная практика, по сути это соблюдение интерфейса метода.
Но возвращать при этом null/false - практика хреновая, если ваш метод на вход требует int, а получил array - надо бросать исключение. Так вы будете знать, что внешний код, который использует ваш метод работает не корректно.

Для объектов настоятельно рекомендую использовать type hinting:

public function test(MyObject $object, $id)
{
    if (!is_int($id)) {
        throw new \InvalidArgumentException('Argument "id" must be int');
    } elseif ($id < 0) {
        throw new \InvalidArgumentException('Argument "id" must be positive');
    }
...


Если пишете на семерке, то и для скаляров и на вывод - тоже стоит указывать type hinting. Правда с выводом не всегда это можно делать, например возврата null, или что-то еще.

public function checkPositive(int $intData): bool

Для сокращения проверок можете мой пакет заюзать https://packagist.org/packages/ko-ko-ko/assert, он спроектирован под максимальную производительность и использование в каждом методе.

Стоит ли продолжать заморачиваться с проверкой передаваемых данных в каждой функции?

Да. За счет этого вы выигрываете в безопасности, надежности и времени поиска багов.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@AndryG
Разделите код на группы:
- контачит с опасным миром входных данных (публичный метод, которому скармливают $_POST['x'] и т.д.)
- используется только в безопасной среде (приватные методы, классы глубоких внутренностей бизнес-логики, которые по нормальному никогда не используются из "грязной" среды)

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

И веселее было бы использовать исключения. В этом случае b($array) из вашего примера уже никто и не вызывали бы.
Ответ написан
Комментировать
dimasmagadan
@dimasmagadan
проверять много раз - избыточный код. чем проще код, тем дешевле его написание и поддержка.

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

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы