- •Тема 1 Основы cgi-программирования
- •1.1 Методы передачи данных
- •1.2 Передача документа пользователю
- •1.3 Передача информации cgi-сценарию
- •Тема 2 Характеристика языка php
- •2.1 Принцип работы php
- •2.2 Переменные, константы, выражения
- •Тема 3 Работа с данными формы
- •3.1 Передача данных
- •3.2 Трансляция полей формы в переменные
- •Тема 4 Конструкции языка
- •4.1 Условные инструкции
- •4.2 Инструкции циклов
- •4.3 Инструкции включения
- •Тема 5 Ассоциативные массивы
- •5.1 Списки и ассоциативные массивы
- •5.2 Операции над массивами
- •5.3 Списки и строки
- •5.4 Сериализация
- •Тема 6 Работа с массивами
- •6.1 Сортировка массивов
- •6.2 Функции для работы с массивами
- •Тема 7 Функции и области видимости
- •7.1 Формат определения функции, передача параметров
- •7.2 Глобальные, локальные, статические переменные
- •7.3 Рекурсия, вложенные и условно-определяемые функции
- •7.4 Передача функций по ссылке и возврат функцией ссылки
- •Тема 8 Строковые функции
- •8.1 Функции работы со строками
- •8.2 Работа с блоками текста
- •Тема 9 Математические функции
- •9.1 Встроенные константы
- •9.2 Встроенные функции
- •Тема 10 Работа с файлами и каталогами,
- •10.1 Функции работы с файлами
- •10.2 Блокирование файла
- •10.3 Функции работы с каталогами
- •10.4 Запуск внешних программ
- •Тема 11 Работа с датами и временем,
- •11.1 Представление времени в формате timestamp
- •11.2 Работа с датами, григорианский календарь
- •11.3 Посылка писем через php
- •Тема 12 Работа с www
- •12.1 Установка заголовков ответа
- •12.2 Работа с Cookies
- •Тема 13 Управление интерпретатором
- •13.1 Управление интерпретатором
- •13.2 Управление сессиями
- •Тема 14 Работа с базой данных mysql
- •14.1 Соединение с базой данных
- •14.2 Выполнение запросов к базе данных
- •Тема 15 Загрузка файлов на сервер
- •15.1 Multipart-формы, тег выбора файла
- •15.2 Поддержка закачки в php
- •Учебное издание
- •Разработка программного обеспечения на платформе net: php.Net
- •246019 Г. Гомель, ул. Советская, 104
7.4 Передача функций по ссылке и возврат функцией ссылки
Передача функций «по ссылке». Как таковая, передача функции по ссылке в PHP не поддерживается. Однако, т. к. это слишком часто может быть полезным, в PHP есть понятие «функциональной переменной». Пример:
function A($i) { echo "a $i\n"; }
function B($i) { echo "b $i\n"; }
function C($i) { echo "c $i\n"; }
$F="A"; // или $F="B" или $F="C"
$F(10); // вызов функции, имя которой хранится в $F
В PHP есть такая стандартная функция – uasort(), которая сортирует ассоциативный массив, заданный ее первым параметром, причем критерием сравнения для элементов этого массива служит функция, имя которой передано вторым параметром. Пример:
// Сравнение без учета регистра символов строк
function FCmp($a,$b)
{ return strcmp(tolower($a),tolower($b))
}
$a=array("b"=>"bbb", "a"=>"Aaa", "d"=>"ddd);
uasort($a,"FCmp"); // Сортировка без учета регистра символов
Здесь функция, имя которой получено со вторым параметром uasort(), должна иметь два аргумента, которые являются сравниваемыми значениями в массиве. В общем случае, функциональная переменная – это всего лишь переменная-строка, содержащая имя функции. Поскольку в PHP нет такого понятия, как области видимости для функций (есть только области видимости для локальных переменных), то конфликтов это не порождает – одному имени может соответствовать не более одной функции. Такой подход не очень хорош, но он действительно работает.
Возврат функцией ссылки. До сих пор рассматривались функции, которые возвращают определенные значения – а именно, копии величин, использованных в инструкции return (это были именно копии, а не сами объекты). Пример:
$a=100;
function R()
{ global $a; // объявляет $a глобальной
return $a; // возвращает значение, а не ссылку!
}
$b=R();
$b=0; // присваивает $b, а не $a!
echo $a; // выводит 100
Пусть необходимо, чтобы функция R() возвращала не величину, а ссылку на переменную $a, чтобы в дальнейшем с этой ссылкой можно было работать точно так же, как и с $a. Использование оператора $b=&R() не подходит, т. к. при этом мы получим в $b ссылку не на $a, а на ее копию. Если задействовать return &$a, то появится сообщение о синтаксической ошибке (PHP воспринимает & только в правой части оператора присваивания сразу после знака =).
Специальный синтаксис описания функции, возвращающей ссылку:
$a=100;
function &R() // & — возвращает ссылку
{ global $a; // объявляет $a глобальной
return $a; // возвращает значение, а не ссылку!
}
$b=&R(); // не забудьте & !!!
$b=0; // присваивает переменной $a!
echo $a; // выводит 0. Это значит, что теперь $b — синоним $a
Нужно поставить & в двух местах: перед определением имени функции, а также в правой части оператора присваивания при вызове функции. Использовать амперсанд в инструкции return не нужно.
Тема 8 Строковые функции
8.1 Функции работы со строками
8.2 Работа с блоками текста
8.1 Функции работы со строками
Строки в PHP – одни из самых универсальных объектов. Любой объект можно упаковать в строку. Строка может содержать любые символы с кодами от 0 до 255 включительно. Нет специального маркера «конца строки», длина строки во внутреннем представлении PHP хранится отдельно. Для формирования и вставки непечатаемого символа в строку используется функция chr(). Из-за слабого контроля типов в PHP строка может содержать число, причем с ней можно работать, как с числом: прибавлять другие числа, умножать и т. д. При этом все преобразования (в десятичной системе) производятся автоматически. Существуют функции, преобразующие число, записанное в различных системах счисления в обычное представление, и наоборот.
Конкатенация строк. Конкатенация – это присоединение к одной строке другой. Оператор + следует применять только для сложения чисел. Для конкатенации строк используется специальный оператор «.» (точка). Оператор «.» всегда воспринимает свои операнды как строки и возвращает строку. В случае, если один из операндов не может быть переведен в строковое представление, т. е. если это массив или объект, то он воспринимается как строки array и object соответственно. Это правило применимо и не только при сцеплении строк, но и при передаче такого операнда в какую-нибудь стандартную функцию, которой требуется строка. Пример:
$a=array(10,20,30);
echo $a // Неожиданный результат «array»!
Есть и другой, более специализированный, способ конкатенации строк. Он обычно используется, когда значения строковых или числовых переменных перемежаются с обычными словами. Если, к примеру, в $day хранится текущее число, в $month – название месяца и в $year – год, то вывести строку вида «Сегодня 8 мая 2000 года» можно так:
echo "Сегодня $day $month $year года";
При этом в строку, вырабатываемую инструкцией echo, автоматически в нужных местах вставятся значения переменных.
Сравнение строк и инструкции if-else. Рассмотрим одно тонкое место в интерпретаторе PHP, касающееся немного неправильной работы со строками. Заключается оно в следующем: если используются операторы сравнения == и != (или любые другие, которые могут потребовать перевода строки в число) с операндами-строками, то результат, не всегда оказывается верным. Примеры:
$one=1 // число один
$zero=0 // присваиваем число ноль
if($one=="") echo 1 // очевидно, не равно – не выводит 1
if($zero=="") echo 3 // Вопреки ожиданиям печатает 3!
if(""==$zero) echo 4 // И это тоже не поможет!..
if("$zero"=="") echo 5
// Не работает в некоторых версиях PHP 3
if(strval($zero)=="") echo 6;
// Теперь правильно – не выводит 6
if($zero==="") echo 7
// Самый лучший способ, но не действует в PHP 3
В операциях сравнения пустая строка "" прежде всего трактуется как 0 (ноль) и уж затем – как «пусто»! Операнды сравниваются как строки только в том случае, если они оба – строки, в противном случае идет числовое сравнение. При этом пустая строка воспринимается как 0, как и любая другая, которую интерпретатору не уда лось перевести в число.
При сравнении двух переменных-строк, нужно быть абсолютно уверенными, что их типы именно строковые, а не числовые. Это не распространяется на оператор === (оператор эквивалентности). Его использование заставляет интерпретатор всегда сравнивать величины и по значению, и по их типу. С точки зрения PHP 0=="", но 0!==="". Нужно всегда использовать === вместо strval()!
Существует одна стандартная ошибка, которая состоит в использовании функция strpos($str,$what), которая возвращает позицию подстроки $what в строке $str или false, если подстрока не найдена. Пусть нужно проверить, встречается ли в строке $str подстрока <? (и напечатать «это PHP-программа», если встречается). Вариант
if(strpos($str,"<?")!=false)
echo "это PHP-программа";
не годится, если <? находится в самом начале строки (в этом случае не будет выдано сообщение, хотя подстрока в найдена, и функция возвратила 0, а не false). Вместо проверки на неравенство, нужно проверять на неэквивалентность:
if(strpos($str,"<?")!===false)
echo "это PHP-программа";
Оператор !=== используется с константой false, а не с пустой строкой "". Для оператора false!==="", в то время как, false=="".
Функции для работы с одиночными символами:
string chr(int $code)
Возвращает строку из одного символа с кодом $code. Эта функция используется для вставки непечатаемых символов в строку – например, кода нуля или символа прогона страницы, а также при работе с бинарными файлами.
int ord(char $ch)
Функция возвращает код символа $ch.
int strrpos(string $where, char $what)
Функция ищет в строке $where последнюю позицию, в которой встречается символ $what (если $what – строка из нескольких символов, то выявляется только первый из них, остальные не играют никакой роли!). В случае, если искомый символ не найден, возвращается false
Функции отрезания пробелов:
string trim(string $st)
Функция возвращает копию $st, только с удаленными ведущими и концевыми пробельными символами. Под пробельными символами здесь и далее подразумеваются: пробел " ", символ перевода строки \n, символ возврата каретки \r и символ табуляции \t. Например, вызов trim(" test\n ") вернет строку "test".
string ltrim(string $st)
Аналогична функции trim(), только удаляет исключительно ведущие пробелы, а концевые не трогает.
string chop(string $st)
Удаляет только концевые пробелы, ведущие не трогает.
Базовые функции:
int strlen(string $st)
Возвращает длину строки $st.
int strpos(string $where, string $what, int $fromwhere=0)
Пытается найти в строке $where подстроку (то есть последовательность символов) $what и в случае успеха возвращает позицию (индекс) этой подстроки в строке. Первый символ строки имеет индекс 0. Необязательный параметр $fromwhere можно задавать, если поиск нужно вести не с начала строки $from, а с какой-то другой позиции. В этом случае следует эту позицию передать в $fromwhere. Если подстроку найти не удалось, функция возвращает false. Проверяя результат вызова strpos() на false нужно использовать только оператор ===.
string substr(string $str, int $from [,int $length])
Функция возвращает участок строки $str, начиная с позиции $start и длиной $length. Если $length не задана, то подразумевается подстрока от $start до конца строки $str. Если $start больше, чем длина строки, или же значение $length равно нулю, то возвращается пустая подстрока. Если передать в $start отрицательное число, то будет считаться, что это число является индексом подстроки, но только отсчитываемым от конца $str (например, 1 означает «начиная с последнего символа строки»). Параметр $length, если он задан, тоже может быть отрицательным. В этом случае последним символом возвращенной подстроки будет символ из $str с индексом $length, определяемым от конца строки.
int strcmp(string $str1, string $str2)
Сравнивает две строки посимвольно (точнее, побайтово) и возвращает: 0, если строки полностью совпадают; 1, если строка $str1 лексикографически меньше $str2; и 1, если, наоборот, $str1 «больше» $str2. Так как сравнение идет побайтово, то регистр символов влияет на результаты сравнений.
int strcasecmp(string $str1, string $str2)
Аналогична strcmp(), только при работе не учитывается регистр букв. С точки зрения этой функции "ab" и "AB" равны.
