Анимация
JavaScript
|
Главная Библионтека о сравнении строк и инструкции if-else Теперь я хотел бы рассмотреть одно тонкое место в интерпретаторе PHP, касающееся немного неправильной работы со строками. Заключается оно вот в чем. Если мы используем операторы сравнения == и != (или любые другие, которые могут потребовать перевода строки в число) с операндами-строками, то результат, вопреки ожиданиям, не всегда оказывается верным. Чаще всего это проявляется как раз в инструкции if. Вот примеры (листинг 12.1): \ Листинг 12.1. Внимание! Опасное место! $one=1 число один $zero=0 присваиваем число ноль if($one=="") echo 1 очевидно, не равно - не выводит 1 if($zero=="") echo 3 Внимание! Вопреки ожиданиям печатает 3! if(""==$zero) echo 4 И это тоже не поможет!.. if("$zero"=="") echo 5 Не работает в некотор1х версиях PHP 3 if(strval($zero)=="") echo 6; Вот теперь правильно - не в1водит 6 че. Что же касается конкатенации строк, то для нее ввели специальный оператор "." (точка). Оператор "." всегда воспринимает свои операнды как строки и возвращает строку. В случае, если один из операндов не может быть переведен в строковое представление, т. е. если это массив или объект, то он воспринимается как строки array и object соответственно. Вообще говоря, это правило применимо и не только при сцеплении строк, но и при передаче такого операнда в какую-нибудь стандартную функцию, которой требуется строка. Например, следующие команды выведут слово array: $a=array(10,20,30); echo $a Внимание! Неожиданн1й результат! Есть и другой, более специализированный, способ конкатенации строк. Он обычно используется, когда значения строковых или числовых переменных перемежаются с обычными словами. Если, к примеру, у нас в $day хранится текущее число, в $month - название месяца и в $year - год, то вывести строку вида "Сегодня 8 мая 2000 года" можно так: echo "Сегодня $day $month $year года"; При этом в строку, вырабатываемую инструкцией echo, автоматически в нужных местах вставятся значения наших переменных. Это позволяет констатировать тот факт, что в PHP все переменные начинаются с $ . ( Замечание В первых версиях PHP 3 при присоединении к числовому нулю пустой строки этот ноль не менял типа, не становился строкой "0". Видимо, срабатывала какая-то оптимизация, и PHP просто пропускал этот бессмысленный, на его взгляд, шаг. Проведенные мной тесты показывают, что в PHP версии 3.0.12 и старше эта ошибка исправлена, но все же иногда нужно иметь ее в виду, особенно, если сценарии должны быть хорошо переносимыми. Итак, если вы хотите сравнить две переменные-строки, нужно быть абсолютно уверенными, что их типы именно строковые, а не числовые. Впрочем, это не распространяется на новый оператор PHP версии 4 === (тройное равенство, или оператор эквивалентности). Его использование заставляет интерпретатор всегда сравнивать величины и по значению, и по их типу. Итак, с точки зрения PHP 0=="", но 0!==="". Если вы не собираетесь программировать на PHP версии, ниже третьей, рекомендую всегда использовать === вместо strval() , как это было сделано в листинге 12.1. Существует одна стандартная ошибка, которую делают многие. Вот в чем она состоит. Есть такая функция - strpos($str,$what), которая возвращает позицию подстроки $what в строке $str или false, если подстрока не найдена. Пусть нам нужно проверить, встречается ли в некоторой строке $str подстрока <? (и напечатать "это PHP-программа", если встречается). Как мы знаем, вариант if(strpos($str,"<?")!=false) echo "это PHP-программа"; не годится, если <? находится в самом начале строки (в этом случае не будет выдано наше сообщение, хотя подстрока в действительности найдена, и функция возвратила 0, а не false). Если вы еще собираетесь работать с PHP версии 3, указанную проблему можно решить так: if(strval(strpos($str,"<?"))!="") echo "это PHP-программа"; Конечно, выглядит это немного "накручено", зато действительно работает. Приятно отметить, что в PHP версии 4 проблема решается гораздо более изящным образом: if(strpos($str,"<?")!===false) echo "это PHP-программа"; if($zero==="") echo 7 Сам1й лучший способ, но не действует в PHP 3 Получается, что в операциях сравнения пустая строка "" прежде всего трактуется как 0 (ноль) и уж затем - как "пусто"? Это звучит довольно парадоксально, но это действительно так. Операнды сравниваются как строки только в том случае, если они оба - строки, в противном случае идет числовое сравнение. При этом пустая строка воспринимается как 0, впрочем, как и любая другая, которую интерпретатору не удалось перевести в число. ( Замечание Обратите внимание, что мы используем оператор !=== именно с константой false, а не с пустой строкой "". Дело в том, что для этого оператора false!==="", в то время как, разумеется, false=="". функции для работы с одиночными символами string chr(int $code) Возвращает строку из одного символа с кодом $code. Эта функция полезна для вставки каких-либо непечатаемых символов в строку - например, кода нуля или символа прогона страницы, а также при работе с бинарными файлами. Пример из листинга 12.2 позволяет вам просмотреть, какие коды соответствуют всем символам, которые можно отобразить в браузере. Иногда эта программа оказывается очень полезной. Листинг 12.2. Программа: печать всей таблицы символов <? Сначала создаем массив того, что мы собираемся выводить, не заботясь о форматировании ( дизайне) информации for($i=0,$x=0; $x<16; $x++) { for($y=0; $y<16; $y++) { $Chars[$x][$y]=array($i,chr($i)); $i++; Теперь в1водим накопленную информацию, используя идеологию вставки участков кода в HTML-документ ?> <table border=1 cellpadding=1 cellspacing=0> <?for($y=0; $y<16; $y++) {?> <tr> <?for($x=0; $x<16; $x++) { ?> <td> <?=$Chars[$x][$y][0]?>: Рекомендую всегда применять последний способ. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 [ 68 ] 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |