Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

PHP5_nachinayushim

.pdf
Скачиваний:
29
Добавлен:
20.03.2015
Размер:
26.79 Mб
Скачать

284 Глава 6

Рис. 6.2.

Следующие три строки отображают значения глобальной, локальной и статиче+ ской переменных внутри функции:

echo "<br>содержимое глобального сообщения: " . $GLOBALS["global_message"]; echo "<br>содержимое локального сообщения: " . $local_message;

echo "<br>статическое число: " . $static_number;

Оператор return изменяет значение $static_number, увеличивая его на 1:

return $static_number = $static_number+1;

}

Программа начинает свою работу с вызова функции my_function():

echo "<b>Первый вызов функции:</b>"; my_function();

Отображаются значения глобальной, локальной и статической переменных, кото+ рые внутри функции равны "Глобальное сообщение", "Локальное сообщение" и 0.

Создание высококачественного кода 285

Как только функция заканчивает работу, выводится содержимое данных переменных вне функции. Здесь в зависимости от уровня отображения сообщений об ошибках возможно появление предупреждений о неопределенных переменных ++++++ это нор+ мально. Переменные $local_message и $static_number определены только внут+ ри кода функции, поэтому вне его они не существуют:

echo "<br><br><b>За пределами функции:</b>";

echo "<br>содержимое глобального сообщения: " . $global_message; echo "<br>содержимое локального сообщения: " . $local_message; echo "<br>статическое число " . $static_number;

Данная функция вызывается еще несколько раз, и каждый раз показывает значе+ ния своих внутренних переменных, а также значения переменных за ее пределами. Внутри функции изменяется только переменная $static_number.

Вложенность функций

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

Например, можно написать родительскую функцию parent, внутри которой оп+ ределяется другая функция (назовем ее child). Проблема заключается в том, что если вызвать функцию parent дважды, то интерпретатор дважды попытается определить функцию child, а так как переопределять функции нельзя, сценарий аварийно за+ вершится. В большинстве случаев лучше определять функции отдельно.

Однако возможна другая ситуация (кроме использования функции переключения, которая рассматривалась выше), когда необходимо вызвать функцию из функции: ре+ курсия (функция вызывает сама себя).

Рекурсия

Вызов функции из самой себя называется рекурсией (recursion). Рекурсивный вызов функции создает циклические структуры, в которых функция продолжает вызывать себя до тех пор, пока удовлетворяется определенное условие. Однако условие необ+ ходимо явно создать внутри кода функции. Если нет уверенности, что существует ка+ кое+либо стоп+значение, которое так или иначе будет достигнуто, то рекурсия может длиться бесконечно. Рассмотрим небольшой пример.

Практика Рекурсивный вызов функции

1. Запустите редактор Web+страниц и введите следующий код:

<html>

<head></head>

<body>

<?php

if ($_POST['posted']) {

$num = $_POST['num']; function recursion($num) {

286 Глава 6

if ($num <= 1) { return 1;

} else {

return $num * recursion($num-1);

}

}

echo "Факториал " . $num . " равен " . (recursion($num));

}

?>

<form method="POST" action="recursion.php">

<input type="hidden" name="posted" value="true">

Найти факториал числа

<input name="num" type="text"> <br>

<br>

<input type="submit" value="Рассчитать факториал"> </form>

</body>

</html>

2.Сохраните файл как recursion.php и закройте его.

3.Откройте страницу recursion.php в браузере (рис. 6.3).

Рис. 6.3.

Теперь, если выбрать значение и нажать кнопку Рассчитать факториал, то добро+ совестный код с рекурсией выдаст ответ. Пример показан на рис. 6.4.

Создание высококачественного кода 287

Рис. 6.4.

Как это работает

Сначала объявляется рекурсивная функция, которой затем в качестве аргумента передается переменная $num_value:

<?php

if ($_POST['posted']) {

$num = $_POST['num']; function recursion($num) {

if ($num <= 1) { return 1;

} else {

return $num * recursion($num-1);

}

}

echo "Факториал " . $num . " равен " . (recursion($num));

}

?>

Затем необходимо убедиться, что значение $num больше единицы; если это не так, то возвращается 1 (факториал от 1, как известно, равен 1). Если введенное число больше единицы, то выполняется рекурсивная часть функции. В конце концов, выво+ дится результат.

В каждой итерации цикла значение не только умножается на последнее получен+ ное число (рекурсивная часть), но и постоянно уменьшается на единицу, чтобы га+ рантировать, что цикл, в конце концов, завершится. Этот сценарий не подходит для вычисления факториалов больших чисел, кроме того, он не работает с отрицатель+ ными числами, но в качестве примера его работы вполне достаточно.

288 Глава 6

Операторы include и require

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

Можно отметить некоторые особенности работы данных конструкций.

Файл подключается путем вставки одной из этих конструкций в PHP+код, но синтаксический анализ основного файла в этой точке переходит из PHP+ режима в HTML+режим, поэтому чтобы запускать код подключаемого файла, этот код все равно необходимо помещать между соответствующими PHP+ разделителями.

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

PHP+сценарий внутри подключаемого файла выполняется при подключении. Любые PHP+переменные и их значения доступны в главном файле, как будто весь код подключаемого файла непосредственно вставлен в главный файл.

Рассмотрим несколько примеров использования данных конструкций в коде (можно использовать полные абсолютные или относительные пути):

include("filename") require ("filename");

Например, чтобы подключить с помощью include файл test.txt, необходимо использовать такой код:

include("test.txt");

Если файл test.txt содержит какой+либо текст, то этот текст будет включен в Web+страницу так, как если бы он был непосредственно записан в ее исходном коде.

Примечательно то, что в круглых скобках функций include или require можно также использовать имена переменных или присоединять переменные к имени файла с тем, чтобы сформировать имя существующего файла:

$Name ="1";

include ("test" . $Name . ".txt");

В результате этой конкатенации создается имя test1.txt, и если файл с таким име+ нем существует, значит он будет подключен, в противном случае генерируется ошибка.

Ниже перечислены ситуации, в которых подключаемые файлы удобны:

подключение текстового файла к странице;

определение переменных и/или констант, а также текста некоторых сообще+ ний об ошибках;

Создание высококачественного кода 289

вставка в страницу значений HTTP+переменных;

выполнение отдельного PHP+сценария (даже если он ничего не возвращает);

подключение часто используемых функций, которые нежелательно определять в каждой странице.

Подключаемые файлы удобны потому, что их можно непосредственно добавлять к файлу и в его коде определять необходимость подключения того или иного файла. Эта возможность рассматривается в следующем примере.

Практика Условное подключение

1. Запустите редактор Web+страниц и введите следующий текст:

Подключен первый файл

2.Сохраните созданный файл как file1.txt.

3.Закройте его, создайте новый текстовый файл и введите в него следующий текст:

Подключен второй файл

4.Сохраните данный файл как file2.txt.

5.Закройте данный файл, создайте новый и введите в него следующий код:

<html>

<head><title></title></head>

<body>

<?php

if (isset($_POST['posted'])) { $choice = $_POST['choice']; if ($choice <> "") {

include("file" . $choice . ".txt"); echo "<hr>";

}

}

?>

<form method="POST" action="include.php">

<input type="hidden" name="posted" value="true">

Выберите подключаемый файл? <select name="choice">

<option value="1">первый файл</option> <option value="2">второй файл</option> </select>

<br>

<br>

<input type="submit" value="Вывести текст"> </form>

</body>

</html>

6.Сохраните этот файл как include.php в том же каталоге, что и первые два текстовых файла.

7.Откройте в браузере страницу include.php и выберите файл из списка. На рис. 6.5 показан примерный результат.

290 Глава 6

Рис. 6.5.

Как это работает

Сначала выводится небольшая форма, предоставляющая пользователю выпадаю+ щий список (с именем choice) с двумя вариантами. Следующий PHP+код при выпол+ нении проверяет, какое значение было выбрано (если выбран, например, первый пункт, то значение равно 1) и использует это значение для формирования имени под+ ключаемого файла.

<?php

if (isset($_POST['posted'])) { $choice = $_POST['choice']; if ($choice <> "") {

include("file" . $choice . ".txt"); echo "<hr>";

}

}

?>

Естественно, должны существовать текстовые файлы file1.txt и file2.txt, содержащие какой+либо текст (в противном случае появится сообщение об ошибке).

О чем следует позаботиться при использовании подключаемых файлов

Многие Web+серверы не настроены на синтаксический анализ файлов с расшире+ нием .inc, поэтому лучше задавать для подключаемых файлов расширение .php ++++++

в таком случае никто не сможет просмотреть через Web+браузер содержимое этих

Создание высококачественного кода 291

файлов (возможно, секретное). Например, зная (или лишь догадываясь), что на сайте имеются .inc+файлы (возможно, содержащие секретную информацию, такую как па+ роли к базе данных), злоумышленник может просто ввести в своем браузере полный URL+указатель на такой файл и просмотреть его необработанный исходный код. Ре+ комендуется всегда задавать для подключаемых файлов расширение .php, тогда они безусловно будут обрабатываться PHP+интерпретатором.

Если требуется подключить один файл через другой подключаемый файл, например, через common.inc.php, который подключается вверху каждой страницы (это весьма распространенная Практика), но есть вероятность, что некоторые функции могут слу+ чайно определяться дважды, то следует использовать операторы include_once или require_once. Они работают так же, как include и require, но всегда подключают файл только однажды независимо от того, сколько раз файлы подключаются в коде.

Резюме

Функции представляют собой блоки кода, которые можно вызывать внутри про+ граммы. Они либо определены в PHP автоматически, как, например, функции обработ+ ки массивов sort() и ksort(), которые описывались в предыдущих главах, либо соз+ даются пользователями (пользовательские функции), как было показано в данной главе. Функции можно представить как небольшие ‘‘черные ящики’’, которые возвращают значение в ответ на переданные им соответствующие переменные. Переменные пере+ даются в функции через аргументы, определяемые в начале функции. Если переменные передаются не по ссылке, то значение, возвращаемое функцией, не влияет на перемен+ ные вне данной функции. Возвращаемое функцией значение можно использовать для переключения между различными блоками кода и выполнения различных действий.

В примерах данной главы было показано, что переменные ведут себя по+разному внутри функций. Эти различия вызваны областью видимости переменных. Перемен+ ные с локальной областью видимости существуют только во время работы функции и в конце ее работы уничтожаются, если они не были определены с использованием ключевого слова static. Переменные, определенные за пределами функций, внутри функций должны использоваться либо с ключевым словом global, либо через массив $_GLOBALS. В этой главе рассматривались подключаемые файлы, функции include(), require(), include_once() и require_once(), а также их использование для раз+ биения кода на модули.

Упражнение

Напишите функцию, с помощью которой пользователь сможет создать собствен+ ную Web+форму. В форме должны быть предусмотрены возможности выбора имен полей и типов полей, отправки информации в PHP+страницу и просмотра передан+ ных значений. Для выбора различных функций внутри главной функции необходимо использовать оператор switch..case.

7

Файлы и каталоги

Вряд ли пользователям хотелось бы посещать Web+сайты, код которых мог бы по+ лучить контроль над жестким диском пользовательского компьютера и делать все, что понадобилось разработчику сайта, например, записывать и стирать файлы и катало+ ги. По этой причине создатели языка JavaScript оставили эти возможности за рамками данного языка. PHP не имеет возможности записывать и стирать файлы с жесткого диска пользователя, но может создавать и удалять файлы и каталоги на Web+сервере. Это очень полезная возможность, потому что часто самый простой и наиболее эф+ фективный способ реализации в приложении определенной функциональности за+ ключается в использовании файловой системы сервера.

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

Файлы могут содержать любые данные, а также информацию о самих себе, напри+ мер, имя владельца файла и дату создания. PHP облегчает работу с файловой систе+ мой, предоставляя ряд функций, которые позволяют получать информацию о файлах, открывать их, а также осуществлять считывание информации из файлов и запись в них. Эта глава посвящена PHP+функциям для работы с файловой системой. Здесь описываются PHP+функции чтения и записи файлов, открытие и закрытие файлов с помощью функций fopen() и fclose(), переименование и удаление файлов, нави+ гация в файлах и чтение каталогов. Кроме того, в данной главе рассматривается полу+ чение информации о правах доступа к файлам и пользователях файлов, а также реа+ лизация загрузки файлов на сервер через Web+интерфейс.

Существует множество различных типов файловых систем, хотя, возможно, поль+ зователям, привыкшим к Windows, не очень знакомы другие системы. Большинство Windows+систем предоставляют пользователю свободный доступ к файлам и каталогам,

Файлы и каталоги 293

тогда как Linux+системы обычно ограничивают доступ к файлам и каталогам путем обеспечения различных прав доступа для пользователей в системе. Работа файловой системы NTFS, которую можно использовать в Windows NT/2000 и более старших версиях, больше похожа на работу файловых систем в Linux+машинах ++++++ она также позволяет предоставлять разным пользователям различные права доступа.

Для PHP+разработчика весьма важно знать, используются ли в системе права дос+ тупа к файлам и как эти права устанавливаются, потому что некоторые функции тре+ буют установки определенных прав, прежде чем они смогут выполнить свою работу. К счастью, PHP предоставляет функции для проверки и установки прав доступа, а также для проверки привилегий текущего пользователя. PHP обычно запускается от имени того же пользователя, что и Apache (на Linux/Apache+серверах), или с привилегиями, предоставленными гостевой учетной записью в IIS+системах.

Обработка файлов и каталогов

Вся информация на жестком диске хранится в файлах того или иного типа, хотя большинство пользователей оперирует понятиями файлов и каталогов. Существуют обычные программные файлы, файлы данных, файлы, которые являются каталогами, и специальные файлы, которые позволяют жесткому диску отслеживать содержимое каталогов и файлов. В PHP имеются встроенные функции, которые способны обраба+ тывать любые существующие файлы, но чаще всего приходится работать с текстовы+ ми файлами, содержащими какие+либо данные.

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

Между операционными системами Linux и Windows существует множество разли+ чий, например способ указания путей к каталогам. В Unix+подобных системах, таких как Linux, для разделения элементов пути используются символы косой черты, например:

/home/dan/data/data.txt

В Windows используются символы обратной косой черты:

C:\MyDocs\data\data.txt

К счастью, PHP в Windows в большинстве ситуаций автоматически конвертирует косую черту в обратную косую черту, например, код

$fp = fopen("/data/data.txt", "r");

не должен создавать каких+либо проблем на Windows+платформе. В некоторых случаях необходимо использовать путь непосредственно (например, когда загружен+ ный на сервер файл копируется из временного каталога в какой+либо другой каталог). В таких ситуациях использование обратной косой черты обязательно. Поскольку PHP интерпретирует обратную косую черту как escape+символ (экранирующий следующий за ним символ), путь необходимо задавать следующим образом:

"C:\\MyDocs\\data\\data.txt"

Позднее будет показан простой способ автоматического конвертирования косой черты в обратную косую черту.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]