while ($file = readdir($dp))
It's using = instead of == inside the condition. When you use = in a condition, the condition evaluates if the variable is true or false. It's really easy to accidentally create an infinite loop that way. Also if anyone sees it they usually assume that you typed it wrong and meant == instead, so if you use it you should add a comment to it.
In this case it kinda works since readdir() returns false when it's done reading the dir, BUT the example section of the documentation for readdir() clearly states not to do it this way.