"Common and not bad"
You way is the most common way of implementing such mechanism. Message however seem to be misleading for end-user and too helpful for potential wrong-doer, so you could simply send a 404 error header and exit, instead.
In including file:
define("INCLUDING", true);
In the file meant to be included:
if (!defined("INCLUDING")) {
header($_SERVER["SERVER_PROTOCOL"] . " 404 Not Found");
exit;
}
"Better"
Other approach looks, for example, like this:
if (basename($_SERVER['PHP_SELF']) === basename(__FILE__)) {
header($_SERVER["SERVER_PROTOCOL"] . " 404 Not Found");
exit;
}
basename($_SERVER["PHP_SELF"])
will give you the current filename, and
basename(__FILE__)
will give you the name of file it is being called from (__FILE__
is so called magic constant).
This approach has that advantage that you don't need to define constant variable in files that will include the "include-only" files (no need for define("INCLUDING", true);
each time you include).
You can put count(get_included_files()) === 1
in your if
's body instead, too (replace 1
with 0
for PHP's versions earlier than 5.0).
"Best"
However, it would be best, if you would simply move all your "include-only" files into a particular directory, to which you would deny access.
For apache, example code to put in your server config file looks like this:
<Directory /var/www/includes/>
Order deny,allow
Deny from all
</Directory>
If you drop first and last line of the above code, you can put it in the .htaccess
file in the said directory you want to restrict access to, but it's preferred that you don't create .htaccess
files if you don't have to, for performance reasons.
For Nginx:
location /includes {
deny all;
return 404;
}