0

On one of my class-based sites, everything is controlled via the index.php page, and every page is its own class that gets called via that index page.

In one of those classes lies both the logged-in and logged-out header that gets called for every page of the site, both of which make a call for an Ad that appears at the top of the site.

The problem is that whenever there is a redirect on a page, it doesn't happen until the class for that page gets called, which happens after the header has already been called, which means that an ad call was made for an ad that was never seen since the page ended in a redirect.

This negatively impacts the performance of the ads since it lowers the Click-through Rate (CTR) of the ads.

How can I ensure an Ad call is not made when a page ends up in a redirect, if there is no way to know the page ended up redirecting until the class for that page is loaded?

The only "outside-the-box" solution I can think of is to somehow use the output buffer to first load the class for that page, and then somehow append the header to the start of the buffer if it makes it to that point with no redirect, but I have no idea if that would work or how you would even do that.

Any ideas?

EDIT:

To clarify, the Redirects are already done via the HTTP header, and all output is currently being buffered. However, each page can have it's own reasons for redirecting, so that's why it's controlled by each page. For example, one page takes care of sending messages, and when a message is sent, it redirects the user back to their inbox after saving the message to the Database. On another page, logged-out users aren't allowed, so that particular page checks to see if a user is logged-in, and if not, redirects them to the login page.

However, it seems that even with full output buffering enabled and with the redirects being done via the header() function inside individual class pages, the buffering STILL does an Ad call before running the header redirect.

ProgrammerGirl
  • 3,157
  • 7
  • 45
  • 82

1 Answers1

0

Redirects must happen in the HTTP header, not using HTML meta tags or Javascript trickery or similar. HTTP headers need to be output before anything else. Because of that and simply because it makes sense, your application should decide whether it wants to redirect the user or not before it even attempts to output any HTML. Therefore there should be no problem at all.

If your current application logic outputs or prepares HTML (which triggers ads) before it decides to redirect the user, you simply have a bad application structure. Change it. It should work like this:

...

if ($userNeedsToBeRedirected) {
    header('Location: http://example.com/other/url');
    exit;
}

// output HTML and ads here
// never triggered on a redirect
deceze
  • 510,633
  • 85
  • 743
  • 889
  • The Redirects are already done via the HTTP header, and all output is currently being buffered. However, each page can have it's own reasons for redirecting, so that's why it's controlled by each page. For example, one page takes care of sending messages, and when a message is sent, it redirects the user back to their inbox after saving the message to the Database. On another page, logged-out users aren't allowed, so that particular page checks to see if a user is logged-in, and if not, redirects them to the login page. [cont...] – ProgrammerGirl Nov 26 '12 at 14:28
  • However, it seems that even with full output buffering enabled and with the redirects being done via the header() function inside individual `class` pages, the buffering STILL does an Ad call before running the header redirect. Any other ideas? – ProgrammerGirl Nov 26 '12 at 14:28
  • If you *execute* code that places the ad in the output buffer... Well, yes, then that code gets called. I don't understand why this code is running though. Ads are part of the HTML, right? Why are you already assembling HTML before you have decided to redirect? That's bad application structure/logic. – deceze Nov 26 '12 at 14:31
  • Because the header is called before the individual page is called, so by the time the redirect is reached in the page code, the ad has already been called into the buffer. In reality, the problem seems to be that even though the Ad is displayed as HTML, it has to be called from the Ad service, and it seems the PHP buffering doesn't wait until the buffering is done to call the Ad, and actually makes the call the moment that line is reached even though no output has yet been made. [cont...] – ProgrammerGirl Nov 26 '12 at 14:53
  • This is why the `header()` redirect is able to happen AFTER the Ad call, since nothing has been outputted yet even though the Ad has already been "inputted". Does that make sense? – ProgrammerGirl Nov 26 '12 at 14:54
  • Well yes, but either way... I dunno how the ad is tracked, whether the call to the PHP function that includes the HTML for the ad already triggers it or whether the HTML evaluated by the browser triggers it. Either way: **If you don't need the ad because the user won't see it because he's going to be redirected anyway, don't output the ad in whatever form.** If there's a redirect, don't output *any* HTML at all, buffered or otherwise, because you don't need it. That's all one can say about this. Structure your application around this premise. Look into an MVC structure which helps you do this. – deceze Nov 26 '12 at 15:41
  • Your solution is outside the scope of this question as it would require re-doing the entire site, which is not possible at this time. I'm looking for a solution within the context of the existing site, and I think the solution might be found within the buffer itself. Do you know if it's possible to append something to the beginning of the output buffer before it is echo'd? If so, then all I would need to do is append the header to the buffer **after** the page is called. Please let me know. – ProgrammerGirl Nov 26 '12 at 16:13
  • Well, what triggers the ad being tracked? Is it the PHP call that places the HTML in the output buffer? Then there's no solution other than *don't make that call that places the HTML in the output buffer*. Because once it's called it's too late to change anything about the call. If it's that the HTML is evaluated by the browser, even during a redirect, then don't output the HTML; you could do this by throwing the buffer away using `ob_end_clean`. If it's anything else you need to provide more information. – deceze Nov 26 '12 at 16:20
  • It's the PHP that calls the Ad the moment that line is reached, but I disagree that there's no solution. All I would need to do is not call the site header class until AFTER the page class has been called, and then simply append it to the start of the buffer. That way, if there is a redirect in the page, the site header class won't get called during that pageload and thus the Ad won't get called. – ProgrammerGirl Nov 26 '12 at 16:28
  • Yes, so the answer is to *not call that function/class.* There's no trick using output buffers here. Output buffers cannot prevent or delay code from being executed. It's all just procedural code, called one line after the other. If you don't want certain code to be called, you need to avoid calling it. – deceze Nov 26 '12 at 16:34
  • This is the solution I'm referring to: http://ideone.com/kNtjrp# Notice how the "header" is being called AFTER the "page", yet it appears BEFORE the "page" in the output. If the "page" contained a redirect, then the "header" would not get called. I think I found my solution. – ProgrammerGirl Nov 26 '12 at 16:37
  • The header is not "being called". The code that creates that header (`echo`) is **executed** in the order that it is in the source code. The *output* is simply buffered and swapped around. The order of the code *execution* doesn't change though. If your ad is tracked when the code is *executed*, this solution doesn't help at all. The only solution is to *not execute the code*. – deceze Nov 26 '12 at 16:40
  • I see, thanks for the explanation. Would there be a way to know at any point in a script whether header() has been called BEFORE it? If so, then I could do my solution, and in the "header" class, I could check if header() has been called before it (e.g. in the "page" class), and then NOT execute the ad code. Is that possible? (I'm just trying to think of an outside-the-box solution...) – ProgrammerGirl Nov 26 '12 at 16:48
  • There's `headers_list()`, which gives you a list of headers to be sent. I'd simply `exit` after a `Location:` header though, which prevents any following code from being executed. It's the usual, sane way to do it. – deceze Nov 26 '12 at 16:50
  • Interesting. Theoretically, if I were to combine my solution regarding calling the "header" class after the "page" class, while adding `exit()` after every redirect `header()` call, would that work? I know it's very crude, but it sounds like it would work. What do you think? – ProgrammerGirl Nov 26 '12 at 17:18
  • I don't know, since I don't know your app. I have given all the general advice I can. – deceze Nov 26 '12 at 18:19