Почему делает 1 +++ 2 = 3?

Внимание: примерный код этого ответа (например, примерный код вопроса) использует расширение PHP mysql, которое устарело в PHP 5.5.0 и полностью удалено в PHP 7.0.0.

Если вы используете последнюю версию PHP, опция mysql_real_escape_string, описанная ниже, больше не будет доступна (хотя mysqli::escape_string является современным эквивалентом). В настоящее время опция mysql_real_escape_string имеет смысл только для устаревшего кода на старой версии PHP.


У вас есть два варианта - экранирование специальных символов в вашем unsafe_variable или использование параметризованный запрос. Оба будут защищать вас от SQL-инъекций. Параметрированный запрос считается лучшей практикой, но для его использования потребуется переходить на более новое расширение mysql в PHP.

Мы рассмотрим нижнюю строку удара, которая будет первой.

//Connect

$unsafe_variable = $_POST["user-input"];
$safe_variable = mysql_real_escape_string($unsafe_variable);

mysql_query("INSERT INTO table (column) VALUES ('" . $safe_variable . "')");

//Disconnect

См. также информацию о функции mysql_real_escape_string .

Чтобы использовать параметризованный запрос, вам нужно использовать MySQLi , а не функции MySQL . Чтобы переписать ваш пример, нам понадобится что-то вроде следующего.

prepare("INSERT INTO table (column) VALUES (?)");

    // TODO check that $stmt creation succeeded

    // "s" means the database expects a string
    $stmt->bind_param("s", $unsafe_variable);

    $stmt->execute();

    $stmt->close();

    $mysqli->close();
?>

Ключевая функция, которую вы хотите прочитать, будет mysqli::prepare .

Также, как предложили другие, вы можете сочтет полезным / легче повысить уровень абстракции с помощью чего-то вроде PDO .

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

  • Если вы хотите изменить структуру SQL на основе пользовательского ввода, параметризованные запросы не помогут, и требуемое экранирование не распространяется на mysql_real_escape_string. В этом случае вам лучше было бы пропускать вход пользователя через белый список, чтобы обеспечить доступ только «безопасных» значений.
  • Если вы используете целые числа от пользовательского ввода в состоянии и берете mysql_real_escape_string, вы столкнетесь с проблемой, описанной в Polynomial в комментариях ниже. Этот случай более сложный, поскольку целые числа не будут окружены кавычками, поэтому вы можете справиться, подтвердив, что пользовательский ввод содержит только цифры.
  • Есть, вероятно, другие случаи, о которых я не знаю. Вы можете найти , этот является полезным ресурсом для некоторых более тонких проблем, с которыми вы можете столкнуться.
28
задан pushkin 19 December 2018 в 17:44
поделиться

6 ответов

Ваше выражение совпадает с:

1+(+(+2))

Любому числовому выражению можно предшествовать - для создания его отрицательным, или +, чтобы ничего не сделать (опция присутствует для симметрии). Со знаками минус:

1-(-(2)) = 1-(-2)
         = 1+2
         = 3

и

1-(-(-2)) = 1-(2)
          = -1

я вижу, что Вы разъяснили свой вопрос сказать, что Вы происходите из среды C. В Python нет никаких инкрементных операторов как ++ и -- в C, который был, вероятно, источником Вашего беспорядка. Чтобы увеличить или постепенно уменьшить переменную i или j в Python используют этот стиль:

i += 1
j -= 1
58
ответ дан hjpotter92 28 November 2019 в 02:32
поделиться

Дополнительными + не являются инкременторы (как ++ a или ++ в C++). Они просто показывают, что число положительно.

существует не такой ++ оператор. Существует унарное + оператор и унарное - оператор все же. Унарное + оператор не имеет никакого эффекта на свой аргумент. Унарное - оператор инвертирует свой оператор или mulitplies это-1.

+1

-> 1

++1

-> 1

Это совпадает с + (+ (1))

   1+++2

-> 3, поскольку это совпадает с 1 + (+ (+ (2))

Аналогично, можно сделать - 1 для значения - (-1), который является +1.

  --1

-> 1

Для полноты существует не * унарный оператор. Так *1 ошибка. Но существует ** оператор, который является питанием, требуется 2 аргумента.

 2**3

-> 8

14
ответ дан Brian R. Bondy 28 November 2019 в 02:32
поделиться

1 + (+ (+ 2)) = 3

1 - (-2) = 3

1 - (-(-2)) =-1

4
ответ дан alexwood 28 November 2019 в 02:32
поделиться

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

 1 + (+(+2))
1
ответ дан James Curran 28 November 2019 в 02:32
поделиться

Попытка Унарный Плюс и Унарный минус :

унарное - (минус) оператор приводит к отрицанию своего числового аргумента.

унарное + (плюс) оператор приводит к своему числовому неизменному аргументу.

>>> +2
2
>>> ++2
2
>>> +++2
2
>>> -2
-2
>>> --2
2
>>> ---2
-2
>>> 1+(++2)
3
4
ответ дан gimel 28 November 2019 в 02:32
поделиться

Думайте он как 1 + (+1* (+ 1*2))). Первым + является оператор, и после знаков "плюс" знак второго операнда (= 2).

Точно так же, как 1---2 - то же как 1 - (-(2)) или 1-(-1* (-1* (2))

1
ответ дан Juha Syrjälä 28 November 2019 в 02:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: