You do NOT want an external REDIRECT. Your code delivers a 302 redirect. The person accessing the page will see "http://www.example.com/fake-page.html" in the address bar of their browser. What you need here is an internal REWRITE.
You do not need to test REQUEST_URI here. Put the URL to be tested in the RewriteRule RegEx pattern.
That is, "RewriteRule .*" says "test every page, image, stylesheet, script request" to see if it matches. You only want to match one specific URL request, so put that one in the RewriteRule RegEx pattern.
The RewriteRule target will be "/fake-page.html" specified without domain name, because you want an internal rewrite not an external redirect.
Add only the [L] flag. Omit the [R] flag. You do not want an external redirect.
The reason the code appears to not work is because your browser caches the response codes and the page content. Clear your browser cache before each test. PHP solution:
The proposed PHP solution also delivered an external 302 redirect exposing the fake page name. What was needed here was a simple include statement. You deliver the fake page to certain visitors, but you deliver it at the exact same URL they originally requested. Caching:
For either method, I would ensure that the page also delivers an expires HTTP header loaded with the current date and time in order to prevent caching:
HEADER ("Date: " . gmDate("D, d M Y H:i:s") . " GMT");
HEADER ("Expires: " . gmDate("D, d M Y H:i:s") . " GMT");