Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка PHP 2008.doc
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
1 Мб
Скачать
☆

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" равны.