-2

Recently I moved my WIP site from a Windows XP machine with WAMP to a MacBook with MAMP. As I test the site I'm finding that the redirects (i.e., $this->redirect="Index.php";) don't seem to be working. They worked fine on the Windows XP machine.

I use a front controller pattern. The index page looks like that:

Index.php:

<?php
.....
switch ($action){
    case 'logoff':
        require_once('Controller_Logoff.php');
        $command=new controller_Logoff();
        break;
    case 'register':
        require_once('Controller_Register.php');
        $command=new controller_Register();
        break;
    ...
}

...
$command->execute($view);
$menu=array(
    new MenuEntry("Logoff","Index.php",array("action"=>"logoff")),
    new MenuEntry("Register","Index.php", array("action"=>"register")),
    ....
) // This menu is shown on the user's view

if ($command->getRedirect()){ //This case doesn't work
    header('Location:'.$command->getRedirect());
}else if ($command->getInclusion()){ //This case works
    include ("UI_Header.php");
    include ("UI_Menu.php");
    include ("UI_Message.php");
    echo "<div class='content'>";
    include ($command->getInclusion());
    echo "</div>";
    include ("UI_Footer.php");
}

The problem seems to occur at this stage: header('Location:'.$command->getRedirect()); Note that it still fails if I do header('Location: http://localhost:8888/'.$command->getRedirect());.

I also tried to include ob_start(); in my script, to no effect.

An example on one of the controller pages (at the end of a new user registration) I have:

Controller_register.php:

<?php

class Controller_Register extends Controller {
    protected $inclusion='UI_Register.php';
    function execute($view){
        .... // Code to register a new user - that works, i.e., a new user appears in the DB
        var_dump("Before redirect");
        $this->redirect="Index.php";
        var_dump("after redirect");
    }

The redirect is a variable in the class used for the various controllers. It's set as null in the parent class. I have verified that it is changed to its correct value (Index.php) by the time the header should be executed.

When I run this code, I get a blank page. The exact course of events is:

  1. Open the site - URL is http://localhost:8888/Project/
  2. Click on the menu item register which sends me to the registration page, which URL is http://localhost:8888/Project/Index.php?action=register
  3. Enter the required info (username, PW, and email) in the registration form and click submit - the information is successfully loaded into the db.
  4. Shown a blank page - the URL doesn't change and remains http://localhost:8888/Project/Index.php?action=register but obviously the file (the registration page) isn't loaded.

The error log from the time I start clicking on the register link yields the following:

  • [09-Oct-2014 23:10:00 Europe/Berlin] PHP Warning: Cannot modify header information - headers already sent by (output started at /Applications/MAMP/htdocs/Project/Index.php:1) in /Applications/MAMP/htdocs/Project/UI_Header.php on line 2
  • [09-Oct-2014 23:10:07 Europe/Berlin] PHP Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at /Applications/MAMP/htdocs/Project/Index.php:1) in /Applications/MAMP/htdocs/Project/Index.php on line 13
JDelage
  • 13,036
  • 23
  • 78
  • 112
  • How could this have ever worked? You are making an assignment, not a function call or execution. – Mike Purcell Oct 02 '14 at 21:57
  • `$this->redirect="Index.php";` will never be able to invoke a redirect out of itself. Where is this property used later in the code? – TheWolf Oct 02 '14 at 21:57
  • 1
    May be `$this->redirect('Index.php');`? BTW - Windows does not care about registry of the filenames, but Mac (as other *nix systems) does.. Just in case if something does not work at all (looking at `Index.php`).. – Cheery Oct 02 '14 at 22:00
  • @TheWolf Technically it is possible and you can make it "work" like that. Although the person who created that API should be shot in the face if that would really be the case. – PeeHaa Oct 02 '14 at 22:04
  • 1
    @TheWolf What about 'magic' `__set`? – Cheery Oct 02 '14 at 22:04
  • I stand corrected, you two are right. However, as @PeeHaa already said, I really hope that's not the way things work in that API. – TheWolf Oct 02 '14 at 22:08
  • Looking at the code, you seem to be setting the property to a value, but you don't seem to be invoking a method. What can you tell us about the $this object? – Sarcastron Oct 02 '14 at 21:57
  • Do you get any errors, warnings or even notices? Have you tried reporting all errors `error_reporting(E_ALL)`? – Alejandro Arbiza Oct 09 '14 at 20:24
  • @ Alejandro - I copied the content of the error log above. – JDelage Oct 09 '14 at 21:14
  • Is it "Index.php" or "index.php"? Mind the capitalization on *nix systems. – tacone Oct 07 '14 at 01:26

3 Answers3

3

output started at /Applications/MAMP/htdocs/Project/Index.php:1)

Remove BOM mark from Index.php or any space in front of <?php

http://en.wikipedia.org/wiki/Byte_order_mark

And read this, please - https://stackoverflow.com/a/8028987/1164491

Community
  • 1
  • 1
Cheery
  • 16,063
  • 42
  • 57
  • There's no white space before ` – JDelage Oct 09 '14 at 21:33
  • @JDelage Use, for example, Notepad++ or its analogues and choose UTF encoding without BOM – Cheery Oct 09 '14 at 21:40
  • I just downloaded a hex editor, and it does show a BOM on my file. Given that it's a file I produced on Eclipse in Windows and imported into Eclipse on Mac, I'm kinda pissed... – JDelage Oct 09 '14 at 21:48
  • @JDelage Did it help? I always use simple editors which allow to save the file without BOM. And I saw somewhere a script which check each .php file for BOM and removes it. – Cheery Oct 09 '14 at 21:50
2

I'm assuming that the code you shared is showing only those portions that you estimated relevant; and based on that the one thing I would do there is to add an exit after sending the header so you are sure that no code will be executed after:

...
if ($command->getRedirect()) { //This case doesn't work
    header('Location:'.$command->getRedirect());
    exit;
} else if ...
0
var_dump("Before redirect");
$this->redirect="Index.php";
var_dump("after redirect");

This is what is causing the redirect failure. The var dumps are outputting to the browser, preventing the redirect from occurring. Try commenting out the vardumps and see if that gets it working.

I also tried to include ob_start(); in my script, to no effect.

This should work, too, but ensure this is included before the above code is run.

UTAlan
  • 132
  • 1
  • 9
  • I only added the `var_dump()` commands as a way to see where the problem was occuring. The code doesn't work with or without them. – JDelage Oct 09 '14 at 19:41