The above directive instructs Nginx to pass every request, whose URL end with ".php" to the PHP interpreter. It works very well and is a nearly universal solution. But in fact, if you use Yii it is excessive.

If you are somewhat familiar with Yii, you might already know that application lifecycle starts in
the so called "entry script", usually named index.php. This is where the web application instance
is created and request processing started.

The truth is that among all of the PHP files that an application consists of, only the entry script
really should be invokable with PHP interpreter from the web! So the relevant part of Nginx config
should resemble the following:

One may ask how this rather subtle configuration change affects security. Here is a little example.

Imagine you have written and application, which among other things allows users to upload some files.
Now, if you "forgot" to implement strict validation rules, malicious user could potentially
upload (exploiting e.g. some NUL char vulnerability) file shell.php into the
server's uploads folder.

Now the malicious user opens the URL: http://yourapp.net/uploads/shell.php

If the common configuration snippet was used, the request will be passed to the PHP - WIN for the hacker.

With the config from this article, the 404 Not Found will be shown - FAIL for the hacker :)

The described approach is not always applicable. If you use some third party tools (e.g. KCFinder),
which has its own scripts meant for web access (e.g. browser.php, upload.php etc), you will need to allow PHP for
these scripts as well. Or better, write a Yii-compatible wrapper script, which will then pass
request parameters from the entry script to a corresponding third party handler.

Really, this article must be upvoted thousand times. It's a really simple change, but dramatically reduces the attack surface. Most MVC frameworks could be using this approach, I wonder why the authors don't advocate it.

As a side note, you can omit that 404 rule and simply return other .php files as text, so they are simply rendered in browser, instead of being interpreted on the server.