Чат Telegram
Группа ВКонтакте
Новый комментарий

Timurik Patron 19.04.2020 в 20:11

Я вот так сделал

<?php

if (empty($_GET)) {
    return 'Ничего не передано';
}

if (empty($_GET['operation'])) {
    return 'Операция не передана';
}

$operations = $_GET['operation'];

$x1 = (float)filter_input(INPUT_GET, 'x1');
$x2 = (float)filter_input(INPUT_GET, 'x2');

switch ($operations) {
    case '+':
        $result = $x1 + $x2;
        break;
    case  '-':
        $result = $x1 - $x2;
        break;
    case  '/':
        $result = $x2 !== 0 ? ($x1 / $x2) : 'На ноль делить нельзя';
        break;
    case  '*':
        $result = $x1 * $x2;
        break;

    default:
        return 'Операция не поддерживается';
}

$expression = $x1 . ' ' . $operations . ' ' . $x2 . ' = ';

return $expression . $result;

единственное теперь при неправильном вводе не будет сообщений, а аргумент будет принимать значение 0.0

ivashkevich 19.04.2020 в 20:27

Как-то не очень хорошо ознакомились с функцией. У неё ещё 2 аргумента есть.

единственное теперь при неправильном вводе не будет сообщений, а аргумент будет принимать значение 0.0

Такие решения не принимаются. Должен быть полностью рабочий код.

Timurik Patron 19.04.2020 в 20:54

Исправил:

$x1 = filter_input(INPUT_GET, 'x1', FILTER_VALIDATE_FLOAT);
$x2 = filter_input(INPUT_GET, 'x2', FILTER_VALIDATE_FLOAT);

if ($x1 === false || $x2 === false) {
    return 'Аргументы 1 и/или 2 не переданы или не являются числами';
}

или необходимо разделить сообщения?

ivashkevich 20.04.2020 в 04:44

Можно разделить, будет дополнительнвм плюсом. Но в целом, это именно то, что я хотел увидеть)

Timurik Patron 20.04.2020 в 08:02

Спасибо.

titelivus 02.05.2020 в 18:52
<?php

if (empty($_GET)) {
    return 'Ничего не передано';
}

if (empty($_GET['operation'])) {
    return 'Операция не передана';
}

$x1 = filter_input(INPUT_GET, 'x1', FILTER_VALIDATE_FLOAT);
$x2 = filter_input(INPUT_GET, 'x2', FILTER_VALIDATE_FLOAT);

if ($x1 === null || $x2 === null) {
    return 'Аргументы 1 или 2 не переданы';
}

if ($x1 === false || $x2 === false) {
    return 'Введите число!';
}

$operations = $_GET['operation'];

switch ($operations) {
    case '+':
        $result = $x1 + $x2;
        break;
    case  '-':
        $result = $x1 - $x2;
        break;
    case  '/':
        $result = $x2 !== 0 ? ($x1 / $x2) : 'На ноль делить нельзя';
        break;
    case  '*':
        $result = $x1 * $x2;
        break;

    default:
        return 'Операция не поддерживается';
}

$expression = $x1 . ' ' . $operations . ' ' . $x2 . ' = ';

return $expression . $result;

Если в любом аргументе ничего не передать и нажать на "Посчитать": Выведется сообщение: "Введите число!". Но логично было бы: "Аргументы 1 или 2 не переданы". Хотя мы ничего не передавали, но на самом деле мы передали пустую строку, а функция filter_input() обработала ее и вернула false. Тем самым выражение:

if ($x1 === null || $x2 === null) {
    return 'Аргументы 1 или 2 не переданы';
}

не сработает =*(

но можно сделать так:

<?php

if (empty($_GET)) {
    return 'Ничего не передано';
}

if (empty($_GET['operation'])) {
    return 'Операция не передана';
}

if ($_GET['x1'] === "" || $_GET['x2'] === "") {
    return 'Аргументы 1 или 2 не переданы';
}

$x1 = filter_input(INPUT_GET, 'x1', FILTER_VALIDATE_FLOAT);
$x2 = filter_input(INPUT_GET, 'x2', FILTER_VALIDATE_FLOAT);

if ($x1 === NULL || $x2 === null) {
    return 'Аргументы 1 или 2 не переданы';
}

if ($x1 === false || $x2 === false) {
    return 'Введите число!';
}

$operations = $_GET['operation'];

switch ($operations) {
    case '+':
        $result = $x1 + $x2;
        break;
    case  '-':
        $result = $x1 - $x2;
        break;
    case  '/':
        $result = $x2 !== 0 ? ($x1 / $x2) : 'На ноль делить нельзя';
        break;
    case  '*':
        $result = $x1 * $x2;
        break;

    default:
        return 'Операция не поддерживается';
}

$expression = $x1 . ' ' . $operations . ' ' . $x2 . ' = ';

return $expression . $result;

Хотя я уверен что есть способ поделикатнее, но это не точно =)

ivashkevich 03.05.2020 в 20:48
if ($_GET['x1'] === "" || $_GET['x2'] === "") {
    return 'Аргументы 1 или 2 не переданы';
}

Бум! И снова ошибка!

titelivus 04.05.2020 в 04:46

А в чем ошибка, если отправить пустую строку, то есть ничего не писать просто нажать на кнопку посчитать, выведет Аргументы 1 или 2 не преданы. Все верно же.

ivashkevich 06.05.2020 в 13:05

Упс, видимо вам я еще не скидывал) Пройдите дополнительный урок Обработка форм в PHP и исправьте ошибки

desperatik@mail.ru 06.05.2020 в 23:02
if (empty($_GET)) {
    return 'Ничего не передано';
}

if (empty($_GET['operation'])) {
    return 'Операция не передана';
}

$x1 = filter_input(INPUT_GET, 'x1', FILTER_VALIDATE_FLOAT);
$x2 = filter_input(INPUT_GET, 'x2', FILTER_VALIDATE_FLOAT);

$operations = $_GET['operation'];

if (!is_numeric($x1) || !is_numeric($x2)) {
    return 'Введите число';
}

switch ($operations) {
    case '+':
        $result = $x1 + $x2;
        break;
    case  '-':
        $result = $x1 - $x2;
        break;
    case  '/':
        $result = $x2 != 0 ? ($x1 / $x2) : 'На ноль делить нельзя';
        break;
    case  '*':
        $result = $x1 * $x2;
        break;

    default:
        return 'Операция не поддерживается';
}

$expression = $x1 . ' ' . $operations . ' ' . $x2 . ' = ';

return $expression . $result;
ivashkevich 08.05.2020 в 19:49

Отлично!

garetziro@gmail.com Patron 05.06.2020 в 22:41

$x2 = $_GET['x2'] ?? null;

Если я правильно понял, то это читается так, что если $_GET['x2'] равно null, то ее значение будет null.
Зачем задавать null если значение и так null?

ivashkevich 06.06.2020 в 08:45

Потому что без применения этого оператора будет ошибка уровня NOTICE, если этого ключа в массиве не будет.

garetziro@gmail.com Patron 08.06.2020 в 21:50
if ($_GET['x1'] === '' || $_GET['x2'] === '')

То есть в данном случае мы просто проверяем - не передано ли в полях что-либо, но не проверяем есть ли сами поля, верно?
В таком случае, если да, то, возможно, следует взять на вооружение и всегда использовать
либо empty, либо сравнение с null или isset, верно?

Тема проверки дается не очень, возвращаюсь к ней. Как-то не совсем усвоил - зачем нужно проверять. Как могут навредить моему сайту, если нет проверки.
Для чего удалять переменную из адресной строки, чтобы получить ошибку - вот не понимаю.
Вы в статье пишите, что если в консоли разработчика удалить поле, то форма будет косячная. Почему? После обновления страницы все работает.
Вот если бы понять важность этой проверки на конкретном примере...

garetziro@gmail.com Patron 08.06.2020 в 22:16

По поводу д.з. к этой статье.
Принял переменные из глобального массива Гет через фильтр FILTER_VALIDATE_FLOAT.
Больше возможностей для использования фильтров в коде не нашел.

$x1 = filter_input(INPUT_GET, 'x1', FILTER_VALIDATE_FLOAT);
$x2 = filter_input(INPUT_GET, 'x2', FILTER_VALIDATE_FLOAT);
if ($x1 === null || $x2 === null) {
    return 'Аргументы 1 или 2 не переданы';
}
ivashkevich 09.06.2020 в 12:55

Норм!

ivashkevich 09.06.2020 в 12:55

В таком случае, если да, то, возможно, следует взять на вооружение и всегда использовать
либо empty, либо сравнение с null или isset, верно?

Совершенно верно

Как-то не совсем усвоил - зачем нужно проверять.

Потому что любая ошибка - это потенциальная уязвимость. К примеру, вывод ошибки с путём до файла - это уязвимость, которая так и называется - раскрытие пути. Сам по себе путь не является чем-то опасным, но может помочь злоумышленнику лучше понять структуру проекта, узнать версию движка, или что-то ещё, что может упростить эксплуатацию других уязвимостей.

Ваше приложение не должно содержать ошибок. Вот прям совсем.

garetziro@gmail.com Patron 09.06.2020 в 20:28

Спасибо за ответ!

GeoOK Patron 31.07.2020 в 15:48

Получилось так. Немного не допер, как сделать аналогичный, но кастомный фильтр для $_GET['operation'], через FILTER_CALLBACK. Как-то там сильно наворочено. Или это еще рано?

<?php

if (empty($_GET)) {
    return 'Ничего не передано';
}

$x1 = filter_input(INPUT_GET, 'x1', FILTER_VALIDATE_FLOAT);
$x2 = filter_input(INPUT_GET, 'x2', FILTER_VALIDATE_FLOAT);
$operation = $_GET['operation'] ?? null;

if ($x1 === null || $x2 === null || $operation === null) {
    return 'Ничего не передано';
}

if ($x1 === false && $x2 === false && empty($operation)) {
    return 'Ничего не передано';
}

if ($x1 === false || $x2 === false) {
    return 'Введите число';
}

if (empty($operation)) {
    return 'Не передана операция';
}

$expression = $x1 . ' ' . $operation . ' ' . $x2 . ' = ';

switch ($operation) {
    case '+':
        $result = $x1 + $x2;
        break;
    case '-':
        $result = $x1 - $x2;
        break;
    case '*':
        $result = $x1 * $x2;
        break;
    case '/':
        if ($x2 == 0) {
            return 'Деление на ноль невозможно';
        }
        $result = $x1 / $x2;
        break;
    default:
        return 'Операция не поддерживается';
}

return $expression . $result;
ivashkevich 02.08.2020 в 17:30
if ($x1 === null || $x2 === null || $operation === null) {
    return 'Ничего не передано';
}

if ($x1 === false && $x2 === false && empty($operation)) {
    return 'Ничего не передано';
}

if ($x1 === false || $x2 === false) {
    return 'Введите число';
}

Зачем столько проверок? Какое значение будет в x1, если не удастся распарсить число?

GeoOK Patron 03.08.2020 в 07:39

Зачем столько проверок?

Ну как бы логика была такая.

1) Проверяем сам массив на наличие данных:

if (empty($_GET)) {
    return 'Ничего не передано';
}

2) Если массив не пуст, теперь проверяем есть ли заданные переменные в массиве:

if ($x1 === null || $x2 === null || $operation === null) {
    return 'Ничего не передано';
}

3) Если есть все переменные, проверяем есть ли во всех переменных аргументы:

if ($x1 === false && $x2 === false && empty($operation)) {
    return 'Ничего не передано';
}

*Хотя согласен, этот пункт можно опустить

Просто все эти 3 пункта могут быть выполнены, только если вмешиваться в работу программы, через строку, поэтому и описал все случаи одним комментарием, так сказать для "взламывателей" )))

Пользователь же, который будет "честно" работать через форму, фактически будет работать только вот с этими условиями:

if ($x1 === false || $x2 === false) {
    return 'Введите число';
}

if (empty($operation)) {
    return 'Не передана операция';
}

Какое значение будет в x1, если не удастся распарсить число?

Ну если верить описанию filter_input, то при удачной фильтрации возвращается само число, при неудачной фильтрации, возвращается false, а при отсутствии самой переменной, возвращается null. А если использовать флаг FILTER_NULL_ON_FAILURE, то наоборот. Во всяком случае, я так понял.

ivashkevich 8 часов назад

Просто все эти 3 пункта могут быть выполнены, только если вмешиваться в работу программы, через строку, поэтому и описал все случаи одним комментарием, так сказать для "взламывателей" )))

всё правильно

Пользователь же, который будет "честно" работать через форму, фактически будет работать только вот с этими условиями:

ни в коем случае не полагайтесь на это

я просто у вас спросил, для чего, не просил ничего переписывать)

if ($x1 === false && $x2 === false && empty($operation)) {

а если только одно передано, а второе false? Тогда проверка не сработает. Нужно с помощью ИЛИ проверять, а не И.

Логические задачи с собеседований