ProfiPHPProfiPHP
Категория: PHP для чайников

Повторное использование кода в PHP

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

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

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

- Существенная оптимизация. Чем меньше кода, тем более оптимизированным и простым становиться сценарий.

Язык РНР предоставляет возможность осуществить использование повторного кода двумя вариантами: с помощью подключение файла в сценарий или путем использования функций.

Включение кода в сценарий

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

Для примера возьмем ситуацию, когда необходимо создать каталог товаров, который содержит очень большое количество страниц. Каждый товар имеет свои атрибуты, одним из которых является изображения. Размеры изображений можно задать как константы с последующим использованием их в дескрипторах HTML для вывода изображений, что позволит отображать все картинки одинакового размера. При изменении значения констант, можно изменять везде размеры изображений. Создать константы можно следующим образом:
define( 'WIDTH', 100 ); 
define( 'HEIGHT', 100 );
Их использование осуществляется следующим образом:
<img src="/image.jpg" height="<?php echo HEIGHT?>" width="<?php echo WIDTH?>" /> 
Чтобы в каждом файле сценария не определять данные константы, достаточно объявить их в одном файле, например setting.php, а затем включать его в сценарий там, где это будет нужно. Для включения файла следует воспользоваться выражением:
include( 'setting.php' );
Подключаемый фрагмента кода интерпретатор РНР вставляет в исходный файл вместо инструкции Include. Следовательно HTML-дескрипторы, содержащие константы HEIGHT и WIDTH, будут отображаться следующим образом:
<img src="/image.jpg" height="100" width="100" />
Web страница отобразит изображение, у которого ширина и высота равна 100 пикселей.

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

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

В языке РНР имеются также функции Require и Require_once, которые подобны Include, но отличаются способом обработки ошибок. Если файла не существует, функция Require выдаст ошибку и сценарий остановится. При использовании Include будет выведено только сообщение об ошибке, но сценарий продолжит выполняться.

В качестве имен файлов также можно использовать значения переменных:
include( "$filename" ); 
Приведем пример. Если у вас на сайте содержится блок, где указан сегодняшний день и соответствующий ему праздник. Для реализации можно создать отдельные файлы для каждого дня:
0101.inc

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

Далее мы подключаем нужный нам файл:
$today = date( "dm" );
include( $today.'.inc' );
В результате выполнения функции Date, переменной $today будет присвоено сокращенное название числа и месяца. Вторая строка подключает необходимый файл. Например, если $today равно 1404 (14 число апреля месяца), то будет подключен файл "1404.inc".

Размещение файлов включения

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

Предположим, что в Web-окружении имеется файл "setting.inc", который можно загрузить следующим образом:
http://mysite.org/setting.inc
Хоть расширение файла ".inc" явно указывает, что он вспомогательный и предназначен для включения, а не для отдельной обработки, после его прямого указания будет выведено все данные, которые сохраняются в файле "setting.inc", например:
<?php 
$password = 'abcdef';
?>
По умолчания Web-серверы не настроены на обработку PHP-кода в файлах с расширениями, отличными от ".php". В результате чего, мы увидим не обработанный код файла "setting.inc", и его содержимое будет отображено пользователю как HTML-код. Для защиты от подобных случаев можно предпринять одно из следующих действий:

- Подключать файл с расширением ".php", что заставит Web-сервера обрабатывать файл сценария РНР. Независимая обработка отдельных файлов включения крайне нежелательна. Например, если подключаемый файл предназначен для удаления информации, тогда независимая обработка такого файла может иметь нежелательные последствия.

- Разместить файл в месте, недоступном извне. Это решение является наиболее предпочтительным. Хотя оно не всегда реализуемо, например при использовании услуг Web-хостинговой компании.

Установка путей для файлов включения

В конфигурационном файле php.ini модуля PHP, можно задать специальные пути, которые будут использоваться для загрузки файлов включения. Данную возможность обеспечивает директива Include_path. Рассмотрим следующие пример:
include_path = ".;/var/www/mysite.com/incl"
Данная строка определяет каталоги, в которых интерпретатор РНР будет искать файлы
включения. Первое значение (символ точки) соответствует текущему каталогу, за которым следует имя второго каталога. РНР позволяет определить столько каталогов, сколько необходимо. При этом порядок проверки каталогов на наличие файлов включения соответствует порядку значений, указанному в директиве Include_path. Разделителем этих значений для операционных систем Windows является точка с запятой и двоеточие - для Unix/Linux.

Для доступа к файлу включения по установленному пути необходимо использовать просто его имя. Если указан полный путь, директива Include_path будет проигнорирована.
Include( 'setting.php' );
Если необходимый файл не содержится по адресу, указанному в директиве Include_path
или в том же каталоге, что и сам сценарий, следует указать полный путь к файлу.

Создание повторно используемого кода

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

Предположим, что к каждой Web-странице необходимо добавить следующую информацию:
echo 'В случае перепечатки материалов с данного сайта, обязательно должна быть прямая индексируемая ссылка';
Мы можем создать функцию, например с именем copyright(), и использовать ее на каждой странице, чем каждый раз писать один и тот же код в конце сценария. Обратите внимание на наличие скобок после имени функции. Они являются обязательными и указывают интерпретатору РНР на то, что выполняется вызов функции.

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

Определение функций

Для создания функции необходимо написать название и определить набор команд, которые она должна выполнять. Общий синтаксис функции имеет вид:
function имя_функции( ) 
{
набор команд;
return;
}
Для примера создадим функцию вывода копирайта, описанную выше:
function copyright( ) {
echo 'В случае перепечатки материалов с данного сайта, обязательно должна быть прямая индексируемая ссылка';
return;
}
Не обязательная инструкция Return останавливает выполнение тела функции и передает управление основному коду сценария.

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

Функции можно передать значения, в зависимости от которого происходит выполнение операций:
function copyright( $website ) {
echo 'В случае перепечатки материалов с данного сайта, обязательно должна быть прямая индексируемая ссылка на '.$website;
return;
}
В этом случае функция считывает значение параметра, которое содержится в параметре
$website. Далее оно используется в теле функции для вывода нужной информации:
copyright( 'mysite.org' );
Результатом выполнения функции может быть некое возвращаемое значение (returning value). Для этого используется оператор Return. Предположим, что в результате выполнения функции copyright() информацию необходимо сохранить в переменную и не выводить на экран. Это можно осуществить следующим образом:
function copyright( $website ) {
$str = 'В случае перепечатки материалов с данного сайта, обязательно должна быть прямая индексируемая ссылка на '.$website;
return $str;
}
Для вывода информации необходимо выполнить следующее действие:
echo copyright( 'mysite.org' );
Использование переменных в функциях

Переменные, которые используются и доступны только в тебе функции называются локальными. Для определения глобальной переменной, которая будет доступна извне, ее необходимо объявить глобальной, используя ключе слово Global. Рассмотрим пример создания локальной переменной внутри функции:
function username( $first_name, $last_name ) {
$name = $last_name.', '.$first_name;
return $name;
}
Функцию username() можно вызвать, передав ей соответствующие значения, и попытаться вывести переменную $name:
username( 'Василий', 'Пупкин' );
echo $name;
Однако в результате ничего выведено не будет, поскольку в переменная $name не содержит никакого значения. Эта переменная была создана внутри функции и не доступна из основного кода сценария.

Для объявления глобальной переменной, необходимо использовать ключевое слово Glogal,
после чего переменную можно использовать вне тела функции и вывести ее значение:
function username( $first_name, $last_name ) {
Global $name;
$name = $last_name.', '.$first_name;
return $name;
}
Аналогичным образом, если переменная объявлена вне тела функции, а затем переменная с тем же именем объявлена внутри функции, то внешняя переменная будет доступна внутри функции только в том случае, если в функции она объявлена глобальной. Для примера рассмотрим следующий фрагмент кода:
$first_name = 'Василий';
$last_name = 'Пупкин';
function username( ) {
Global $first_name, $last_name;
echo $last_name.', '.$first_name;
}
username( );
Если при объявлении переменных $first_name и $last_name в теле функции не использовать ключевое слово Global, созданные локальные переменные будут отличаться от глобальных.

Передача значений в функцию

Чтобы передать значения в функцию, необходимо их заключить в скобки после имени функции:
function имя_функции( значение1, значение2, ... ) 
{
набор команд;
return;
}
Передача значений корректного типа

В качестве аргументов можно использовать переменные любого типа, включая массивы или объекты. Рассмотрим следующий пример:
function add_numbers( $numbers )
{
for( $i = 0; $i < sizeof( $numbers ); $i++ )
{
@$sum = $sum + $numbers[$i];
}
return $sum;
}
$arr = array( '1', '2', '3' );
echo add_numbers( $arr );
Данная функция вычисляет сумму элементов массива. Если же переданная переменная не является массивом, интерпретатор РНР преобразует ее к нужному типу: числу или строке, что в результате может привести к неправильному выполнению операции. Чтобы этого не случилось, необходимо проверять переданную ей информацию. Например, в предыдущее выражение перед циклом for можно добавить следующее условие:
if ( ! is_array( $numbers ) )
{
echo "Переданная переменная не является массивом";
exit( );
}
Точно так же эта функция должна проверить, что элементы массива являются числами.

Передача значений в корректном порядке

В котором порядке передаются значения в функции, в таком же порядке функция их получает. Рассмотрим следующий пример:
function myFunction( $x, $y, $z ) 
{
// выполнение некоторых действий
}
Осуществим вызов этой функции:
myFunction( $var1, $var2, $var3 );
При этом происходит следующее: переменной присваивается переданное значение
$var1, переменной - значение $var2 и переменной $z - $var3.

Если при вызове функции порядок переданных аргументов не соответствует тому, который использовался при определении, - возникает ошибка.

Передача корректного количества переменных

Функции необходимо передать определенное количество переменных. Если одна из них пропущена, ей присваивается значение NULL. Рассмотрим следующий пример вывода сообщения об ошибке:
Warning: Missing argument 2 for myFunction(), called in file.php on line 8 and defined in file.php on line 3 
(Предупреждение: Отсутствует аргумент 2 функции myFunction() в файле file.php в строке 8 и определение в файле file.php в строке 3)
Предупреждения (warning) не останавливают выполнение сценария.

Если функции передать слишком много аргументов, лишние из них будут проигнорированы.

Переменным, значения которых передаются в функцию, можно присвоить значения по умолчанию, которое будет передано, если аргумент не передан.
function myFunction( $x = 1, $y = 'world' )
Передача значений по ссылке

При передаче аргументов по значению переданное значение копируется в локальную переменную, которая и используется в теле функции. Для изменение значение извне необходимо использовать глобальные переменные, но можно также осуществить, используя передачу по ссылки (passing by reference). Для этого при определении функции необходимо добавить знак амперсанта (&) перед именем переменной:
$first_name = 'Василий';
function username( &$first_name ) {
return $first_name = $first_name.' Пупкин';
}
username( $first_name );
echo $first_name;
При вызове этой функции в качестве аргумента передается не значение, а адрес, по которому хранится переменная. Поэтому в результате в переменной $first_name будет хранится строка: Василий Пупкин.

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

Возвращаемое значение функции

Для возвращения значения функции в языке РНР используется оператор Return. Это значение затем может обрабатываться различными способами.

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

Использование встроенных функций

Язык РНР имеет большой набор полезных встроенных функций, которые используются наряду со стандартными функциями и ничем не отличаются от пользовательских. Они имеют следующий общий вид:
isset( $varname )
empty( $varname )
Обработка ошибок
Хорошо написанная функция должна предвидеть все возможные ситуации и случае ошибки возвращать значение FALSE. Лучше вывести пользователю собственноручно созданное сообщение, чем стандартное предупреждение, сгенерированное РНР. Для этого в РНР предусмотрена функция Exit и Die.

Добавить комментарий

Имя:
Текст комментария: