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

dimdim

Привет всем!
Есть функция редактирования статьи по ее 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

 

dimdim

сам понял..
if ($id != (string)$safe_id) {

 

Drunkenmunky

Излишне сложно.
Просто преобразуйте получаемый параметр в тип int/
Например так

PHP:
  1. if(isset($_GET[‘id’])) $id = sprintf(‘%d’, $_GET[‘id’]);
 

MouseZver

Вот что делаешь :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

 

Drunkenmunky

Зачем?
Явно задаем ноль. Потом проверяем глобальный массив и преобразовываем полученное.
Полторы строчки. — просто, понятно, надежно, безопасно.

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

dimdim

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

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

 

MouseZver

затем что у тебя в том коде такова логика, пока не справил

 

Drunkenmunky

Подразумевалось, что это очевидно. Видимо, не всем.
Учту.

 

MouseZver

  • почему не регуляркой ? preg_replace d+
  • не ( int ) ?
  • не через фильтр ?

— Добавлено —

 

Drunkenmunky

Если присмотритесь к моему первому(уточняю — в этом топике, #3) сообщению, то заметите «например так».
Когда так говорят, обычно имеют в виду, что есть и другие варианты.
Дескать, если заинтересует, то прикинь всякое к носу.

 

mkramer

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

Код (Text):
  1. ‘ union delete from users;

Его там не будет, и мы со спокойной душой выдадим 404-ю.

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

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *