Php аргументы функции по умолчанию. Реализация механизма разграничения прав доступа к админ-части. Значения аргументов функции по умолчанию

Передача аргументов пользовательским функциям

При объявлении функции можно указать список параметров, которые могут передаваться функции, например:

function funct ($a , $b , /* ..., */ $z ) { ... };
?>

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

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

  • параметры-значения;
  • параметры-переменные.

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

По умолчанию аргументы в функцию передаются по значению (это означает, что если вы измените значение аргумента внутри функции, то вне ее значение все равно останется прежним). Приведем пример:

function funct ($string )
{
echo "

Параметр = $string

" ;
}

$str = 777 ;
funct (777 );
funct ($str );

// Функция "funct" выведет строку "Параметр = 777" дважды

?>

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

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

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

function funct (& $string )
{
$string .= "а эта внутри." ;
}
$str = "Эта строка за пределами функции, " ;
funct ($str );
echo $str ; // Выведет "Эта строка за пределами функции, а эта внутри."
?>

Параметры по умолчанию

При программировании часто возникает необходимость создания функции с переменным числом параметров. Тому есть две причины:

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

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

function makecup ($type = "Чая" )
{
return "Сделайте чашечку $type.\n" ;
}
echo makecup ();
echo makecup ("Кофе" );
?>

Результат работы приведенного скрипта будет таким:

Сделайте чашечку Чая
Сделайте чашечку Кофе

PHP также позволяет использовать массивы и специальный тип NULL в качестве значений по умолчанию, например:

function makecup ($types = array("Кофе" ), $Maker = NULL )
{
$device = is_null ($Maker ) ? "сахаром" : $Maker ;
return "Сделайте чашечку " . join (", " , $types ). " с $device.\n" ;
}
echo makecup ();
echo makecup (array("Кофе" , "Чая" ), "сливками" );
?>

Рассмотренный скрипт выведет следующее:

Сделайте чашкчку Кофе с сахаром. Сделайте чашечку Кофе, Чая с сливками.

Значение по умолчанию должно быть константным выражением.

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

function makecup ($type = "чая" , $cond )
{
return ;
}

Echo makecup ("горячего" ); // Не будет работать так, как мы могли бы ожидать
?>

Результат работы приведенного выше скрипта будет примерно следующим:

Warning : Missing argument 2 for makecup() in c:\inetpub\сайт\test.php on line 2
Сделайте чашечку горячего.

Теперь видоизменим рассмотренный скрипт, исправив в нем ошибки:

function makecup ($cond , $type = "чая" )
{
return "Сделайте чашечку $type $cond.\n" ;
}

Echo makecup ("горячего" ); // Теперь наш скрипт работает корректно!
?>

Результат работы исправленного скрипта будет выглядеть следующим образом:

Сделайте чашечку чая горячего.

Внимание! Начиная с PHP 5 , значения по умолчанию могут быть переданны по ссылке!

Переменное число аргументов в функциях

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

Реализация этой возможности достаточно прозрачна и заключается в использовании функций func_num_args() , func_get_arg() и func_get_args() .

Рассмотрим возможности рассмотренных стандартных функций:

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

function funct ()
{
$numargums = func_num_args ();
echo "Колличество аргументов: $numargums\n" ;
}

Funct (1 , 2 , 3 ); // Скрипт выведет "Колличество аргументов: 3"
?>

Стандартная функция func_get_arg() возвращает элемент из списка переданных пользовательской функции аргументов:

function funct ()
{
$numargs = func_num_args ();
echo "Колличество аргументов: $numargs
\n"
;
if ($numargs >= 2 ) {
echo "Второй аргумент: " . func_get_arg (1 ). "
\n" ;
}
}

Funct (1 , 2 , 3 );
?>

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

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

Передача аргументов

PHP поддерживает два способа передачи аргументов функции. Первый - передача аргументов по значению (работает по умолчанию), второй - передача аргументов по ссылке. Также PHP поддерживает значения по умолчанию. Давайте теперь рассмотрим все три варианта подробнее.

По умолчанию аргументы передаются в функцию по значению (это значит, если вы измените значение параметра внутри функции, то вне ее переданное значение останется прежним):

$color цвет"; // Значение переменной не изменилось?>

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

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

\n"; } echo tea(); // выведет значение по умолчанию echo tea("черный"); ?>

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

Значение, возвращаемое функцией

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

Return выражение;

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

"; // => 16. function foo($num) { if($num === 10) return "$num равно 10"; else return "$num не равно 10"; echo "hello"; // эта строка кода никогда не выполнится } echo foo(6); ?>

Подписчикам

Аргументы функции

Что такое аргументы функции?

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

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

Передача аргументов функции по значению и по ссылке

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

При передаче аргументов по значению исходное значение внешней переменной остается постоянным при изменении значения аргумента внутри функции. Если же требуется, чтобы функция могла влиять на значение внешней переменной, необходимо передавать ей аргументы по ссылке. Делается это при помощи символа амперсанда "&" перед именем аргумента в описании функции (см. пример №1).

Пример №1. Передача аргументов функции по значению и по ссылке

Значения аргументов функции по умолчанию

Также в PHP имеется возможность использовать для аргументов функции значения по умолчанию , которые представляют собой значения, используемые в случае, если данному аргументу при вызове функции не будет передано вообще никакого значения. Для того, чтобы задать значение аргумента по умолчанию, необходимо в определении функции присвоить желаемое значение данному аргументу (см. пример №2). При этом значения по умолчанию могут иметь как аргументы, передаваемые по значению, так и аргументы, передаваемые по ссылке. Однако в любом случае все аргументы, которым присваиваются значения по умолчанию, должны идти в списке после аргументов, у которых значения по умолчанию отсутствуют. Кроме того, в качестве значений по умолчанию могут использоваться только константные выражения, а также массивы и значение NULL . Использовать, например, переменные или вызовы функций нельзя.

Пример №2. Использование значений аргументов по умолчанию

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

Если точное количество аргументов, передаваемых функции, заранее не известно, можно использовать список аргументов переменной длины . Такой список формируется при помощи специальной переменной, перед которой ставится многоточие "..." . В результате аргументы будут переданы в указанную переменную в виде массива (см. пример №3).

Пример №3. Использование списка аргументов переменной длины

Перед многоточием можно указывать обычные аргументы, при этом все остальные аргументы, переданные функции будут занесены в массив. Более того, перед многоточием можно указывать тип аргументов, которые могут быть занесены в массив, а также знак амперсанда "&" для передачи аргументов по ссылке (см. пример №4).

"; //Выведет 10, т.к. значение было передано функции //по ссылке и затем изменено функцией на 10 echo $a_1; ?>

Пример №4. Особенности использования списка аргументов переменной длины

Разрешается использовать многоточие "..." для разворачивания массива, передаваемого в качестве аргумента функции, в аргументы функции в виде его элементов (см. пример №5).

"; //Присваиваем массив переменной $a_3=; //Разворачиваем переданный функции массив //Выведет 3 echo m_sum_2(...$a_3); ?>

Пример №5. Разворачивание массива аргументов, переданного функции при вызове

Функции для доступа к аргументам

  • func_get_args() - возвращает массив, состоящий из аргументов функции;
  • func_get_arg(n) - возвращает указанный аргумент функции, где n=0,1,2,... - номер аргумента в списке, который начинается с нуля (напомним, что аргументы вычисляются слева направо);
  • func_num_args() - возвращает количество реально переданных функции аргументов.

"; //Выведет значение третьего аргумента, переданного функции echo func_get_arg(2); //Возвращаем сумму аргументов функции return $sum; } //Вызвали функцию. Выведет 38, т.е. количество переданных аргументов равно 3, //а значение 3-го аргумента равно 8 (нумерация элементов начинается с нуля) m_sum(1,2,8); ?>

Пример №6. Использование специальных функций для работы аргументами

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

Быстрый переход к другим страницам

Http://сайт Copyright © Петр Романовский, Минск, 2016-2019.

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

Что ж, сама по себе данная тема довольно грузная, и требует определённого времени на анализ и постанувку задачи.

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

Давайте с самого начала обсудим архитектуру модульной системы на выбранной нами псевдо-системе.

Все модули представлены ввиде подключаемых к главному документу (индекс-файлу) вставок. Запрос модуля происходит из строки запроса QUERY_STRING, и название подключаемого модуля передаётся в качестве аргумента act. В некотором месте индекса файла происходит изъятие и обработка данного параметра. После, если у пользователя достаточно прав для доступа к модулю в контексте чтения, происходит проверка существования указанного в строке запроса модуля, и если таковой существует, то происходит его подключение к индекс файлу.

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

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

Значение do буду фиксированными, данная переменная будет принимать следующие значения:

  • main - главная часть модуля (доступно в контексте чтения)
  • config - раздел настройки модуля (доступно в контексте записи)
  • create - произвести некоторые действия, по добавлению информации в БД (доступно в контексте записи)
  • delete - доступ к разделу, предоставляющему возможности удалить некоторую информацию, в контексте данного модуля (доступно в контексте записи)
  • edit - доступ к редактированию информации в контексте модуля (доступно в контексте записи)

В целом, этот список можно увеличить, при этом всё зависит лишь только от масштабов проекта и его потребностей в функционале.

Теперь непосредственно о модулях. Кроме физического существования некоторого модуля в контексте файловой системы проекта, модуль так же должен быть добавлен в особую таблицу БД, которая будет содержать информацию о всех существующих модулях в системе. Добавление и изменение данных данной таблицы, обычно, производится непосредственно в контексте модулей, а то есть во время их инсталяции в системе. Однако это уже углубление в принципы посмотроения расширяемых систем, о чём мы как-то в другой раз поговорим, и посему, мы ограничимся ручным обновлением и добавлением данных о модулях.

Так, запись о модуле системы будет содержать следующую информацию: английский идентификатор названия модуля, который будет идентичен значению переменной среды GET - act (относительно него будет производится непосредственно запрос модуля), русский идентификатор модуля, который будет использоватся в списке модулей.

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

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

Что ж, давайте рассмотрим эту особую структуру. Она будет следующей: [ module_indefier: + \: + \;] *

То есть идёт список из пар: имя модуля ":" права чтения "," права записи ";". При этом данная метка обновляется в момент внесения изменений о правах доступа пользователя к системе. Если в системе появляется информация о модуле, который не вошёл в данную метку, то стоит просто произвести процедуру редактирования, и данные сохранятся автоматически.

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

Я не буду добавлять ничего лишнего в неё, но лишь то, что будет использоватся в контексте темы данной статьи. Таблица пользователей будет содержать следующие поля: идентифицатор пользователя (числовой счётчик), логин, пароль (хеш оригинального пароля), профиль безопасности пользователя (идетификатор группы пользователя, относительно прав в системе), и всё. Мне кажется этой информации нам с вами вполне хватит, для реализации поставленной задачи, а уже все остальные надстройки я предоставляю возможность сделать самим.

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

Таблица `modules`:

CREATE TABLE `modules` (`id` bigint(20) NOT NULL auto_increment, `indefier` text collate utf8_unicode_ci NOT NULL, `title` text collate utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Таблица `secure_groups`:

CREATE TABLE `secure_groups` (`id` bigint(20) NOT NULL auto_increment, `title` text collate utf8_unicode_ci NOT NULL, `perms` text collate utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;

Таблица `users`

CREATE TABLE `users` (`id` bigint(20) NOT NULL auto_increment, `login` text collate utf8_unicode_ci NOT NULL, `passwd` text collate utf8_unicode_ci NOT NULL, `groupId` int(1) NOT NULL default "0", PRIMARY KEY (`id`)) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;

temp=array(); $this->temp["_result"]=0; $this->temp["_uid"]=explode("::",$_COOKIE["site_hash"]); $this->temp["_uid"]=$this->temp["_uid"]; $this->temp["_gid"]=$this->getUserSecurityAccess($this->temp["_uid"]); $this->temp["_conn_id"]=mysql_connect("host","user","passwd"); mysql_select_db("database"); $this->temp["_q1"]=mysql_query("SELECT perms" ."FROM `secure_groups`" ."WHERE id=".$this->temp["_gid"]); $this->temp["_access_stamp"]=mysql_fetch_assoc($this->temp["_q1"]); $this->temp["_access_stamp"]=$this->temp["_access_stamp"]["perms"]; $this->temp["_access_stamp"]=explode(";",$this->temp["_access_stamp"]); $this->temp["_access_stamp"]=array_slice($this->temp["_access_stamp"],0,-1); foreach($this->temp["_access_stamp"] as $this->temp["v"]){ $this->temp["_mod_access"]=explode(":",$this->temp["v"]); $this->temp["_mod_indefier"]=$this->temp["_mod_access"]; if($this->temp["_mod_indefier"]==$module){ $this->temp["_perms"]=explode(",",$this->temp["_mod_access"]); switch($act){ case "r": $this->temp["_result"]=($this->temp["_perms"]==1)? 1:0; break; case "w": $this->temp["_result"]=($this->temp["_perms"]==1)? 1:0; break; } break; } } mysql_close($conn_id); return $this->temp["_result"]; } } ?>

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

Функция secure::getUserId()

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

Функция secure::getUserSecurityAccess($id)

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

Функция secure::checkUserPermission($module,$act))

Производится запрос к БД, относительно прав пользователя на произведение действий чтения/записи в контексте переданного в качестве параметра модуля.

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

Процедура авторизации будет выглядеть ввиде внесения личных данных пользователя (логин и пароль) в специальную форму, после отправки которой произойдёт обработка данных, переданных пользователем, по-методу функции checkAuthData(), и, в случае корректности данных, будет произведено сохранение данных о пользователе ввиде куки записи на период установленный пользователем, либо в отсутствии заданного значение на период по-умолчанию.

Для проверки аутентичности данных хранимых в переменной среде $_COOKIE, мы будем использовать функцию EatCookie(), которая будет производить валидацию данных, возвращая булевый результат проверки (истина - ложь).

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

  • `ulogin` - логин пользователя
  • `upasswd` - пароль пользователя
  • `stime` - время сессии, устанавливаемое пользователем (от 1 до 5 часов)
  • `auth` - имя кнопки отправки

Вот, в целом и всё. Осталось лишь пробовать, экспериментировать, ошибатся и находить решение, что я всецело и оставляю вам.

Надеюсь, что мы скоро встретимся, а для тех кто имеет ко мне вопрос в отношении статьи, да и не только - писать на [email protected], либо на [email protected].

С уважением Карпенко Кирилл, глава IT-отдела ИНПП.