Because it is difficult / inefficient to test each variable before using it. Instead, they only check the input variables - check visitors at the door, and not once in the house.
This, of course, a good defensive programming method for testing at least the more important vars before using them, especially if the input comes from many places.
This is a little off topic, but the solution I would recommend is to check the input variables as follows:
$username=get('username', 'string'); $a=get('a', 'int'); ... , 'string'); $username=get('username', 'string'); $a=get('a', 'int'); ... , 'int'); $username=get('username', 'string'); $a=get('a', 'int'); ...
$ _ REQUEST, and the like should never be used (or even be available) directly.
In addition, when the output HTML, you should always use it:
echo html($username); // replaces '<' with '<' - uses htmlentities
To avoid SQL injection attacks, you can use MeekroDB, but unfortunately it is very limiting (only MySQL, only one DB ...). It has a nice API that contributes to security, so I would recommend checking it out. For myself, I created a small database library that is based on PDO and uses prepared statements. YMMV.