Menu
Is free
registration
home  /  Firmware/ Check existence of php variable. Checking for the existence of a variable

Check existence of php variable. Checking for the existence of a variable

The material is intended mainly for beginner web programmers.

Introduction.

I am often approached by clients who have self-written CMS installed or modules written by novice web programmers who do not understand what is needed to protect data and often copy filtering functions without thinking about how they work and what exactly needs to be done with them.

Here I will try to describe in as much detail as possible common errors when filtering data in PHP script and give simple tips how to properly filter the data.

There are many articles on the Internet about filtering data, but they are not complete and without detailed examples.

Debriefing.

Filtration. Mistake # 1
For numeric variables, the following check is used:
$ number = $ _GET ["input_number"]; if (intval ($ number)) (... execute SQL query ...)
Why will it lead to SQL injection? The point is that the user can specify in the variable input_number meaning:
1 "+ UNION + SELECT
In this case, the check will be passed successfully. the intval function gets the integer value of the variable, i.e. 1, but in the variable itself $ number nothing has changed, so the whole malicious code will be passed to the SQL query.
Correct filtering:
$ number = intval ($ _ GET ["input_number"]); if ($ number) (... execute SQL query ...)
Of course, the condition can change, for example if you only need to get a certain range:
if ($ number> = 32 AND $ number<= 65)

If you are using checkboxes or multi-selects with numeric values, check this:
$ checkbox_arr = array_map ("intval", $ _POST ["checkbox"]);
array_map
I also meet filtering in the form:
$ number = htmlspecialchars (intval ($ _ GET ["input_number"]));
htmlspecialchars
Or:
$ number = mysql_escape_string (intval ($ _ GET ["input_number"]));
mysql_escape_string

It can cause nothing but a smile :)

Filtration. Mistake # 2.
For string variables, the following filtering is used:
$ input_text = addslashes ($ _ GET ["input_text"]);
The addslashes function escapes specials. characters, but it does not take into account the database encoding and filtering can be bypassed. I will not copy the text of the author who described this vulnerability and just give a link to Chris Shiflett (the translation can be found on the Russian Internet).

Use mysql_escape_string or mysql_real_escape_string function, example:
$ input_text = mysql_escape_string ($ _ GET ["input_text"]);
If you do not intend to enter html tags, then it is best to do the following filtering:
$ input_text = strip_tags ($ _ GET ["input_text"]); $ input_text = htmlspecialchars ($ input_text); $ input_text = mysql_escape_string ($ input_text);
strip_tags - strip html tags.
htmlspecialchars - converts special. characters in the html entity.
This way you protect yourself from XSS attacks other than SQL injection.
If you need html tags, but only as for displaying the source code, then it is enough to use:
$ input_text = htmlspecialchars ($ _ GET ["input_text"]); $ input_text = mysql_escape_string ($ input_text);

If it is important for you that the value of the variable is not empty, then use the trim function, for example:
$ input_text = trim ($ _ GET ["input_text"]); $ input_text = htmlspecialchars ($ input_text); $ input_text = mysql_escape_string ($ input_text);

Filtration. Mistake number 3.
It concerns database search.
To search by numbers, use the filtering described in the first error.
To search by text, use the filtering described in the second error, but with caveats.
In order for the user to be unable to perform a logical error, it is necessary to delete or screen the special. SQL symbols.
Example without add. line processing:
$ input_text = htmlspecialchars ($ _ GET ["input_text"]); // Search: "%" $ input_text = mysql_escape_string ($ input_text);
At the output, we get a request of the form:
... WHERE text_row LIKE "%". $ Input_text. "%" ... // WHERE text_row LIKE "%%%"
This will significantly increase the load on the base.
In my script, I use a function that removes unwanted characters from the search:
function strip_data ($ text) ($ quotes = array ("\ x27", "\ x22", "\ x60", "\ t", "\ n", "\ r", "*", "%", "<", ">","? ","! "); $ goodquotes = array (" - "," + "," # "); $ repquotes = array (" \ - "," \ + "," \ # "); $ text = trim (strip_tags ($ text)); $ text = str_replace ($ quotes, "", $ text); $ text = str_replace ($ goodquotes, $ repquotes, $ text); $ text = ereg_replace ("+" , "", $ text); return $ text;)
Of course, not all of the above characters are dangerous, but in my case they are not needed, so I search and replace.
An example of using filtering:
$ input_text = strip_data ($ _ GET ["input_text"]); $ input_text = htmlspecialchars ($ input_text); $ input_text = mysql_escape_string ($ input_text);
I also advise you to limit the number of characters in the search, at least not less than 3, because if you have a large number of records in the database, then a search by 1-2 characters will significantly increase the load on the database.
Filtration. Mistake # 4.
Values ​​in a variable are not filtered $ _COOKIE... Some people think that since this variable cannot be passed through the form, then this is a guarantee of security.
This variable is very easy to spoof by any browser by editing the site's cookies.
For example, in one well-known CMS there was a check of the used site template:
if (@is_dir (MAIN_DIR. "/ template /". $ _COOKIE ["skin"])) ($ config ["skin"] = $ _COOKIE ["skin"];) $ tpl-> dir = MAIN_DIR. "/ template /". $ config ["skin"];
In this case, you can substitute the value of the variable $ _COOKIE ["skin"] and cause an error, as a result of which you will see the absolute path to the site folder.
If you use the value of cookies to save to the database, then use one of the above described filters, this also applies to the variable $ _SERVER.
Filtration. Mistake # 5.
Included directive register_globals... Be sure to turn it off if it's on.
In some situations, you can pass the value of a variable that should not have been passed, for example, if there are groups on the site, then the $ group variable should be empty or equal to 0 for group 2, but it is enough to fake the form by adding the code:

In the PHP script, the variable $ group will be equal to 5 if it was not declared with a default value in the script.
Filtration. Mistake # 6.
Check your downloads.
Check the following points:
  1. File extension. It is desirable to prohibit downloading files with extensions: php, php3, php4, php5, etc.
  2. Is the file uploaded to the server move_uploaded_file
  3. file size
Examination. Mistake # 1.
I came across cases when for an AJAX request (for example: increasing the reputation) the username or his ID was passed (to whom the reputation is increased), but in PHP itself there was no check for the existence of such a user.
For example:
$ user_id = intval ($ _ REQUEST ["user_id"]); ... INSERT INTO REPLOG SET uid = "($ user_id)", plus = "1" ... ... UPDATE Users SET reputation = reputation + 1 WHERE user_id = "($ user_id)" ...
It turns out that we create a record in the database, which is completely useless to us.
Examination. Mistake # 2.
When performing various kinds of actions (adding, editing, deleting) with data, do not forget to check the user's rights to access this function and additional features(using html tags or the ability to publish material without verification).

For a long time I fixed a similar error in one module of the forum, when any user could edit an administration message.

Examination. Mistake number 3.
When using multiple php files do a simple check.
In file index.php(or in any other main file) write this line before including other php files:
define ("READFILE", true);
At the beginning of other php files, write:
if (! defined ("READFILE")) (exit ("Error, wrong way to file.
Go to main."); }
This will restrict access to files.
Examination. Mistake # 4.
Use hashes for users. This will help prevent XSS from calling a particular function.
An example of generating a hash for users:
$ secret_key = md5 (strtolower ("http://site.ru/". $ member ["name"]. sha1 ($ password). date ("Ymd"))); // $ secret_key is our hash
Next, in all important forms, substitute an input with the value of the current user hash:

During script execution, check:
if ($ _POST ["secret_key"]! == $ secret_key) (exit ("Error: secret_key!");)
Examination. Mistake # 5.
When displaying SQL errors, make a simple restriction on information access. For example, set a password for a GET variable:
if ($ _GET ["passsql"] == "password") (... SQL error output ...) else (... Just error information, no details ...)
This will hide information from the hacker that can help him in hacking the site.
Examination. Mistake # 5.
Try not to include files by getting filenames externally.
For example:
if (isset ($ _ GET ["file_name"])) (include $ _GET ["file_name"]. ". php";)
Use the switch

I want to check if a variable exists. Now I am doing something like this:

Try: myVar except NameError: # Do something.

Are there other ways without exceptions?


2018-05-09 13:10

Answers:

To check for the presence of a local variable:

If "myVar" in locals (): # myVar exists.

To check for the existence of a global variable:

If "myVar" in globals (): # myVar exists.

To check if an object has an attribute:

If hasattr (obj, "attr_name"): # obj.attr_name exists.


2018-05-09 13:16

Using variables that have not been defined or set (implicitly or explicitly) is almost always bad Any as this indicates that the program logic was not thought out properly and is likely to lead to unpredictable behavior.

The next trick, which is similar to yours, will ensure that the variable has some value before use:

Try: myVar except NameError: myVar = None # Now you "re free to use myVar without Python complaining.

However, I still don't think this is a good idea - in my opinion, you should refactor your code to avoid this situation.


2018-05-09 13:19

Using try / except - The best way check the existence of a variable. But there is almost certainly a better way to do what you are doing than setting / testing globals.

For example, if you want to initialize a module-level variable the first time you call some function, you'd better do something like this with code:

My_variable = None def InitMyVariable (): global my_variable if my_variable is None: my_variable = ...


2018-05-09 13:27

for objects / modules, you can also

"var" in dir (obj)

For example,

>>> class Something (object): ... pass ... >>> c = Something () >>> ca = 1 >>> "a" in dir (c) True >>> "b" in dir (c) False


2017-10-28 18:39

The easy way is to initialize it first myVar = None

Then later:

If myVar is not None: # Do something


2018-06-04 18:46

My guess is that the test will be used in a function similar to user97370's answer.I don't like this answer because it pollutes the global namespace. One way to fix this is to use a class instead:

Class InitMyVariable (object): my_variable = None def __call __ (self): if self.my_variable is None: self.my_variable = ...

I don't like this because it complicates the code and opens up questions like if this would validate the Singleton programming pattern? Fortunately, Python has allowed functions to have attributes for a while, which gives us this simple solution:

Def InitMyVariable (): if InitMyVariable.my_variable is None: InitMyVariable.my_variable = ... InitMyVariable.my_variable = None


2018-03-25 20:31

2018-05-09 13:12

A way that often works well for handling this kind of situation is to not explicitly check if the variable exists but just go ahead and wrap the first usage of the possibly non-existing variable in a try / except NameError.

null function (11)

I have (or not) a $ _GET ["myvar"] variable coming from my query string and I want to check if this variable exists and also if the value matches something inside my if statement:

What I am doing and think is not the best way to do:

if (isset ($ _ GET ["myvar"]) && $ _GET ["myvar"] == "something"): do something

This is a simple case, but imagine you want to compare many of these $ myvar variables.

Answers

This is similar to the accepted answer, but uses in_array instead. I prefer to use empty () in this situation. I also suggest using the new string array declaration that is available in PHP 5.4.0+.

$ allowed = ["something", "nothing"]; if (! empty ($ _ GET ["myvar"]) && in_array ($ _ GET ["myvar"], $ allowed)) (..)

Here is a function to test multiple values ​​at once.

$ arrKeys = array_keys ($ _ GET); $ allowed = ["something", "nothing"]; function checkGet ($ arrKeys, $ allowed) (foreach ($ arrKeys as $ key) (if (in_array ($ _ GET [$ key], $ allowed)) ($ values ​​[$ key];)) return $ values;)

I use all my own useful function exst (), which automatically declares variables.

$ element1 = exst ($ arr ["key1"]); $ val2 = exst ($ _ POST ["key2"], "novalue"); / ** * Function exst () - Checks if the variable has been set * (copy / paste it in any place of your code) * * If the variable is set and not empty returns the variable (no transformation) * If the variable is not set or empty, returns the $ default value * * @param mixed $ var * @param mixed $ default * * @return mixed * / function exst (& $ var, $ default = "") ($ t = "" ; if (! isset ($ var) ||! $ var) (if (isset ($ default) && $ default! = "") $ t = $ default;) else ($ t = $ var;) if (is_string ($ t)) $ t = trim ($ t); return $ t;)

Well, you can get by with just if ($ _ GET ["myvar"] == "something") as this condition assumes that the variable also exists. If it is not, the expression will also evaluate to false.

I think it's okay to do it in conditionals like above. No harm actually.

My question is, is there a way to do this without declaring the variable twice?

No, there is no way to do it right without doing two checks. I hate it too.

One way to get around this is to import all the relevant GET variables at one central point into an array or object of a specific type (most MVC do this automatically) and set any properties that are needed later. (Instead of accessing the request variables through code.)

If (isset ($ _ GET ["myvar"]) == "something")

Thanks to Mellowsoon and Pekka, I did some research here and came up with this:

  • Check and declare each variable as null (if so) before using it (as recommended):
! isset ($ _ GET ["myvar"])? $ _GET ["myvar"] = 0: 0;

* ok this is simple but works great, you can start using the variable everywhere after this line

  • Using an array for all cases:
$ myvars = array ("var1", "var2", "var3"); foreach ($ myvars as $ key)! isset ($ _ GET [$ key])? $ _GET [$ key] = 0: 0;

* after that you can use your variables (var1, var2, var3 ... etc.),

PS: a function getting a JSON object should be better (or a simple delimited string for bang / bang);

Better approaches are appreciated :)

UPDATE:

Use $ _REQUEST instead of $ _GET, this way you cover the $ _GET and $ _POST variables.

Isset ($ _ REQUEST [$ key])? $ _REQUEST [$ key] = 0: 0;

The solution I found from the game is to do this:

If ($ x = & $ _ GET ["myvar"] == "something") (// do stuff with $ x)

As a hint, you might consider this approach:

Required = array ("myvar" => "defaultValue1", "foo" => "value2", "bar" => "value3", "baz" => "value4"); $ missing = array_diff ($ required, array_keys ($ _ GET)); foreach ($ missing as $ key => $ default) ($ _GET [$ key] = $ default;)

You set the defaults and set the non-received parameters to the default :)

Unfortunately, this is the only way to do it. But there are approaches to working with large arrays. For example, something like this:

$ required = array ("myvar", "foo", "bar", "baz"); $ missing = array_diff ($ required, array_keys ($ _ GET));

The $ missing variable now contains a list of values ​​that are required but are missing from the $ _GET array. You can use $ missing array to display the message to the visitor.

Or you can use something like this:

$ required = array ("myvar", "foo", "bar", "baz"); $ missing = array_diff ($ required, array_keys ($ _ GET)); foreach ($ missing as $ m) ($ _GET [$ m] = null;)

Now every required element has a default value. Now you can use if ($ _ GET ["myvar"] == "something") without worrying about the key not being set.

Refresh

Another way to clean up the code would be to use a function that checks if a value has been set.

Function getValue ($ key) (if (! Isset ($ _ GET [$ key])) (return false;) return $ _GET [$ key];) if (getValue ("myvar") == "something") (/ / Do something)

why not create a function to do this, convert the variable you want to check into a real variable eg.

Function _FX ($ name) (if (isset ($$ name)) return $$ name; else return null;)

then you do _FX ("param") == "123", just a thought

I found (much) better code to do this if you want to check anything in.

If [[$ 1 = ""]] then echo "$ 1 is blank" else echo "$ 1 is filled up" fi

Why is all this? Everything in exists in Bash, but it is empty by default, so test -z and test -n cannot help you.

If [$ (# 1) = 0] then echo "$ 1 is blank" else echo "$ 1 is filled up" fi

You can check if a given variable exists (that is, it is initialized or it). To do this, use the function:

Isset (variable);

If the variable in this moment does not exist (has not been assigned a value anywhere before or has been removed by a function unset () ), then the function isset () returns false , otherwise - true :

$ x = 5;

if (isset ($ x))

echo ‘< BR > Variable $ x exists, ‘,“ its value is $ x < BR >”;

The screen will display:

Variable $ x exists, its value is 5

It is important to remember that we cannot use an uninitialized variable in the program - this will generate a warning from the interpreter. PHP .

To find out if a value is a variable empty , the function is used:

empty ( variable);

If the value of the variable is zero ,“0”, NULL , empty line (“” ), false, the variable is not declared or is an empty array then this function returns true , otherwise - false .

To check type of variable, the functions are used:

Is_string (variable);

is _ int (variable);

is _ float (variable);

is _ null (variable);

is _ array (variable);

is _ numeric (variable); - if the variable is numeric ( integer , float ) or a string containing only numbers.

These functions return true if the variable is of the specified type.

Data output

Formatless output

Formatless the output of strings or values ​​of variables is carried out by the function:

echo list of variables;

echo line;

where variable list - the names of the output variables, separated by commas.

If we work with a web browser, then this function directs the output to the client side of the browser (to its window).

As already said, if in a line enclosed in double quotes, variable names are encountered, the corresponding values ​​are displayed instead of these names. Moreover, if such a string contains tags Html (handles enclosed in angle brackets), then the browser displays this Html -code the way it should do it when interpreted Html -document:

$ year = 2012;

$ message = “ Wish to all happiness !”;

echo “

My congratulations !

”;

echo “ Has come $ year year !
$ message
”;

?>

The heading of the level will be displayed. H 3 and a subsequent greeting, with the word “ happiness!" will be displayed in bold italic:

My congratulations!

2012 has come! I wish everyone happiness!

This is how you can create dynamic sites.

Formatted output

Formatted the output allows you to represent the outputted numbers in different number systems, and in the decimal system - in different forms ( formats ). It is similar to formatted output in Si and is carried out by the functions:

printf (“Format”, output list);

sprintf (“Format”, output list);

The first function outputs formatted data to the browser window and returns its amount.

The second function only formats the output data, but does not output it.

Format Is a sequence of conversion descriptors for output values.

Transform Descriptor for each value has the form:

% Filler Align Length Accuracy Type

- Aggregate - this is the character that will be used to complete the conversion result to the specified length (default - space ); if it is another character, then it is preceded by a single quote ( apostrophe ),

- Alignment - by default - by right the edge of the output field; if there is a minus ( - ), then by left ,

- Length - width of the output field - the number of character spaces allocated for the output of this value. If the displayed value contains less familiarity than the given one length then the remaining space will be filled spaces or filling characters,

- Accuracy - the number of decimal places in the fractional part of the number,

- Type of - type of output value:

b binary ,

with symbol ,

d whole in decimal notation,

e material in exponential form (floating point),

f material in fixed point form,

s line ,

O whole in octal number system,

x whole in hexadecimal notation.

Example:

php

$ zarp _1 = 6543.21;

$ zarp _2 = 45321.67;

$ fam _1 = "Balaganov";

$ fam _2 = "Bender";

printf ("< H 1> Payroll h 1>");

printf ("%" .- 12s% ". 10.2f rub.", $ fam_1, $ zarp_1);

echo "
";

printf ("%" .- 12s% ". 10.2f rub.", $ fam_2, $ zarp_2);

echo "
";

?>

The point was chosen as a placeholder ( ‘. ). Surnames are left aligned ( - ) in a field of width 12 characters. Numbers are represented in fixed point form in a field width 10 characters and with precision 2 decimal places, right justified.