こんにちは。
率直に言って、なぜそうなるのか理解できませんでした、だけだと
どうにも回答の仕様がないのですが・・・。
経験上、ハマるとわかりにくい所を推測しますと、
おそらくyokkaman2007さんは、
$bun =
preg_replace('/<a href="(.*?)">/i','<a href="'.urlencode("$1").'">',$bun);
の記述で
preg_replaceの中で
'<a href="'.urlencode("$1").'">'
の動作が行われることを期待していたと思いますが、PHPの言語の性格上、
関数の引数に渡すのは値であり、式は渡せません。
よって、行われるのは上記の文を評価し、その値を
preg_replaceに渡す動きです。
言い換えれば
$replace_ment = '<a href="'.urlencode("$1").'">';
$bun =
preg_replace('/<a href="(.*?)">/i',$replace_ment,$bun);
とほぼ同じ動作になるはずです。
式をそのまま
preg_replaceに渡す事はできない。
それでもマッチング結果に何かしら処理を施してから置換結果にあてる必要がある。
それを解決するための 方法の一つ として、提供したのが、前の回答の内容でして、
preg_replaceに、e修飾子を指定して、「この内容の命令を中で実行してね」という
命令文そのものを第二引数に渡すというやりかたです。渡された命令文は、
preg_replaceの中で実行されるので、この中に書いてある$1のキーワードも
有効になります。
こんなところで終わりにします。
理解できないところ、納得できないところを質問する場合、
どのポイントがわからないのか絞り込んで説明するか、
或いは、自分の予想(仮説)を順序だてて示して、自分の期待値と何が違うのか、
辺りを明示していただかないと、回答が徒労に終わる場合もありますので、
ご配慮いただきたく。

kende様のご指摘通り、三項演算子を使用する際には、コードの複雑度などを考慮する必要がありますね。書きやすさと共に可読性も追求したいところですね。