Анимация
JavaScript


Главная  Библионтека 

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

В этом случае вхражение ($k=key($Names)), естественно, будет равно нулю, и цикл оборвется, чего бы нам совсем не хотелось.

Именно по этим причинам разработчики PHP придумали другой, хотя и менее универсальный, но гораздо более удобный метод перебора массивов, о котором сейчас и пойдет речь.

Прямой перебор массива

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

Классический перебор

Давайте опять вернемся к нашему примеру, в котором массив $Names хранил связь имен людей и их возрастов. Вот как можно перебрать этот массив при помощи прямого перебора:

for(Reset($Names); list($k,$v)=each($Names); /*пусто*/) echo "Возраст $k - $v\n";

В самом начале заголовка цикла мы видим нашу старую знакомую Reset() . Дальше переменным $k и $v присваивается результат работы функции each(). Третье условие цикла попросту отсутствует (чтобы это подчеркнуть, я включил на его место комментарий).

Что делает функция each() ? Во-первых, возвращает небольшой массив (я бы даже сказал, список), нулевой элемент которого хранит величину ключа текущего элемента массива $Names, а первый - значение текущего элемента. Во-вторых, она продвигает указатель текущего элемента к следующей позиции. Следует заметить, что если следующего элемента в массиве нет, то функция возвращает не список, а false. Именно поэтому она и размещена в условии цикла for. Становится ясно, почему мы не указали третий блок операторов в цикле for: он просто не нужен, ведь указатель на текущий элемент и так смещается функцией each() .

Перебор в стиле PHP 4

Прямой перебор массивов применялся столь часто, что разработчики PHP решили в четвертой версии языка добавить специальную инструкцию перебора массива - foreach. Мы уже рассматривали ее ранее. Вот как с ее помощью можно перебрать и распечатать наш массив людей:

foreach($Names as $k=>$v) echo "Возраст $k - $v\n";



( Замечание

Есть и еще одна причина предпочесть этот вид перебора "связке" цикла for с eaсh(). Дело в том, что при применении foreach мы указываем имя перебираемого массива $Names только в одном месте, так что когда вдруг потребуется это имя изменить, нам достаточно будет поменять его только один раз. Наоборот, использование Reset() и each() заставит нас в таком случае изменять название переменной в двух местах, что потенциально может привести к ошибке. Представьте, что произойдет, если мы случайно изменим операнд each(), но сохраним параметр Reset()!

списки и строки

Есть несколько функций, которые чрезвычайно часто используются при программировании сценариев. Среди них - функции для разбиения какой-либо строки на более мелкие части (например, эти части разделяются в строке каким-то специфическим символом типа ), и, наоборот, слияния нескольких небольших строк в одну большую, причем не впритык, а вставляя между ними разделитель. Первую из этих возможностей реализует стандартная функция explode(), а вторую - implode(). Рекомендую обратить особое внимание на указанные функции, т. к. они применяются очень часто.

Функция explode() имеет следующий синтаксис:

list explode(string $token, string $Str [, int $limit])

Она получает строку, заданную в ее втором аргументе, и пытается найти в ней подстроки, равные первому аргументу. Затем по месту вхождения этих подстрок строка " разрезается" на части, помещаемые в массив-список, который и возвращается. Если задан параметр $limit, то учитываются только первые ($limit-1) участков "разреза". Таким образом, возвращается список из не более чем $limit элементов. Это позволяет нам проигнорировать возможное наличие разделителя в тексте последнего поля, если мы знаем, что всего полей, скажем, 6 штук. Вот пример:

$st="4597219361ИвановИван40ivan@ivanov.comТекст, содержащий ()!"; $A=explode("",$st,6); Mi знаем, что там только 6 полей! теперь $A[0]="Иванов", ... $A[5]= "Текст, содержащий ()!" list($Surname,$Name,$Age,$Email,$Tel)=$A; распределили по переменн1м

Просто, не правда ли? Рекомендую везде, где не требуется совместимость с PHP третьей версии, использовать именно этот способ перебора, поскольку он работает с максимально возможной скоростью - даже быстрее, чем перебор списка при помощи for и числового счетчика.



сериализация

Возможно, после прочтения описания функций implode() и explode() вы обрадовались, насколько просто можно сохранить массив, например, в файле, а затем его оттуда считать и быстро восстановить. Если вас посетила такая мысль, то, скорее всего, вы уже успели в ней разочароваться: во-первых, таким образом можно сохранять только массивы-списки (потому что ключи в любом случае теряются), а во-вторых, ничего не выйдет с многомерными массивами.

Давайте теперь предположим, что нам все-таки нужно сохранить какой-то массив (причем неизвестно заранее, сколько у него измерений) в файле, чтобы потом, при следующем запуске сценария, его аккуратно загрузить и продолжить работу. Можно, конечно, начинать писать универсальную рекурсивную функцию для упаковки массива в строку (ведь в файлы можно писать только строки), и еще одну, которая будет эту строку разбирать и восстанавливать на ее основе массив в исходном виде.

Примечание

Рекомендую проделать это в качестве упражнения, заодно постарайтесь добиться, чтобы упакованные данные занимали минимум объема. Это пригодится вам в будущем, при работе с Cookies. Однако вскоре вы поймете, что все не так просто в PHP, в котором работа со ссылочными переменными очень и очень ограничена. Особенно будет тяжело с функцией распаковки строки.

И тут нам на помощь опять приходят разработчики PHP. Оказывается, обе функции давным-давно реализованы, причем весьма эффективно со стороны быстродействия (но, к сожалению, непроизводительно с точки зрения объема упакованных данных). Называются они, соответственно, Serialize() и Unserialize().

Конечно, строкой разбиения может быть не только один символ, но и небольшая строка. Не перепутайте только порядок следования аргументов при вызове функции!

Функция implode() и ее синоним join() производят действие, в точности обратное вызову explode() .

string implode(string $glue, list $List) или string join(string $glue, list $List)

Они берут ассоциативный массив (обгчно это список) $List, заданный в ее первом параметре, и "склеивают" его значения при помощи "строки-клея" $glue во втором параметре. Примечательно, что вместо списка во втором аргументе можно передавать любой ассоциативный массив - в этом случае будут рассматриваться только его значения.

Рекомендую вам чаще применять функции implode() и explode() , а не писать самостоятельно их аналоги. Работают они очень быстро.



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