За последние 24 часа нас посетили 10537 программистов и 913 роботов. Сейчас ищут 443 программиста ...

Не могу понять преобразование (int)

Тема в разделе "PHP для новичков", создана пользователем dimdim, 11 янв 2021.

  1. dimdim

    dimdim Новичок

    С нами с:
    11 янв 2021
    Сообщения:
    3
    Симпатии:
    0
    Привет всем!
    Есть функция редактирования статьи по ее int id

    public function edit($id='')
    {
    $safe_id = (int)$id;
    if ($id!=$safe_id) {
    echo 'неверный номер статьи ';
    return false;
    }
    echo 'все верно';
    // ... и далее выполняется код';
    }

    если $id = '123n456';

    получаем переменные -
    $id: 123n456
    strlen:7
    var_dump: string(7) "123m456"

    $safe_id:123
    strlen:3
    var_dump: int(123)

    т.е. $id точно не равно $safe_id
    но при этом результат 'все верно'

    Не могу понять где грабли в if ( $id != $safe_id) {
    почему в данном примере $id == $safe_id
     
  2. dimdim

    dimdim Новичок

    С нами с:
    11 янв 2021
    Сообщения:
    3
    Симпатии:
    0
    сам понял..
    if ($id != (string)$safe_id) {
     
  3. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.071
    Симпатии:
    220
    Излишне сложно.
    Просто преобразуйте получаемый параметр в тип int/
    Например так
    PHP:
    1. if(isset($_GET['id'])) $id = sprintf('%d', $_GET['id']);
     
  4. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.180
    Симпатии:
    1.197
    Адрес:
    Лень
    Вот что делаешь :D
    PHP:
    1. $id = '1';
    2.  
    3. $id != $id; // ой забыл еще ( int ) для красоты
    --- Добавлено ---
    используй строгое сравнение

    PHP:
    1. !==
    --- Добавлено ---
    @Drunkenmunky, не надо преобразовывать ничего
    https://www.php.net/manual/ru/function.filter-var.php
    с FILTER_VALIDATE_INT
    --- Добавлено ---
    @Drunkenmunky кстати, а потом $id ты проверяешь на существование ? :D
     
  5. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.071
    Симпатии:
    220
    Зачем?
    Явно задаем ноль. Потом проверяем глобальный массив и преобразовываем полученное.
    Полторы строчки. - просто, понятно, надежно, безопасно.

    PHP:
    1. $id = 0;
    2. if(isset($_GET['id'])) $id = sprintf('%d', $_GET['id']);
     
  6. dimdim

    dimdim Новичок

    С нами с:
    11 янв 2021
    Сообщения:
    3
    Симпатии:
    0
    Строгое сравнение тут не поможет, т.к. разные типы. id = string а safe_id = int и всегда будет фальш

    Пока ждал модерацию, читал мануалы, получилось что
    если php 7 сравнивает строку и число, то он строку приводит к числу, а потом сравнивает 2 числа.
    и тогда получается что 123 == '123n234' это (true) и будет дыра. можете проверить
    а если я указал if ($id != (string)$safe_id) { то сравнение идет символьное, т.к. сравниваются 2 строки
     
  7. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.180
    Симпатии:
    1.197
    Адрес:
    Лень
    затем что у тебя в том коде такова логика, пока не справил
     
  8. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.071
    Симпатии:
    220
    Подразумевалось, что это очевидно. Видимо, не всем.
    Учту.
     
  9. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.180
    Симпатии:
    1.197
    Адрес:
    Лень
    • почему не регуляркой ? preg_replace \d+
    • не ( int ) ?
    • не через фильтр ?
    --- Добавлено ---
     
  10. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.071
    Симпатии:
    220
    Если присмотритесь к моему первому(уточняю - в этом топике, #3) сообщению, то заметите "например так".
    Когда так говорят, обычно имеют в виду, что есть и другие варианты.
    Дескать, если заинтересует, то прикинь всякое к носу.
     
  11. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.151
    Симпатии:
    1.644
    Я вообще такими вещами не занимаюсь. Такие id обычно идут в запросы базы, запросы нормальные люди делают через подготовленные выражения, если кто-то вставит что-то плохое, база просто поищет у себя пост с айди
    Код (Text):
    1. ' union delete from users;
    Его там не будет, и мы со спокойной душой выдадим 404-ю.

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