0

I am pretty new to "advanced PHP", and I keep coming across an error with PHP headers.

    <?php
        $getTrans = dbquery("SELECT * FROM cms_transactions WHERE userid = '".USER_ID."' AND pin = '0' ORDER BY date DESC LIMIT 50");
        $oe = 1;
        while($transaction = mysql_fetch_assoc($getTrans)){
            if ($oe == 2)
            {
                $oe = 1;
            }
            else
            {
                $oe = 2;
            }
            $oDate = strtotime($transaction['date']);
            $sDate = date("<b>l, j - F, o</b> g:ha",$oDate);
            echo'
                <tr style=" background-color: ' . (($oe == 2) ? '#e2e2e2' : '#fff') . ';">
                <td>'.$transaction['id'].'</td>
                <td>'.$transaction['descr'].'</td>
                <td>'.$transaction['credits'].' deducted</td>
                <td>'.$transaction['amount'].' deducted</td>
                <td>'.$transaction['vip_points'].' deducted</td>
                <td>'.$sDate.'</td>
                <td><input type="submit" value="+ Pin" name="'.$transaction['id'].'" /></td>
                </tr>
            ';
    $trans = $transaction['id'];
    if(isset($_POST["$trans"])){
        dbquery("UPDATE cms_transactions SET pin = '1' WHERE id = '".$trans."' AND userid = '".USER_ID."' LIMIT 1");
        header("Location: ".WWW."/identity/transactions");
    }
        }
        if(mysql_num_rows($getTrans) == 0){
        echo '<div class="error" id="black">You have no recent Transactions</div>';
        }

    ?>

I keep getting a PHP Header error at the bottom for /identity/transactions.

I realise that I am getting the problem because the "page has already loaded content", and a PHP Header must be used at the start of the page. The following snippet I posted is a file which is included; in the main file.

The main problem is, I am looking for a way to separate the content from the "backend" php work.

So for example:

The main PHP file has all the code, and the include(); file has the "content" side.

Is there any way that this is possible? If you could give an example, that would be great!

Please let me know if something is unclear to you.

EDIT; This is the WHOLE file:

<table class="information-table" style="margin-top:-5px;">
<tr>

<td style="text-shadow:none;">

<a class="new-button" href="<?php echo WWW ; ?>/account/logout"><b>Log out</b><i></i></a>

        <div id="back-link" style="color:#fff;">

        <a href="<?php echo WWW ; ?>/identity/avatars" style="color:#fff;">My Avatars</a> &raquo; <a href="<?php echo WWW ; ?>/identity/settings" style="color:#fff;">Account Settings</a> &raquo; Transactions

        </div>


</td></tr>
</table>


<div id="column1" class="column" style="width:960px;margin-right:10px;">

        <h1>Account Transactions:</h1>
        <h3>Pinned Transactions:</h3>
        <i>Pinning a transaction is useful if you have a transaction that is important; that you might need in the future!</i>
        <p>
        <table>
        <thead>
        <tr><td>ID</td><td>Description</td><td>Credits</td><td>Pixels</td><td>Stars</td><td>Purchase Date</td><td></td></tr>
        </thead>
        <tbody>
        <form method="post">
        <?php
            $getTrans = dbquery("SELECT * FROM cms_transactions WHERE userid = '".USER_ID."' AND pin = '1' ORDER BY date DESC LIMIT 100");
            $oe = 1;
            while($transaction = mysql_fetch_assoc($getTrans)){
                if ($oe == 2)
                {
                    $oe = 1;
                }
                else
                {
                    $oe = 2;
                }
                $oDate = strtotime($transaction['date']);
                $sDate = date("<b>l, j - F, o</b> g:ha",$oDate);
        $transs = $transaction['id'];
        if(isset($_POST["un$transs"])){
            dbquery("UPDATE cms_transactions SET pin = '0' WHERE id = '".$transs."' AND userid = '".USER_ID."' LIMIT 1");
            header("Location: ".WWW."/identity/transactions");
        }
                echo'
                    <tr style=" background-color: ' . (($oe == 2) ? '#e2e2e2' : '#fff') . ';">
                    <td>'.$transaction['id'].'</td>
                    <td>'.$transaction['descr'].'</td>
                    <td>'.$transaction['credits'].' deducted</td>
                    <td>'.$transaction['amount'].' deducted</td>
                    <td>'.$transaction['vip_points'].' deducted</td>
                    <td>'.$sDate.'</td>
                    <td><input type="submit" value="- Pin" name="un'.$transaction['id'].'" /></td>
                    </tr>
                ';
            }
            if(mysql_num_rows($getTrans) == 0){
            echo '<div class="error" id="black">You have no Pinned Transactions</div>';
            }

        ?>
        </form>
        </tbody>
        </table>
        </p>

        <h3>Recent Transactions</h3>
        <p>
        <table>
        <thead>
        <tr><td>ID</td><td>Description</td><td>Credits</td><td>Pixels</td><td>Stars</td><td>Purchase Date</td><td></td></tr>
        </thead>
        <tbody>
        <form method="post">
        <?php
            $getTrans = dbquery("SELECT * FROM cms_transactions WHERE userid = '".USER_ID."' AND pin = '0' ORDER BY date DESC LIMIT 50");
            $oe = 1;
            while($transaction = mysql_fetch_assoc($getTrans)){
                if ($oe == 2)
                {
                    $oe = 1;
                }
                else
                {
                    $oe = 2;
                }
                $oDate = strtotime($transaction['date']);
                $sDate = date("<b>l, j - F, o</b> g:ha",$oDate);
        $trans = $transaction['id'];
        if(isset($_POST["$trans"])){
            dbquery("UPDATE cms_transactions SET pin = '1' WHERE id = '".$trans."' AND userid = '".USER_ID."' LIMIT 1");
            header("Location: ".WWW."/identity/transactions");
        }
                echo'
                    <tr style=" background-color: ' . (($oe == 2) ? '#e2e2e2' : '#fff') . ';">
                    <td>'.$transaction['id'].'</td>
                    <td>'.$transaction['descr'].'</td>
                    <td>'.$transaction['credits'].' deducted</td>
                    <td>'.$transaction['amount'].' deducted</td>
                    <td>'.$transaction['vip_points'].' deducted</td>
                    <td>'.$sDate.'</td>
                    <td><input type="submit" value="+ Pin" name="'.$transaction['id'].'" /></td>
                    </tr>
                ';
            }
            if(mysql_num_rows($getTrans) == 0){
            echo '<div class="error" id="black">You have no recent Transactions</div>';
            }

        ?>
        </form>
        </tbody>
        </table>
        </p>

</div>
<style>
td {
padding:10px;
}

tbody td {
text-shadow:0 1px 0 #fff;
}

thead td {
font-weight:bold;
text-align:center;
}
</style>
zuc0001
  • 924
  • 4
  • 12
  • 27
  • there are a bunch of questions about this already: [this](http://stackoverflow.com/a/8028987/184124) is a really good, detailed answer about the problem with solutions – HorusKol Nov 19 '12 at 04:29
  • The usual way is to first do the page processing; after that is done, include the **content file** , and simply use the result of the processing in the content. – Kneel-Before-ZOD Nov 19 '12 at 04:36

2 Answers2

0

You can use Output buffering, in this case to prevent header already sent :

ob_start();
$getTrans = dbquery("SELECT * FROM cms_transactions WHERE userid = '".USER_ID."' AND pin = '0' ORDER BY date DESC LIMIT 50");
        $oe = 1;
        while($transaction = mysql_fetch_assoc($getTrans)){
            if ($oe == 2)
            {
                $oe = 1;
            }
            else
            {
                $oe = 2;
            }
            $oDate = strtotime($transaction['date']);
            $sDate = date("<b>l, j - F, o</b> g:ha",$oDate);
            echo'
                <tr style=" background-color: ' . (($oe == 2) ? '#e2e2e2' : '#fff') . ';">
                <td>'.$transaction['id'].'</td>
                <td>'.$transaction['descr'].'</td>
                <td>'.$transaction['credits'].' deducted</td>
                <td>'.$transaction['amount'].' deducted</td>
                <td>'.$transaction['vip_points'].' deducted</td>
                <td>'.$sDate.'</td>
                <td><input type="submit" value="+ Pin" name="'.$transaction['id'].'" /></td>
                </tr>
            ';
    $trans = $transaction['id'];
    if(isset($_POST["$trans"])){
        dbquery("UPDATE cms_transactions SET pin = '1' WHERE id = '".$trans."' AND userid = '".USER_ID."' LIMIT 1");
        header("Location: ".WWW."/identity/transactions");
    }
        }
        if(mysql_num_rows($getTrans) == 0){
        echo '<div class="error" id="black">You have no recent Transactions</div>';
        }    

ob_end_clean();
Somy A
  • 1,682
  • 15
  • 18
0

I've had a crack at refactoring your code, putting all the processing at the top of the page, and the presentation at the bottom (makes the error you are encountering much less likely to occur).

<?php

// I always do most of my PHP processing before any presentation stuff
// Makes for more manageble code

// Init the Variables
 // Transaction Arrays
$pinned_transactions = array();
$unpinned_transactions = array();
 // Interaction Variables
$ids = array();
$action = false;

// Check for Unpin/Pin Request
if( isset( $_POST['unpin'] ) && count( $_POST['unpin'] ) ){

  // There is a request to Unpin a Transaction
  $ids = array_keys( $_POST['unpin'] );
  $action = 0;

}elseif( isset( $_POST['pin'] ) && count( $_POST['pin'] ) ){
  // There is a request to Pin a Transaction
  $ids = array_keys( $_POST['pin'] );
  $action = 1;
}

// There was some kind of Pin/Unpin Request
if( count( $ids ) ){

  // Process the Change
  dbquery( 'UPDATE cms_transactions SET pin = '.(int) $action.' WHERE id IN( '.implode( ',' , $ids ).' ) AND userid = '.(int) USER_ID );

  // Set the Redirect
  $redirect_to = WWW.'/identity/transactions';

  // Use Headers, if we can
  if( !headers_sent() )
    header( 'Location: '.$redirect_to );
  // Outputting a javascript Redirect (as a fallback)
  //   along with a link (if javascript is off).
  echo '<script type="text/javascript">document.location.href = "'.$redirect_ro.'";</script>';
  echo '<a href="'.$redirect_to.'">Click here to continue</a>';
  die();

}

// Perform a Query for Pinned Transactions
$getTrans = dbquery( 'SELECT * FROM cms_transactions WHERE userid = '.(int) USER_ID.' AND pin = 1 ORDER BY date DESC LIMIT 100' );
while( $t = mysql_fetch_assoc( $getTrans ) ){

  $oDate = strtotime( $t['date'] );
  $sDate = date( "<b>l, j - F, o</b> g:ha" , $oDate );
  $t['date'] = $sDate;

  $pinned_transactions[] = $t;
}

// Perform a Query for Unpinned Transactions
$getTrans = dbquery( "SELECT * FROM cms_transactions WHERE userid = '".USER_ID."' AND pin = '0' ORDER BY date DESC LIMIT 50" );
while( $t = mysql_fetch_assoc( $getTrans ) ){

  $oDate = strtotime( $t['date'] );
  $sDate = date( "<b>l, j - F, o</b> g:ha" , $oDate );
  $t['date'] = $sDate;

  $unpinned_transactions[] = $t;
}


?><table class="information-table" style="margin-top:-5px;">
  <tr>
    <td style="text-shadow:none;">
      <a class="new-button" href="<?php echo WWW; ?>/account/logout"><b>Log out</b><i></i></a>
      <div id="back-link" style="color:#fff;">
        <a href="<?php echo WWW; ?>/identity/avatars" style="color:#fff;">My Avatars</a> &raquo; <a href="<?php echo WWW; ?>/identity/settings" style="color:#fff;">Account Settings</a> &raquo; Transactions
      </div>
    </td>
  </tr>
</table>

<div id="column1" class="column" style="width:960px;margin-right:10px;">

  <h1>Account Transactions:</h1>

  <h3>Pinned Transactions:</h3>
  <i>Pinning a transaction is useful if you have a transaction that is important; that you might need in the future!</i>
  <p>
<?php if( count( $pinned_transactions ) ){ ?>
    <form method="post">
      <table>
        <thead>
          <tr><td>ID</td><td>Description</td><td>Credits</td><td>Pixels</td><td>Stars</td><td>Purchase Date</td><td></td></tr>
        </thead>
        <tbody>
<?php   foreach( $pinned_transactions as $k => $r ){ ?>
          <tr class="<?php echo ( $k%2 ? 'odd' : 'even' ); ?>">
            <td><?php echo $transaction['id']; ?></td>
            <td><?php echo $transaction['descr']; ?></td>
            <td><?php echo $transaction['credits']; ?> deducted</td>
            <td><?php echo $transaction['amount']; ?> deducted</td>
            <td><?php echo $transaction['vip_points']; ?> deducted</td>
            <td><?php echo $transaction['date']; ?></td>
            <td><input type="submit" value="- Pin" name="unpin[<?php echo $transaction['id']; ?>]" /></td>
          </tr>
<?php   } ?>
        </tbody>
      </table>
    </form>
<?php }else{ ?>
    <div class="error" id="black">You have no Pinned Transactions</div>
<?php } ?>
  </p>

  <h3>Recent Transactions</h3>
  <p>
<?php if( count( $unpinned_transactions ) ){ ?>
    <form method="post">
      <table>
        <thead>
          <tr><td>ID</td><td>Description</td><td>Credits</td><td>Pixels</td><td>Stars</td><td>Purchase Date</td><td></td></tr>
        </thead>
        <tbody>
<?php   foreach( $unpinned_transactions as $k => $r ){ ?>
          <tr class="<?php echo ( $k%2 ? 'odd' : 'even' ); ?>">
            <td><?php echo $transaction['id']; ?></td>
            <td><?php echo $transaction['descr']; ?></td>
            <td><?php echo $transaction['credits']; ?> deducted</td>
            <td><?php echo $transaction['amount']; ?> deducted</td>
            <td><?php echo $transaction['vip_points']; ?> deducted</td>
            <td><?php echo $transaction['date']; ?></td>
            <td><input type="submit" value="- Pin" name="pin[<?php echo $transaction['id']; ?>]" /></td>
          </tr>
<?php   } ?>
        </tbody>
      </table>
    </form>
<?php }else{ ?>
    <div class="error" id="black">You have no recent Transactions</div>
<?php } ?>
  </p>

</div>
<style>

td {
  padding:10px;
}

// Odd and Even Rows
tr.odd {
  background-color:#FFFFFF;
}
tr.even {
  background-color:#E2E2E2;
}

tbody td {
  text-shadow:0 1px 0 #fff;
}

thead td {
  font-weight:bold;
  text-align:center;
}

</style>
Luke Stevenson
  • 10,357
  • 2
  • 26
  • 41