Search code examples
phpincludefopenreversefwrite

PHP: invert/reverse file line order when include()d OR when writting with fwrite


I have created a small module that allows users to add small messages when entering a webpage. For that, it writes them down into a html document (msg.html) and later in the page I include() it into a div.

My biggest problem is that I don't know how to make the resultant file, the one showed with the include(), to show the most recent as first and so on... I tried changing the fopen atributes (a, r, b, c, cb+, etccccc), but nothing steady.

For how I see it, I should make the php form write into the file, append ALWAYS at the top most line, so the include() will show the file normally, the most recent as first.

OR, I could make some kind of reversed array and include() or echo the "reversed" content. In either way, I just don't have the knowledge to make that happen.

Here is my code:

<?php

if (isset($_POST['msg'])) {

    $usr = preg_replace('/[^a-zA-Z0-9]/', '',$_POST['usr']);
    $msg = $_POST['msg'];

    if (empty($usr)) {
        $usr = "Anonymous";
    }

    if (!empty($msg)) {
        $fsp = fopen('msg.html', "ab+"); 
        fwrite($fsp, '<tr><td class="info"><span class="usr">'. $usr .'</span><br><span class="dat">'. date("F j, Y, H:i ") .'</span></td><td>'. $msg ."</td></tr>\n");
        fclose($fsp);
        unset($_POST['msg']);
        unset($_POST['usr']);
    }
}

?>

<form method="post" action="#">
    <div id="comments">
        <h3>Messages</h3>
        <table>
            <tr><td>Name:</td><td><input type="text" id="usr" name="usr"></td></tr>
            <tr><td>Message:</td><td><textarea id="msg" name="msg"></textarea></td></tr>
            <tr><td></td><td><input type="submit" value="Add message!"></td></tr>
        </table>

        </table>
        <table id="ccc">
            <?php include('msg.html'); ?>
        </table>
    </div>
</form>

Solution

  • Since you are descreetly placing a newline at the end of each line you could do this instead of include:

    $arr = file('msg.html');
    echo implode("", array_reverse($arr));
    

    The only gotcha I can see here is that you will need to make sure that no newlines exist within the message itself. so change

    fwrite($fsp, '<tr><td class="info"><span class="usr">'. $usr .'</span><br><span class="dat">'. date("F j, Y, H:i ") .'</span></td><td>'. $msg ."</td></tr>\n");
    

    to

    fwrite($fsp, '<tr><td class="info"><span class="usr">'. nl2br($usr) .'</span><br><span class="dat">'. date("F j, Y, H:i ") .'</span></td><td>'. nl2br($msg) ."</td></tr>\n");