DEV Community

loading...
Cover image for Common PHP mistakes and solutions

Common PHP mistakes and solutions

jmau111 profile image Julien Maury Originally published at blog.julien-maury.dev ・3 min read

PHP is such a flexible and powerful language. However, it's easy to make mistakes, especially if you're a beginner.

Parse errors

Are you tired of getting parse errors?

For example:

Parse error: syntax error, unexpected ','

Use modern editors such as VS code. You'll find useful plugins to easily install a syntax highlighter. Stupid typos will be highlighted in red, making your life easier.

Don't waste your time spotting typos.

Do you sleep at night?

There may be many forms of this one, but here is a classic oversight:

if (defined("MY_CONST")) {
    define("MY_CONST");
}
Enter fullscreen mode Exit fullscreen mode

If you look at this carefully, you'll see it misses an essential element. Maybe you can handle it after a well-deserved sleep, or at least after a short break.

The correct version is:

if (!defined("MY_CONST")) {
    define("MY_CONST");
}
Enter fullscreen mode Exit fullscreen mode

You want to define the constant only if it's not defined before.

Don't be so negative!

function isNotEligible(int $age, int $score, string $team): bool {
    return $age < 18 || $score < 9999 || $team === "admin"; 
}
Enter fullscreen mode Exit fullscreen mode

The above function works, but it's not good practice to use this "negative" approach, as it's less readable and thus, harder to use.

For example, to check if someone is eligible:

if (!isNotEligible()) {}
Enter fullscreen mode Exit fullscreen mode

It overcomplicated and it does not feel right. Instead, write:

function isEligible(int $age, int $score, string $team): bool {
    return $age >= 18 && $score >= 9999 && $team !== "admin"; 
}
Enter fullscreen mode Exit fullscreen mode

and use it like that:

if (isEligible()) {
    // some code
} 
Enter fullscreen mode Exit fullscreen mode

or:

if (!isEligible()) {
    // some code
}
Enter fullscreen mode Exit fullscreen mode

There's no escape!

echo $_GET['s'];// "s" would be a search keyword
Enter fullscreen mode Exit fullscreen mode

Not escaping GET params is always wrong. Full stop.

A quick and dirty fix would be:

if (isset($_GET['s'])) {
    echo htmlentities($_GET['s'], ENT_QUOTES, 'UTF-8');
}
Enter fullscreen mode Exit fullscreen mode

Does it exist?

This one is a classic misunderstanding.

Developers often use method_exists() like that:

$directory = new Directory('.');
var_dump(method_exists($directory,'read'));
Enter fullscreen mode Exit fullscreen mode

Source: PHP documentation, method_exists()

In the above example, the method exists and you can use it.

What if the method is protected or private? If you aren't in the scope (respectively not in a child class or not in the class itself), you get a fatal error, even if method_exists() returns true.

You'd better use is_callable() to check if you really can call and use the method in your context:

$myClass = new MyClass();
var_dump(is_callable([$myClass, 'myMethod']);
Enter fullscreen mode Exit fullscreen mode

You must know the difference to use the appropriate function in your conditions.

The anonymous stdClass

PHP provides a built-in empty class called stdClass. It creates an anonymous object.

Don't be confused if you come from another programming language. It's not like JavaScript or Ruby. You don't have a mother class at the top of the chain and all objects extending it.

You can consider stdClass as an alternative to associative arrays. To use it, you don't have to formally define a new class, you can directly assign properties dynamically.

If you look at another built-in function called json_decode(), it uses stdClass:

$string = '{
    "text": "coucou"
}';
print_r(json_decode($string));
Enter fullscreen mode Exit fullscreen mode

The result is:

stdClass Object
(
    [text] => coucou
)
Enter fullscreen mode Exit fullscreen mode

When you cast an array as an object, you get an stdClass Object:

$them = (object) ["Ava", "Iris", "Delta",];
print_r($them);
Enter fullscreen mode Exit fullscreen mode

See the print:

stdClass Object
(
    [0] => Ava
    [1] => Iris
    [2] => Delta
)
Enter fullscreen mode Exit fullscreen mode

Source: PHP documentation - reserved classes

References vs. values

This confusion happens a lot:

$numbers = range(1, 7);
foreach ($numbers as &$value) {
    // some code
}
foreach ($numbers as $value) {
    // some code
}
print_r($numbers);
Enter fullscreen mode Exit fullscreen mode

Look at the results after the second loop:

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    [5] => 6
    [6] => 6
)
Enter fullscreen mode Exit fullscreen mode

What the...

The first loop passes $value by reference, then the second loop passes $value by value. The problem is that the script still holds the reference from the last pass (of the first foreach).

To fix that, you can clean $value:

$numbers = range(1, 7);
foreach ($numbers as &$value) {
    // some code
}

unset($value);// clean $value

foreach ($numbers as $value) {
    // some code
}
print_r($numbers);
Enter fullscreen mode Exit fullscreen mode

Now, as probably expected, you get "7":

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    [5] => 6
    [6] => 7
)
Enter fullscreen mode Exit fullscreen mode

Wrap up

PHP has powerful built-in functions, but it's easy to get confused.

There are specific rules you must know to prevent nasty bugs, and it's better to look at things with a fresh eye.

Photo by Quino Al on Unsplash

Discussion (0)

Forem Open with the Forem app