Some additional notes

As you can't assume that gettext is available and you want your app to work in all environments, you should provide a gettext "emulation":
function _( $strString){return $strString;}
function bindtextdomain( $strString){return $strString;}
function dcgettext( $strDomain, $strString, $nCategory){ return $strString;}
function dgettext( $strDomain, $strMessage) { return $strString;}
function gettext( $strString){return $strString;}
function textdomain( $strString){return $strString;}
Replace the line
die( 'gettext extension is not available!');
with the code above, and the gettext functions will be available even if gettext is not installed. They just return the original text, so that the apps will be in the original language.

In message boxes you ask the user "There is a file "{FILENAME}". What shall I do with it?". The {FILENAME} could be on a totally different position in one of the target languages, so splitting the string is not an option.

The solution is to replace the "{FILENAME}" with "%s" and use the sprintf() php function with the string. That way your strings are as portable as possible.

Sometimes you need to translate strings which are on multiple lines: They are noted in .po files on multiple lines as well, with quotes at the beginning and the end of a line. The first line is just a "".

msgid ""
"this is a"
"multiline string"
msgstr ""
"Dies ist ein"
"mehrzeiliger String"