-2

I was made a mistake yesterday and spent hours to fix it. I have method like this

{
    if (isset($data['y'])) {
        $this->y = $data['y'];
    }

    if (isset($data['z'])) {
        $this->y = $data['z']; // <- error here
    }
}

And yes, I assign $this->y two times instead of one y and one z :-(

So question: can any static analyze tools catch such errors? I have PHP Storm and Rector, PHPStan, PHP CS Fixer in my CI toolchain but they missed this error.

5
  • 2
    How would anything detect that as an error, it could be exactly what you want to do. Commented Apr 8, 2022 at 19:08
  • I think about heuristics, because two assing of the same variable in row might be mistake. Commented Apr 8, 2022 at 19:15
  • The simplest situation with two assign in row are catched by PHP Storm and other tools { $this->y = $data['y']; $this->y = $data['z']; // <- error here } Commented Apr 8, 2022 at 19:16
  • What if you wanted to set a variable from either $data['y'] or $data['z'] depending on which one has a value? Commented Apr 8, 2022 at 19:18
  • If computers could tell what we mean to program them to do we wouldn't have to program them at all. Commented Apr 8, 2022 at 19:30

1 Answer 1

0

This isn't so much an answer, but it's too complicated to put in a comment.

As the comments pointed out, there's simply no way for a robot to figure out that what you wrote isn't what you intended. The easiest solution is to live with human frailty and debug your code.

But that doesn't mean you can't write your code to better express your intent. Consider:

{
    $fields = ['x', 'y'];

    foreach ($fields as $field) {
        if (isset($data[$field]) {
            $this->$field = $data[$field];
        }
    }
}

Now you have expressed in you code that you only want to assign like-named fields.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for idea. Unfortunally the real method is more complicated: it have type casts in issets like $this->id = (int) $data['id']; or $this->y = (float) $data['y'] and setters like $this->setCardsWidth((int) $data['width']);
Just spitballing, but you could make setters for all the variables, which would also catch many of your errors. Having all variables set the same way might make the interface of your object easier to maintain. You could even have the setters follow a pattern that would allow you to something like $setterName = 'set' . ucfirst($data[$field]); $this->$setterName($data[$field]);. Ultimately the point is that only you can protect yourself from errors like the one you describe.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.