PHP is a great web development language and flexible language, but we can see some mistakes made by php programmers. I made the following list to list the 10 errors that PHP programmers often make, most of which are related to security.
PHP is a great web development language and flexible language, but we can see some mistakes made by php programmers. I made the following list to list the 10 errors that PHP programmers often make, most of which are related to security.
At present, many of my friends are studying PHP and will always encounter various problems in daily program development projects. This article will introduce you to the 10 most common problems in PHP development, hope to help your friends.
Error 1: the pointer is left after the foreach loop.
In a foreach loop, if we need to change the iteration elements or use references to improve efficiency, it is a good solution:
$ Arr = array (1, 2, 3, 4); foreach ($ arr as & $ value) {$ value = $ value * 2 ;} // $ arr is now array (2, 4, 6, 8)
There is a problem that many people will be confused. After the loop ends, the value is not destroyed, and the value is actually a reference to the last element in the array. In this way, if you do not know this in future use of $ value, will cause some inexplicable errors :) look at the following code:
$ Array = [1, 2, 3]; echo implode (',', $ array), "\ n"; foreach ($ array as & $ value) {}// by reference echo implode (',', $ array), "\ n"; foreach ($ array as $ value) {}// by value (I. e ., copy) echo implode (',', $ array), "\ n ";
The running result of the above Code is as follows:
1, 2, 3 1, 2
You guessed it? Why is this result?
Let's analyze it. After the first loop, $ value is the reference of the last element in the array. The second cycle begins:
Step 1: Copy arr [0] to value (note that the value is a reference of arr [2]), and then the array is changed to [1, 2, 1].
Step 2: Copy arr [1] to value. Then, the array is changed to [1, 2].
Step 3: Copy arr [2] to value. Then, the array is changed to [1, 2].
In conclusion, the final result is, 2.
The best way to avoid this error is to use the unset function to destroy the variable immediately after the loop:
$ Arr = array (1, 2, 3, 4); foreach ($ arr as & $ value) {$ value = $ value * 2;} unset ($ value ); // $ value no longer references $ arr [3]
Error 2: incorrect understanding of isset () function Behavior
For the isset () function, if the variable does not exist, false is returned. If the variable value is null, false is returned. This kind of behavior can easily confuse people... See the following code:
$ Data = fetchRecordFromStorage ($ storage, $ identifier); if (! Isset ($ data ['keyshouldbeset']) {// do something here if 'keyshouldbeset' is not set}
The human intention of writing this Code may be that if data ['keyshouldbeset'] is not set, the corresponding logic is executed. But the problem is that even if data ['keyshouldbeset'] has been set, but the set value is null, the corresponding logic will still be executed, which is not in line with the Code's intention.
The following is another example:
If ($ _ POST ['active']) {$ postData = extractSomething ($ _ POST);} //... if (! Isset ($ postData) {echo 'Post not active ';}
The above Code assumes that POST ['active'] is true, then postData should be set, so isset (postData) returns true. Otherwise, the code above assumes that the only way for isset (postData) to return false is that $ _ POST ['active'] also returns false.
Is that true? Of course not!
Even if POST ['active'] returns true, postData may be set to null. In this case, isset ($ postData) returns false. This does not conform to the Code's intention.
If the above Code is only intended to check whether $ _ POST ['active'] is true, the following implementation will be better:
If ($ _ POST ['active']) {$ postData = extractSomething ($ _ POST );}//... if ($ _ POST ['active']) {echo 'Post not active ';}
The array_key_exists () function may be better at determining whether a variable is actually set (distinguish unset and set to null. The first example of refactoring is as follows:
$ Data = fetchRecordFromStorage ($ storage, $ identifier); if (! Array_key_exists ('keyshouldbeset', $ data) {// do this if 'keyshouldbeset' isn' t set}
In addition, combined with the get_defined_vars () function, we can more reliably check whether variables are set in the current scope:
If (array_key_exists ('varshouldbeset', get_defined_vars () {// variable $ varShouldBeSet exists in current scope}
Error 3: Mixed return values and return references
Consider the following code:
Class Config {private $ values = []; public function getValues () {return $ this-> values ;}$ config = new Config (); $ config-> getValues () ['test'] = 'test'; echo $ config-> getValues () ['test'];
Running the above Code will output the following content:
PHP Notice: Undefined index: test in/path/to/my/script. php on line 21
What is the problem? The problem is that the above Code obfuscated the return value and return reference. In PHP, unless you specify the returned reference, PHP returns a value for the array, that is, copying the array. Therefore, the code above assigns a value to the returned array, which is to assign a value to the copy array instead of the original array.
// GetValues () returns a COPY of the $ values array, so this adds a 'test' element // to a COPY of the $ values array, but not to the $ values array itself. $ config-> getValues () ['test'] = 'test'; // getValues () again returns another copy of the $ values array, and THIS copy doesn't // contain a 'test' element (which is why we get the "undefined index" message ). echo $ config-> getValues () ['test'];
The following is a possible solution: output the copied array instead of the original array:
$ Vals = $ config-> getValues (); $ vals ['test'] = 'test'; echo $ vals ['test'];
If you want to change the original array, that is, to reverse the array reference, what should you do? You can simply display the specified return reference:
Class Config {private $ values = []; // return a REFERENCE to the actual $ values arraypublic function & getValues () {return $ this-> values ;}} $ config = new Config (); $ config-> getValues () ['test'] = 'test'; echo $ config-> getValues () ['test'];
After the transformation, the above Code will output test as expected.
Let's look at an example that will make you more confused:
Class Config {private $ values; // using ArrayObject rather than arraypublic function _ construct () {$ this-> values = new ArrayObject ();} public function getValues () {return $ this-> values; }}$ config = new Config (); $ config-> getValues () ['test'] = 'test '; echo $ config-> getValues () ['test'];
If you want to output the "Undefined index" error like above, you will be wrong. The code will output "test" normally ". The reason is that PHP returns objects by reference by default, rather than by value.
To sum up, when using the function return value, we need to find out whether the value is returned or the reference is returned. In PHP, objects are returned by reference by default, and arrays and built-in basic types are returned by value by default. This should be different from other languages (many languages use references for arrays ).
Like other languages, such as java or C #, using getter or setter to access or set class attributes is a better solution. Of course, PHP does not support this by default and needs to be implemented by itself: