The following article will point out a few possible scenarios when writing PHP code in general, Laravel in particular. These may be basic logical errors, improper function usage; Or simply convention errors are not worth it.
1. Using try-catch
with incorrect catch
order
1 2 3 4 5 6 7 8 9 10 | <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span> <span class="token class-name"> Throwable</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">report</span> <span class="token punctuation">(</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span> <span class="token class-name">ValidationException</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reportValidationException</span> <span class="token punctuation">(</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span> <span class="token class-name"> Exception</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reportException</span> <span class="token punctuation">(</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Because Throwable is the parent class of Exception and ValidationException, in the above example, the exception to be thrown will be caught at the first catch and the two catch below will become meaningless.
When using try catch, pay attention to the order and paternity of the exception type.
The code above can be amended as follows:
1 2 3 4 5 6 7 8 9 10 | <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span> <span class="token class-name">ValidationException</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reportValidationException</span> <span class="token punctuation">(</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span> <span class="token class-name"> Exception</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reportException</span> <span class="token punctuation">(</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span> <span class="token class-name"> Throwable</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">report</span> <span class="token punctuation">(</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
2. Handling the same exception in the catch
statement
1 2 3 4 5 6 7 8 | <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span> <span class="token class-name">ValidationException</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">report</span> <span class="token punctuation">(</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span> <span class="token class-name"> Exception</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">report</span> <span class="token punctuation">(</span> <span class="token variable">$exception</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
In both cases catch
, have the same treatment as call to report()
. Then splitting into two catch
statements becomes unnecessary.
If you only want to catch
ValidationException, you should remove the catch
statement below.
If you want to catch all exceptions and handle them in the same catch
, you should remove the catch
statement above.
3. Use unnecessary if
syntax
1 2 3 4 5 6 | <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token variable">$a</span> <span class="token operator">==</span> <span class="token variable">$b</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">true</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Or maybe a little shorter.
1 2 | <span class="token keyword">return</span> <span class="token variable">$a</span> <span class="token operator">==</span> <span class="token variable">$b</span> <span class="token operator">?</span> <span class="token boolean">true</span> <span class="token punctuation">:</span> <span class="token boolean">false</span> <span class="token punctuation">;</span> |
The above two pieces of code are written incorrectly in logic but are quite redundant and lengthy. For simple comparative logic, consider shortening the following:
1 2 | <span class="token keyword">return</span> <span class="token variable">$a</span> <span class="token operator">==</span> <span class="token variable">$b</span> <span class="token punctuation">;</span> |
4. The variable declaration is only used once
1 2 3 4 5 6 | <span class="token keyword">function</span> <span class="token function">foo</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$a</span> <span class="token operator">=</span> <span class="token single-quoted-string string">'bar'</span> <span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token variable">$a</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Declaring the local variable $a
in this case is not necessary.
For operations that are not too long and complex, the following should be considered:
1 2 3 4 | <span class="token keyword">function</span> <span class="token function">foo</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token single-quoted-string string">'bar'</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
5. Use the array_splice()
function in the loop of the current array itself.
1 2 3 4 5 6 7 8 9 10 | <span class="token variable">$numbers</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">3</span> <span class="token punctuation">,</span> <span class="token number">4</span> <span class="token punctuation">,</span> <span class="token number">5</span> <span class="token punctuation">,</span> <span class="token number">6</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">foreach</span> <span class="token punctuation">(</span> <span class="token variable">$numbers</span> <span class="token keyword">as</span> <span class="token variable">$key</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token variable">$number</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token variable">$number</span> <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">!==</span> <span class="token number">0</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">array_splice</span> <span class="token punctuation">(</span> <span class="token variable">$numbers</span> <span class="token punctuation">,</span> <span class="token variable">$key</span> <span class="token punctuation">,</span> <span class="token number">1</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">var_dump</span> <span class="token punctuation">(</span> <span class="token variable">$numbers</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
The array_splice()
function is one of the solutions thought of in the problem of removing unwanted elements from an array.
In the above example, the array_splice()
function is used to remove odd numbers inside the $numbers
array.
The expected results when running the above code are:
1 2 | <span class="token variable">$numbers</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">4</span> <span class="token punctuation">,</span> <span class="token number">6</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> |
However, in reality, the result returned is
1 2 | <span class="token variable">$numbers</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">3</span> <span class="token punctuation">,</span> <span class="token number">5</span> <span class="token punctuation">,</span> <span class="token number">6</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> |
The reason is that the array_splice()
function changed the current array and caused an error when using the $key
index variable. The value of $key
no longer reflects the position of the element to be removed.
Can be verified by displaying data after each foreach
loop
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token variable">$numbers</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">3</span> <span class="token punctuation">,</span> <span class="token number">4</span> <span class="token punctuation">,</span> <span class="token number">5</span> <span class="token punctuation">,</span> <span class="token number">6</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">foreach</span> <span class="token punctuation">(</span> <span class="token variable">$numbers</span> <span class="token keyword">as</span> <span class="token variable">$key</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token variable">$number</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token variable">$number</span> <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">!==</span> <span class="token number">0</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">var_dump</span> <span class="token punctuation">(</span> <span class="token variable">$numbers</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">var_dump</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'Spliced number: '</span> <span class="token punctuation">.</span> <span class="token variable">$number</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">var_dump</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'Spliced postion: '</span> <span class="token punctuation">.</span> <span class="token variable">$key</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">array_splice</span> <span class="token punctuation">(</span> <span class="token variable">$numbers</span> <span class="token punctuation">,</span> <span class="token variable">$key</span> <span class="token punctuation">,</span> <span class="token number">1</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">var_dump</span> <span class="token punctuation">(</span> <span class="token variable">$numbers</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | array(6) { [0] => int(1) [1] => int(2) [2] => int(3) [3] => int(4) [4] => int(5) [5] => int(6) } string(17) "Spliced number: 1" string(18) "Spliced postion: 0" array(5) { [0] => int(2) [1] => int(3) [2] => int(4) [3] => int(5) [4] => int(6) } string(17) "Spliced number: 3" string(18) "Spliced postion: 2" array(4) { [0] => int(2) [1] => int(3) [2] => int(5) [3] => int(6) } string(17) "Spliced number: 5" string(18) "Spliced postion: 4" |
This is a fairly basic error but is sometimes overlooked, resulting in unforeseen results.
With the above example problem, there are many different solutions. Two of many ways to consider:
Use the for
loop and reduce the value of the pointer variable at the time of “splice”
1 2 3 4 5 6 7 8 9 | <span class="token variable">$numbers</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">3</span> <span class="token punctuation">,</span> <span class="token number">4</span> <span class="token punctuation">,</span> <span class="token number">5</span> <span class="token punctuation">,</span> <span class="token number">6</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span> <span class="token variable">$i</span> <span class="token operator">=</span> <span class="token number">0</span> <span class="token punctuation">;</span> <span class="token variable">$i</span> <span class="token operator"><</span> <span class="token function">count</span> <span class="token punctuation">(</span> <span class="token variable">$numbers</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$i</span> <span class="token operator">++</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token variable">$numbers</span> <span class="token punctuation">[</span> <span class="token variable">$i</span> <span class="token punctuation">]</span> <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">!==</span> <span class="token number">0</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">array_splice</span> <span class="token punctuation">(</span> <span class="token variable">$numbers</span> <span class="token punctuation">,</span> <span class="token variable">$i</span> <span class="token punctuation">,</span> <span class="token number">1</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$i</span> <span class="token operator">--</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Using the array_filter()
function
1 2 3 | <span class="token variable">$numbers</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">3</span> <span class="token punctuation">,</span> <span class="token number">4</span> <span class="token punctuation">,</span> <span class="token number">5</span> <span class="token punctuation">,</span> <span class="token number">6</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token variable">$evenNumbers</span> <span class="token operator">=</span> <span class="token function">array_filter</span> <span class="token punctuation">(</span> <span class="token variable">$numbers</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token variable">$number</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$number</span> <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
6. Assign values containing space characters to Laravel’s environment variables
1 2 | APP_NAME=My App |
The variables in the dotenv file (of Laravel) do not support values with an escaped whitespace character. Therefore, in the above example, the error will be dumped with the following content (Laravel 5.8):
1 2 3 | The environment file is invalid <span class="token operator">!</span> Failed to parse dotenv file due to unexpected whitespace <span class="token punctuation">.</span> Failed at <span class="token punctuation">[</span> My App <span class="token punctuation">]</span> <span class="token punctuation">.</span> |
Therefore, always remember to escape the values of environment variables in Laravel.
1 2 | <span class="token constant">APP_NAME</span> <span class="token operator">=</span> <span class="token double-quoted-string string">"My App"</span> |
7. Pass null
values into the function using type-hint
1 2 3 4 5 6 | <span class="token keyword">function</span> <span class="token function">foo</span> <span class="token punctuation">(</span> int <span class="token variable">$a</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$a</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token variable">$b</span> <span class="token operator">=</span> <span class="token function">foo</span> <span class="token punctuation">(</span> <span class="token keyword">null</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
The above code generates an error (PHP Fatal error) when there is a difference in the data type between the argument and function arguments.
The above problem can be solved by either of the following two options:
Use nullable type (From PHP 7.1 and above)
1 2 3 4 | <span class="token keyword">function</span> <span class="token function">foo</span> <span class="token punctuation">(</span> <span class="token operator">?</span> int <span class="token variable">$a</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$a</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Assigning default values by null to function arguments
1 2 3 4 | <span class="token keyword">function</span> <span class="token function">foo</span> <span class="token punctuation">(</span> int <span class="token variable">$a</span> <span class="token operator">=</span> <span class="token keyword">null</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$a</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
8. Use loose comparisons ( ==
,! !=
) On the strpos()
function
1 2 3 4 | <span class="token keyword">function</span> <span class="token function">doesContain</span> <span class="token punctuation">(</span> <span class="token variable">$str</span> <span class="token punctuation">,</span> <span class="token variable">$char</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">strpos</span> <span class="token punctuation">(</span> <span class="token variable">$str</span> <span class="token punctuation">,</span> <span class="token variable">$char</span> <span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token boolean">false</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
The strpos()
function is often used to determine whether a substring is in a given string or not by the position of the substring. If substring is not found, strpos()
returns false
.
For the above example, the function doesContain()
will return true
if string $str
contains the character string $char
.
1 2 3 | var_dump(doesContain('Hello world!', 'l')); bool(true) |
However, when testing the letter H
or the Hello
character string, the result is false
1 2 3 4 5 6 | <span class="token function">var_dump</span> <span class="token punctuation">(</span> <span class="token function">doesContain</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'Hello world!'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'H'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">bool</span> <span class="token punctuation">(</span> <span class="token boolean">false</span> <span class="token punctuation">)</span> <span class="token function">var_dump</span> <span class="token punctuation">(</span> <span class="token function">doesContain</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'Hello world!'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'Hello'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">bool</span> <span class="token punctuation">(</span> <span class="token boolean">false</span> <span class="token punctuation">)</span> |
The reason is that the first character / string (substring) in the first position will have an offset value of 0. Therefore, when comparing !=
With false
values, the result will be false
.
Therefore, strict comparisons ( ===
,! !===
) should be used when using the strpos()
function strpos()
1 2 3 4 | <span class="token keyword">function</span> <span class="token function">doesContain</span> <span class="token punctuation">(</span> <span class="token variable">$str</span> <span class="token punctuation">,</span> <span class="token variable">$char</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">strpos</span> <span class="token punctuation">(</span> <span class="token variable">$str</span> <span class="token punctuation">,</span> <span class="token variable">$char</span> <span class="token punctuation">)</span> <span class="token operator">!==</span> <span class="token boolean">false</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
9. Optional parameters are preceded by mandatory parameters
1 2 | <span class="token keyword">function</span> <span class="token function">foo</span> <span class="token punctuation">(</span> <span class="token variable">$a</span> <span class="token operator">=</span> <span class="token keyword">null</span> <span class="token punctuation">,</span> <span class="token variable">$b</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">}</span> |
The method declaration of the above function is valid but not valid.
When we want to call the foo()
function with the value of the parameter $a
equal to null
, we will have to pass the value to both parameters. Although the first parameter has default values.
1 2 3 | <span class="token keyword">function</span> <span class="token function">foo</span> <span class="token punctuation">(</span> <span class="token variable">$a</span> <span class="token operator">=</span> <span class="token keyword">null</span> <span class="token punctuation">,</span> <span class="token variable">$b</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">}</span> <span class="token function">foo</span> <span class="token punctuation">(</span> <span class="token keyword">null</span> <span class="token punctuation">,</span> <span class="token variable">$c</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Therefore, always sort the last optional parameters after the function definition.
1 2 3 | <span class="token keyword">function</span> <span class="token function">foo</span> <span class="token punctuation">(</span> <span class="token variable">$b</span> <span class="token punctuation">,</span> <span class="token variable">$a</span> <span class="token operator">=</span> <span class="token keyword">null</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">}</span> <span class="token function">foo</span> <span class="token punctuation">(</span> <span class="token variable">$c</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |