At the risk of running afoul of Muphry's Law, your example needs double-quoted strings and curly braces (or your identifiers need to be moved outside the quotes and concatenated in).
At any rate, a downside to this approach is that you can't easily add a class or target (or any other attribute) to the A tag (at least in your simplified example).
Of course you could have an optional named parameter that would allow you to pass them in, e.g.:
function user_profile_link ($user, $attrs) {
return build_tag('a', array_merge(array('href' => "/user/profile/{$user->profile}"), $attrs), $user->name);
}
function build_tag ($tag, $attrs, $content) {
array_walk($attrs, create_function('$value, $name, $list', '{$list[] = htmlentities($name, UTF-8) . "=\"" . htmlentities($value, UTF-8) . "\"";}'), &$list);
return "<$tag " . join(' ', $list) . '>' . (($content !== '') ? htmlentities($content, UTF-8) . "</$tag>" : '/>');
}
But trying to do method-chainey sorts of things in PHP quickly runs into the language's clunky syntax, not to mention keeping track of exactly what level of quotation you're at, and so on. This is one of the reasons I like Ruby, as this kind of stuff is much more natural. Something like this:
def build_tag(tag, attrs, content)
attr_string = attrs.collect { |name, value| h(name) + '="' + h(value) + '"' }.join(' ')
"<#{tag} #{attr_string}>" + ((content != '') ? h(content) + "</#{tag}>" : '/>')
end
Both of these are probably a little denser than a sane person would put into production code, but the Ruby example is much more human-parseable to my eyes. (I'm using rails helper 'h', which could easily be defined in PHP as well).