header('Content-Type: application/octet-stream'); // или какой там у вас mime-type
header('Content-Transfer-Encoding: Binary'); // или текст?
header('Content-disposition: attachment; filename="file.exe"');
Еще неплохо бы указать header('Content-Length: '.filesize($fn));
Но он не всегда известен заранее, и иногда работает без него.
Без Content-Length в Google Chrome, например, будет "бесконечная" загрузка файла. Пользователю будет непонятно, сколько ему осталось грузить, поэтому лучше указывать.