In my web development practice, I very often came across situations in which customers set a specific goal, namely, the division of parts of the admin panel regarding accessibility to certain users. At the same time, the development of this module was carried out in the context of an expandable system, that is, with an unfixed number of modules to which access is organized, and, accordingly, an unlimited number of system users.

Well, on my own this topic It’s quite heavy and requires some time to analyze and formulate the problem.

In the context of this article, we will develop in the context of some abstract information system, with its own infrastructure and architecture, while this system provides the user with the opportunity to expand functionality, that is, install new modules, and accordingly set access rights to them for one or another user registered as a system administrator.

Let's discuss the architecture of a modular system on our chosen pseudo-system from the very beginning.

All modules are presented in the form of inserts connected to the main document (index file). The plugin request comes from the QUERY_STRING query string, and the name of the plugin is passed as the act argument. At some point in the file index, this parameter is retrieved and processed. Afterwards, if the user has sufficient rights to access the module in the reading context, the existence of the module specified in the query line is checked, and if it exists, it is connected to the index file.

I mentioned the “reading context” for a reason, since our system assumes the existence of two contexts for working with the system, namely reading and writing. In this case, reading implies direct access to the module and to those parts of it that do not involve making changes to the data structure in the database. By recording, we mean directly making changes to the information stored in the database.

To implement this mechanism, we will check the value of the `do` query string variable, which is processed in the module itself and carries information about which section of the module needs to be granted access to the user.

The value of do will be fixed, this variable will take the following values:

  • main - the main part of the module (available in reading context)
  • config - module configuration section (available in the recording context)
  • create - perform some actions to add information to the database (available in the context of a record)
  • delete - access to a section that provides the ability to delete some information in the context of a given module (available in the context of a record)
  • edit - access to edit information in the module context (available in the post context)

In general, this list can be increased, but everything depends only on the scale of the project and its functional needs.

Now directly about the modules. In addition to the physical existence of some module in the context file system project, the module must also be added to a special database table, which will contain information about all existing modules in the system. Adding and changing data in this table is usually done directly in the context of modules, that is, during their installation in the system. However, this is already a deepening into the principles of viewing expandable systems, which we will talk about some other time, and therefore, we will limit ourselves to manual update and adding module data.

Thus, a record about a system module will contain the following information: the English identifier of the module name, which will be identical to the value of the environment variable GET - act (the module will be directly requested in relation to it), the Russian identifier of the module, which will be used in the list of modules.

In addition to the modules, we will have two more tables, namely a table in which data regarding access rights profiles will be stored and a table with information about users directly.

The security profile table will consist of only three fields - a profile identifier (the numeric value of the record identifier), a text module identifier (intended for users), as well as a specially generated text label containing information about user rights in the context of each module.

Well, let's take a look at this particular structure. It will be as follows: [module_indefier: + \: + \;] *

That is, there is a list of pairs: module name ":" read rights "," write rights ";". In this case, this label is updated when changes are made to the user’s access rights to the system. If information appears in the system about a module that is not included in this label, then you just need to carry out the editing procedure, and the data will be saved automatically.

Now we just have to look at the structure of just one database table, and we can get down to implementing the algorithmic part, namely the table with information about system users, because assigning access rights to them is our main task.

I will not add anything extra to it, but only what will be used in the context of the topic of this article. The user table will contain the following fields: user ID (numeric counter), login, password (hash of the original password), user security profile (user group ID, relative to rights in the system), and that’s it. It seems to me that this information is quite enough for you and me to implement the task, and I give the opportunity to do all the other add-ons ourselves.

So, we discussed the structure, and, I hope, everyone already has some idea of ​​how we will implement the task set in the topic of the article. Now I will provide auxiliary SQL code for the tables described above, after which I will immediately move on to implementing the algorithm for checking user access rights, as well as creating and changing access profiles. After each individual module, we will discuss in detail any questions that readers may have.

`modules` table:

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` table:

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 ;

Table `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)? break; case "w": $this->temp["_result"]=($this->temp["_perms"]==1) :0; break; ) ) mysql_close($conn_id); return $this->temp["_result"]; ) ) ?>

This class implements functions designed to implement the algorithmic task described above. We will now discuss each function separately.

secure::getUserId() function

Using this function, we mean that during user authorization in the system, the `site_hash` variable was set in the $_COOKIE environment variable, consisting of the user's identifier in the system and a hash to verify its authenticity in the system. The function simply removes the value of the identifier, returning its value as output.

Function secure::getUserSecurityAccess($id)

Output this function returns the security profile ID of the current user on the system.

Function secure::checkUserPermission($module,$act))

A request is made to the database regarding the user's rights to perform read/write actions in the context of the module passed as a parameter.

All that remains is to describe the procedure for creating a variable in the $_COOKIE environment, and the topic of the article can be considered solved.

The authorization procedure will look like entering the user’s personal data (login and password) into a special form, after sending which the data submitted by the user will be processed using the checkAuthData() function method, and, if the data is correct, the user data will be saved as recording cookies for a period set by the user, or in the absence of a specified value, for a default period.

To check the authenticity of the data stored in the $_COOKIE environment variable, we will use the EatCookie() function, which will validate the data by returning a Boolean verification result (true - false).

I do not provide the form to submit, since this is not part of the programming theory, indicating only the field identifiers.

  • `ulogin` - user login
  • `upasswd` - user password
  • `stime` - session time set by the user (from 1 to 5 hours)
  • `auth` - submit button name

That's all. All that remains is to try, experiment, make mistakes and find a solution, which I leave entirely to you.

I hope that we will meet soon, and for those who have a question for me regarding the article, and not only - write to [email protected], or on [email protected].

Sincerely, Kirill Karpenko, head of the IT department of INPP.

For subscribers

Function Arguments

What are function arguments?

Function Arguments are listed separated by commas in parentheses after the name of the function being defined and are its local variables.

Any expressions that are passed to the function for processing and can be evaluated can be used as argument values. In this case, the function may not take any arguments at all, but if there are arguments, they are calculated from left to right.

Passing function arguments by value and by reference

Default arguments are passed to the function by value, but also supported passing arguments by reference and default values.

When passing arguments by value, the original value of the external variable remains constant when the value of the argument inside the function changes. If you want a function to be able to influence the value of an external variable, you must pass arguments to it by reference. This is done using the ampersand symbol "&" before the argument name in the function description (see example No. 1).

Example No. 1. Passing function arguments by value and by reference

Default Function Argument Values

Also in PHP it is possible to use for function arguments default values, which represent the values ​​used if no value at all is passed to this argument when calling the function. In order to set the default argument value, you need to assign the desired value to this argument in the function definition (see example No. 2). In this case, default values ​​can have both arguments passed by value and arguments passed by reference. However, in any case, all arguments that are assigned default values ​​must appear in the list after the arguments that do not have default values. Additionally, only constant expressions, arrays, and NULL can be used as default values. You cannot use, for example, variables or function calls.

Example No. 2. Using default argument values

Variable length argument list

If the exact number of arguments passed to the function is not known in advance, you can use variable length argument list. Such a list is formed using a special variable preceded by an ellipsis "...". As a result, the arguments will be transferred to the specified variable in the form of an array (see example No. 3).

Example No. 3. Using a Variable Length Argument List

You can specify regular arguments before the ellipsis, but all other arguments passed to the function will be included in the array. Moreover, before the ellipsis, you can indicate the type of arguments that can be entered into the array, as well as the ampersand sign “&” for passing arguments by reference (see example No. 4).

"; //Outputs 10, because the value was passed to the function //by reference and then changed by the function to 10 echo $a_1; ?>

Example No. 4. Features of using a variable length argument list

It is allowed to use the ellipsis "..." to expand the array passed as a function argument into function arguments in the form of its elements (see example No. 5).

"; //Assign the array to the variable $a_3=; //Expand the array passed to the function //Output 3 echo m_sum_2(...$a_3); ?>

Example No. 5. Expanding the array of arguments passed to a function when called

Functions for accessing arguments

  • func_get_args()- returns an array consisting of function arguments;
  • func_get_arg(n)- returns the specified function argument, where n=0,1,2,... is the number of the argument in the list, which starts from zero (remember that the arguments are calculated from left to right);
  • func_num_args()- returns the number of arguments actually passed to the function.

"; //Will display the value of the third argument passed to the function echo func_get_arg(2); //Return the sum of the function arguments return $sum; ) //Called the function. Print 38, i.e. the number of arguments passed is 3, //and the value The 3rd argument is equal to 8 (numbering of elements starts from zero) m_sum(1,2,8);

Example No. 6. Using special functions to work with arguments

Note that function arguments can also be accessed using special functions, especially if the function takes more arguments than it expects to receive (see example #6):

Quickly navigate to other pages

Http://site Copyright © Petr Romanovsky, Minsk, 2016-2019.

Parameters are specified in the function definition, inside parentheses, and are its local variables, i.e. they are visible only in her body; if there are several parameters, then they are indicated separated by commas. When called, a function can receive arguments that are used to initialize parameters.

We have looked at what parameters are, now we will learn about what values ​​they are initialized with. The values ​​that will be assigned to parameters are called arguments - this could be, for example, a string or integer literal, a variable, or some more complex expression consisting of variables and operators, but which can be evaluated by the PHP interpreter to obtain the value with which the parameter will be initialized. Simply put, an argument is the value passed to a function:

Passing Arguments

PHP supports two ways of passing function arguments. The first is passing arguments by value (works by default), the second is passing arguments by reference. PHP also supports default values. Let's now look at all three options in more detail.

By default, arguments are passed to a function by value (this means that if you change the value of a parameter inside the function, the value passed outside it will remain the same):

$color color"; // The value of the variable has not changed?>

If you need to allow a function to modify the passed arguments outside of the function, you must pass them by reference. In order for an argument to be passed by reference, you must specify an & (ampersand) before the parameter name in the function definition:

Functions can define default argument values. To set a default value, in the function definition you just need to assign the parameter to the desired value:

\n"; ) echo tea(); // will print the default value echo tea("black"); ?>

Note: Any parameters that have default argument values ​​must be located to the right of arguments that do not have default values, otherwise your code may not work as expected:

Function return value

When a function completes, it can return some value (the result of the function) to the program that called it. The return statement inside functions is used to determine the value returned by the function. The return value can be any type. It has the following syntax:

Return expression;

The return statement can be located anywhere in the function. When control reaches it, the function returns a value (if specified) and completes its execution. If a return statement is not specified or a return value is not specified, then the function will return NULL . To use the return value, the result of the function execution can be assigned, for example, to a variable:

"; // => 16. function foo($num) ( if($num === 10) return "$num is 10"; else return "$num is not 10"; echo "hello"; // this line of code will never execute ) echo foo(6);

Passing Arguments to User-Defined Functions

When declaring a function, you can specify a list of parameters that can be passed to the function, for example:

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

When calling the funct() function, you must specify all the passed parameters, since they are required. In PHP, user-defined functions can have optional or default parameters, but more on that later.

According to established traditions, in all programming languages ​​there are two types of function arguments:

  • parameters-values;
  • parameters-variables.

Functions cannot change the value parameter, that is, it is read-only for the function - it can use it, but nothing more. It is not necessary to specify a variable as a value parameter; you can specify the value itself, hence the name - value parameter.

By default, arguments to a function are passed by value (this means that if you change the value of an argument inside the function, the value outside the function will still remain the same). Here's an example:

function funct ($string)
{
echo "

Parameter = $string

" ;
}

$str = 777 ;
function(777);
function( $str);

// The "funct" function will print the string "Parameter = 777" twice

?>

Unlike value parameters, variable parameters can be changed while the function is running. Here you can no longer pass a value; you must pass a variable. PHP uses the mechanism of passing a variable by reference to declare variable parameters.

If you want to allow a function to modify its arguments, you must pass them by reference.

If you want the argument to always be passed by reference, you must specify an ampersand (&) before the argument name in the function declaration:

function function (& $string )
{
$string .= "and this one is inside." ;
}
$str = "This line is outside the scope of the function,";
funct($str);
echo $str ; // Prints "This line is outside the function, and this line is inside."
?>

Default Settings

When programming, there is often a need to create a function with a variable number of parameters. There are two reasons for this:

  • There are too many parameters. There is no point in specifying all the parameters every time;
  • Functions must return values different types depending on the set of parameters.

IN PHP functions can return any values ​​depending on the parameters passed to them.

function makecup ($type = "Tea" )
{
return "Make a cup $type.\n";
}
echo makecup();
echo makecup("Coffee");
?>

The result of the above script will be like this:

Make a cup of tea
Make a cup of coffee

PHP also allows you to use arrays and the special type NULL as default values, for example:

function makecup ($types = array("Coffee"), $Maker = NULL )
{
$device = is_null ($Maker) ? "sugar" : $Maker ;
return "Make a cup". join(", ", $types). " with $device.\n" ;
}
echo makecup();
echo makecup (array("Coffee" , "Tea" ), "cream" );
?>

The script in question will output the following:

Make a cup of coffee with sugar. Make a cup of Coffee, Tea with cream.

The default value must be a constant expression.

Note that all arguments that have default values ​​must be located to the right of arguments that do not have default values, otherwise your code may not work as you expect. Consider the following example:

function makecup ($type = "tea" , $cond )
{
return ;
}

Echo makecup ("hot"); //Won't work as we might expect
?>

The output of the above script will be something like this:

Warning: Missing argument 2 for makecup() in c:\inetpub\site\test.php on line 2
Make a cup of hot food.

Now let’s modify the considered script, correcting the errors in it:

function makecup ($cond , $type = "tea")
{
return"Make a cup $type $cond.\n";
}

Echo makecup ("hot"); // Now our script works correctly!
?>

The result of the corrected script will look like this:

Make a cup of hot tea.

Attention! Since PHP 5, default values ​​can be passed by reference!

Variable number of arguments in functions

Sometimes we don't know exactly how many parameters will be passed to our function. Especially for this case, PHP developers have provided the ability to use a variable number of arguments.

The implementation of this feature is quite transparent and consists of using the functions func_num_args() , func_get_arg() And func_get_args() .

Let's consider the capabilities of the considered standard functions:

Standard function func_num_args() returns the number of arguments passed to the user function:

function function()
{
$numargums = func_num_args();
echo "Number of arguments: $numargums\n";
}

Funct(1, 2, 3); // The script will print "Number of arguments: 3"
?>

Standard function func_get_arg() returns an element from the list of arguments passed to the user function:

function function()
{
$numargs = func_num_args();
echo "Number of arguments: $numargs
\n"
;
if ($numargs >= 2 ) (
echo "Second argument: ". func_get_arg(1). "
\n" ;
}
}

Funct(1, 2, 3);
?>


Close