Qtree reads your tree and breaks it into tokens whenever it sees a space. Because of the way TeX works, when you write \en 22 the space is processed by TeX's input routine before qtree has had a chance to see it. To get it to work, use one of the following standard approaches:
Since your goal is an empty branch, just write ~ (a non-breaking space) instead of your custom phantom command:
\Tree [.12 ~ 22 ]
More generally, for any custom macro you want to use this way, add harmless syntax that avoids having a space immediately after your command:
\Tree [.12 \en{} 22 ]
\Tree [.12 {\en} 22 ]
Or you can try one of the following, slightly more creative solutions
Use a single punctuation character as your command name (but make sure you don't override a standard command you will need). Punctuation cannot be used in multi-character names (except by reassigning character classes, which never mind), so TeX does not swallow the space after such a command.
\renewcommand\~{\phantom{1}}
\Tree [.12 \~ 22 ]
Use TeX (not LaTeX) syntax to define a command that must be followed by punctuation when invoked. The punctuation (which is obligatory, but is not part of the command name) separates the command name from the space that follows.
\def\en/{\phantom{1}}
\Tree [.12 \en/ 22 ]
You can also arrange for your special command to take effect only in trees (this is especially useful with the third option, since most single-symbol commands are already in use). Instead of defining your command globally, define \qtreeinithook to define your command; the hook will be executed, with local scope, whenever you start a new tree.
\newcommand\qtreeinithook{\renewcommand\~{\phantom{1}}}
{}. See Space after LaTeX commands for more details. Also, you might consider using eithertikz-qtreeor the more powerfulforestfor drawing trees.qtreeis quite old and relatively limited. – Alan Munn Oct 04 '16 at 03:07