The $1 reference is only available within the preg_replace() context - you can't just store it as text inside another variable and expect preg_replace() to parse it correctly.
Try something like this:
$variable['new'] = 'hi';
$variable['cow'] = 'wow';
$string = 'this is a [phpfile=new]. [phpfile=cow]!';
$string = preg_replace('/\[phpfile=(\w+)\]/ie', '$variable["$1"]', $string);
If you'll notice, I'm using the 'e' modifier on the regexp. What this does is makes PHP treat the replacement string (the 2nd parameter of the preg_replace() function) as PHP code. So instead of literally replaceing it with $variable["$1"], it a) replaces $1 with the first matched subset of the pattern, and b) parses the string $variable["new"] as PHP code, which obviously evaluates to the string "hi" in your example.