Теперь, когда вы имеет представление о том, как использовать массивы для организации простой таблицы, а также о том, как спроектировать таблицы массивов для обеспечения максимальной гибкости при работе с сортировкой, рассмотрим другой тип таблиц — поисковые таблицы (lookup tables). В отличие от описанных выше таблиц, поисковая таблица не предназначена для отображения пользователю. Вместо этого ее можно описать как таблицу ссылок, создаваемую и используемую РНР-сценарием для повышения эффективности или упрощения задачи. В настоящем разделе рассматривается простое приложение поисковой таблицы. В частности, будет показано, как реализовать поисковую таблицу для вывода криптограмм. Небольшое пояснение для тех, кто не знаком с криптограммами: для заданной строки необходимо заменить каждую букву (например, "А") другой буквой. Задача состоит с том, чтобы расшифровать закодированное сообщение. Несмотря на то что существует множество способов реализации сценария генерации криптограмм, мы попытаемся сделать это с помощью набора функций для работы с массивами, начиная с range (). В РНР функция range () применяется для создания массивов, которые содержат заданный диапазон чисел или букв. Синтаксис этой функции выглядит так: range(mixed $low, mixed $high) $low представляет начало диапазона, a $high — конец. Как уже было сказано, параметры могут быть числами (например, от 1 до 10), или буквами (например, от d до w). Функция rand () вернет индексированный целыми ключами массив, содержащий все цифры или буквы от $low до $high. Эта функция будет использоваться далее для создания массива, содержащего все буквы алфавита, а также буквы, используемые для кодирования криптограммы. Вторая функция, которую нужно представить — это функция, которая будет отвечать за определение того, как буквы закодированы в финальной криптограмме, а именно — shuffle (). Эта функция подобна рассмотренной ранее array_rand (), но с одним существенным отличием. Вместо создания нового массива случайным образом на базе другого существующего массива, функция shuffle () перетасовывает случайным образом содержимое массива. Ниже показан очень простой синтаксис shuffle (). shuffle($input) Еще одной функцией, которая понадобится для целей этого примера, будет та, которая меняет местами пары ключ/значение (так, что ключи становятся значениями, а значения — ключами) — функция array_f l ip (), также имеющая простой синтаксис: array_flip($input) $ input представляет массив, для которого надо поменять местами ключи и значения, и в результате вызова функция возвращает новый массив. И, наконец, рассмотрим нашу первую функцию поиска в PHP-массиве — in_array(). Эта функция принимает два параметра (искомое значение и массив, в котором нужно искать) и возвращает булевское значение, означающее успешность или неудачу поиска конкретного значения. Ниже показан синтаксис функции in_array (). in_array($needle, $haystack [, $strict]) Обратите внимание, что функция in_array() также принимает необязательный третий параметр — $ s t r i c t . Это необязательное логическое значение (по умолчанию равное false) определяет, должно ли искомое значение $needle совпадать с элементом массива $haystack не только по значению, но и по типу. То есть, в массиве, содержащем строковое значение ' 10 ', поиск целого числа 10 вернет true. Однако если установить значение параметра $ s t r i c t равным true, та же операция вернет false. Теперь, когда вы познакомились с новыми функциями, которые будут использоваться в данном примере, рассмотрим первую часть сценария генерации криптограмм, которая показана в листинге 2.17.
НА ЗАМЕТКУ В листинге 2.17 завершающий дескриптор ?> опущен, поскольку это только начальный фрагмент сценария.
Листинг 2.17. Генератор криптограмм с применением PHP-массивов (часть 1) <?php /* Инициализация генератора случайных чисел */ srand((double)microtime() * 1000000); $message = "This is my super secret message!"; $message = strtoupper(Smessage); 82 ИспользованиеРНРдля^ Часть I /* Создать алфавитный массив с ключами от А до Z и значениями от 0 до 25 соответственно */ $alphabet = array_flip(range('A', 'Z')); Scryptogram = range('A1, ' Z ' ) ; /* Случайное тасование поисковой таблицы, используемой для генерации криптограмм */ shuffle($cryptogram);
Как показано в листинге 2.17, первый шаг, предпринимаемый в этом сценарии —это инициализация генератора случайных чисел. Как и в случае с array_rand(), функции shuffle () это необходимо для правильной работы. После этого переменная $message (представляющая исходную строку, которую нужно закодировать) инициализируется и преобразуется в верхний регистр с помощью функции strtoupper (). Используя комбинации функций ranged и array_flip (), создается ассоциативный массив $alphabet, который имеет ключевые значения для каждой буквы алфавита и ассоциирует их с целыми числами от 0 до 25. Дополнением переменной $alphabet служит переменная $cryptrogram, которая инициализируется 26 значениями, представляющими буквы алфавита. Переменная $cryptrogram будет использоваться для кодирования сообщения в окончательной криптограмме. Когда вся и инициализация завершена, поисковая таблица криптограммы тасуется с помощью описанной ранее функции shuffle () и начинается кодирование криптограммы, как показано в листинге 2.18.
Листинг 2.18. Генератор криптограмм с применением PHP-массивов (часть 2) $encoded = ""; /* Цикл по всем символам кодируемого сообщения */ for($i = 0; $i < strlen($message); $i++) { $char = $message[$i]; /* Определение, является ли данный символ кодируемым, с помощью поиска в таблице $cryptogram */ if(!in_array($char, $cryptogram)) { /* Если символ некодируемый, копировать его без изменений в кодовую строку */ $encoded .= $char; } else { /* Если символ кодируемый, заменить соответствующим символом из $cryptogram */ $encoded .= $cryptogram[$alphabet[$char]]; echo $encoded;
НА ЗАМЕТКУ Хотя строки PHP не являются массивами, они могут вести себя подобно массивам. Это позволяет разработчику получить доступ к отдельному символу строки по индексу, заключенному в квадратные скобки, как это делается в листинге 2.18. Следует отметить, что несмотря на то, что строки ведут себя подобно массивам, они не могут использоваться в операторах, манипулирующих массивами, таких как foreach ( ) , или функциях, работающих с массивами.
Когда вся инициализация завершена, следующим шагом в этом сценарии является организация цикла по индивидуальным символам кодируемого сообщения с помощью оператора for (), начиная с 0 и до значения длины строки, возвращаемого функцией strlen (). Функция s t r l en () возвращает длину переданной строки (строки подробно обсуждаются в главе 1). Поскольку некоторое количество исходных символов не кодируются (знаки пунктуации, пробелы и тому подобные), нужно проверять каждый символ на этот предмет. Для этого применяется функция поиска в массиве in_array(), проверяющая наличие данного символа в таблице поиска Scryptogram. Если нет доступной трансляции данного символа (то есть i n a r r a yO возвращает false), он передается в выходную зашифрованную строку $encoded без изменений. В противном случае символ транслируется на базе массива $cryptogram. Однако поскольку ключами массива $cryptogram являются не символы, а числа от 0 до 25, массив $alphabet используется для извлечения конкретного целого значения для заданного символа. После того, как сообщение обработано символ за символом, $encoded содержит готовую криптограмму сообщения (которая затем отображается клиенту). Так как этот сценарий при каждом запуске генерирует абсолютно новую криптограмму, от него невозможно получить повторяющийся вывод. После запуска этого сценария вывод у автора выглядел так: