$formvar = preg_replace("/[^\w\d]/g","",$formvar);
inside the brackets add any special characters you want to allow. example:
[^\w\d\-\@\.\&\n ] (note the unescaped space)
A whitelist is far more powerful than just removing characters you think are bad. It's future proof.
This regex tells preg it wants to replace everything except the characters listed after the carat. In a bracketed character list carat means "anything except the following".
\w = word characters
\d = numeric digits
the rest are just escaped individual characters.
For address data like "apt. #305". You can do a regex in front of the one I gave that converts "#" to "number" or don't do anything before to let the above just remove it.
$formvar = preg_replace("/\#/g","number",$formvar);
Also remember that you can't do:
$_POST['formvar'] = preg_replace("/\#/g","number",$_POST['formvar']);
because this array is immutable. but
$formvar = preg_replace("/\#/g","number",$_POST['formvar']);
would work.
By not allowing ; or # you also break encoded characters on query string or POST which is a good measure to help break XSS. By not allowing ' or " and ; you help break sql injections, though you should also use the functions for filtering query data. The &'s used for argument separation aren't affected since these are not included in the data when you read them for php.
Default deny for the win. You may need to do a few tweaks if you discover stuff getting scrubbed that shouldn't be, but it's way more secure than doing it the other way.
-r