^ this is really really important!
But it could be even worse depending on your server configuration. I believe (but I haven't tested) that some Apache configurations can result in unknown file extensions being ignored. So if someone uploads a file named say "myhack.php.foobar" and it is placed in a publicly accessible directory, Apache will ignore the "foobar" extension because it doesn't recognise it, and then decide it's a PHP file, and execute it.
Also check out Apache content negotiation
while you're at it) and here the you see that index.html.en and index.en.html could all evaluate as index.html and you can see a similar way file naming could potentially be abused.
The parent post describes how PHP (or any script for that matter) _could_ be injected, but doesn't completely show how it could be executed. The above gives some ideas how that might work.
You _could_ just test that the file name ends with (.png) and Apache _should_ serve it as "image/png". But that's not secure enough for my liking, so my recommendations are:
And lastly, don't leave anything to chance. This is a really risky area that a lot of people screw up! Never be complacent. Always revisit it. Don't rely on server configuration to be correct because it's too easy to set things up, then move/rebuild a server, and then find you're vulnerable. You need multiple layers of defence.
I have a question to any who anyone who knows - why doesn't Apache demand that PHP scripts have their execute bit set? Because it seems to me that would help quite a bit.