Значения в $ _POST уже html-декодированы для удобства. Поэтому, когда ваш скрипт запускается, верно следующее:
$_POST['txt'] == '&';
htmlspecialchars('&') == '&'
[править]
Похоже, это требует дальнейшего объяснения
Когда форма, подобная приведенной выше, передается на сервер браузером с одним амперсандом в качестве значения 'txt', в текст запроса помещается следующее:
txt=&
Значение закодировано, поскольку браузер объединяет несколько полей с символом амперсанда, например
txt=&&user=soulmerge&pass=whatever
PHP принимает переданные значения и декодирует их для удобства программиста - он делает амперсанд из & Теперь я подумал, что это было причиной вопроса в первую очередь - думаю, я ошибся. Фердинанд правильно ответил на вопрос.