One security rule I live by as a sysadmin, which admittedly causes me a lot of trouble with PHP apps, is that the running web server user is never able to write to files within the document root.
Any user-file upload/download mechanism goes somewhere else, so that read access can do a permission check, and be delivered through readfile()
or a redirect to a CDN, not passed through a complex mechanism that may decide to execute the file's contents.
Configuration files are similarly locked down. A project that configures itself with PHP code is a project that offers arbitrary code execution to anyone who can change that configuration file.
I don't let the web user install new code to /bin; we shouldn't let the web user install new code to /srv/www. It's the server, not a system administrator.
Not coincidentally, our document root is never the root of a git repository. It's typically placed in a public
folder, allowing us to have a special writable folder like cache
both within the project/deployment, and outside of the document root.