Your problem is that sed is a single-line tool; it looks at files one line at a time. It is possible to tell it to retain context across lines and have it vary its actions based on that, but this is a rather obscure and difficult, and therefore rarely used, feature of sed. Instead, I would do this with Perl:
#!/useusr/bin/perl -w
use strict;
use warnings;
foreach my $file (@ARGV) {
    open INPUT, "<$file";
    open OUTPUT, ">$file.new";
    my $found = 0;
    while (my $line=<INPUT>) {
        if ($line =~ /<\?php/ && !$found) {
            $found=1;
        } else {
            print OUTPUT $line;
        }
    }
    close INPUT;
    close OUTPUT;
}
 call with the list of files you want it to edit as command-line arguments. It will dump the filtered output into files with an additional .new extension.
Having said that though, best practice when your server is compromised is to wipe it and restore from backups. There's no telling what other bad things might have happened.
 
                