Как стать автором
Обновить

Особенности условных конструкции со строками в PHP

Время на прочтение3 мин
Количество просмотров3.4K
На Хабре часто обсуждается какой язык лучше для написания безопасных приложений. При этом часто отмечается, что PHP спроектирован таким образом, что начинающий разработчик будет допускать ошибки, приводящие к дырам безопасности. В этом хабрапосте я хочу рассказать о, на мой взгляд, нелогичном поведении операций сравнения, операторов if и switch при работе со строками. Опытным разработчикам данные особенности известны, но решил все же собрать их в одном месте. Думаю пост будет полезен начинающим разработчикам и тем, кто работает в PHP, имея опыт программирования на других языках.

Что есть истина?

Какие строки истинны? Рассмотрим пример:
echo '"" is '. (''?'true':'false'). "\n";
echo '«0» is '. ('0'?'true':'false'). "\n";
echo '"-0" is '. ('-0'?'true':'false'). "\n";
echo '«0.0» is '. ('0.0'?'true':'false'). "\n";
echo '«00» is '. ('00'?'true':'false'). "\n";
echo '«A» is '. ('A'?'true':'false'). "\n";Имеем:"" is false
«0» is false
"-0" is true
«0.0» is true
«00» is true
«A» is true
Итак истинны все непустые строки, кроме строки «0». Логика такого поведения для меня не ясна. На практике часто с помощью оператора if проверяется заполнено ли поле формы, например:if(isset($_GET['income']) && $_GET['income']) {… }Такая проверка примет поле, в котором указан 0 за незаполненное. Чтобы избежать возможного недоразумения, следует использовать проверку в виде: if(isset($_GET['income']) && strlen($_GET['income'])) {… }

Сравнение с участием строк

В PHP два оператора сравнения == и ===. Второй оператор сравнивает совпадение типов и значений, первый производит преобразование типа, а затем выполняет сравнение. Особенность оператора == в том, что при сравнении числа и строки, просходит преобразование строки в число. Если строка не представляет собой число, то она преобразуется в числовое значение 0. Рассмотрим пример:echo '«A»==0 is '. ('A'==0?'true':'false'). "\n";
echo '«A»===0 is '. ('A'===0?'true':'false'). "\n";
echo '«A»==0.0 is '. ('A'==0?'true':'false'). "\n";
echo '«A»===0.0 is '. ('A'===0?'true':'false'). "\n";Результат работы скрипта:«A»==0 is true
«A»===0 is false
«A»==0.0 is true
«A»===0.0 is falseЕсли ваша функция сравнивает строку, переданную в качестве аргумента с заданной строкой, то следует предварительно проверить, что в качестве аргумента передана строка, а не число. Пример будет приведен далее, при рассмотрении оператора switch.

Оператор switch

Мы ожидаем, что оператор switch сравнивает переданное значение с заданными константами. Особенность реализации switch в php в том, что он производит сравнение с помощью оператора ==, то есть не производит сравнение типов. В качестве примера рассмотрим вымышленную функцию, которая возвращает зарплату сотрудника, получая его имя на входе:<?php
function get_salary($name) {
switch($name) {
case 'John':
return 3400;
break;
case 'Mary':
return 4600;
break;
default:
return 0;
}
}

echo «John's salary is ». get_salary('John'). "\n";
echo «Mary's salary is ». get_salary('Mary'). "\n";
echo «Peter's salary is ». get_salary('Peter'). "\n";
echo «0's salary is ». get_salary(0). "\n";
?>Результат работы скрипта:John's salary is 3400
Mary's salary is 4600
Peter's salary is 0
0's salary is 3400На примере видно, что безопасность функции скомпрометирована путем передачи числового значения вместо строкового. Чтобы защитить функцию от нежелательного использования, требуется проверять тип входного значения.<?php
function get_salary($name) {
if(!is_string($name)) return 0;
switch($name) {
case 'John':
return 3400;
break;
case 'Mary':
return 4600;
break;
default:
return 0;
}
}

echo «John's salary is ». get_salary('John'). "\n";
echo «Mary's salary is ». get_salary('Mary'). "\n";
echo «Peter's salary is ». get_salary('Peter'). "\n";
echo «0's salary is ». get_salary(0). "\n";
?>Результат работы скрипта:John's salary is 3400
Mary's salary is 4600
Peter's salary is 0
0's salary is 0Итак, некоторые операции сравнения ведут себя контринтуитивно. Кто предупрежден, тот вооружен.

Кросспост Особенности условных конструкции со строками в PHP с webew.ru.
Теги:
Хабы:
Всего голосов 45: ↑42 и ↓3+39
Комментарии88

Публикации

Истории

Работа

PHP программист
119 вакансий

Ближайшие события

One day offer от ВСК
Дата16 – 17 мая
Время09:00 – 18:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн
Антиконференция X5 Future Night
Дата30 мая
Время11:00 – 23:00
Место
Онлайн
Конференция «IT IS CONF 2024»
Дата20 июня
Время09:00 – 19:00
Место
Екатеринбург
Summer Merge
Дата28 – 30 июня
Время11:00
Место
Ульяновская область