2

I have a JavaScript update script that updates a chatroom, like this:

// Update chat rooms //
if(time > lastchatupdatetime + .4){
    for(var i in this.chatroomlist){
        var chattext = AJAX('server/updateChatRoom.php','id='+i);
        document.getElementById("S3DChatRoom_" + i).innerHTML = chattext;
    }
    lastchatupdatetime = time;
}

The AJAX function looks like this:

var AJAX = function (page, send, callback){

    if(typeof callback == 'undefined') callback = function() {};
    var xmlhttp;
    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
    }
    else { // for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }



    xmlhttp.onreadystatechange = function (){
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            chatresponse = xmlhttp.responseText;

            callback();
        }
    }
    xmlhttp.open("POST",page,true);
    xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xmlhttp.send(send);

    return chatresponse;
}

The PHP script looks like this:

$chatroomid = isset($_POST['id'])?$_POST['id']:0;
$chatroomdir = "../chatrooms/";
$chatroomurl = $chatroomdir . 'chatroom_' . $chatroomid . ".json";

if(file_exists($chatroomurl)){
    $chattext = json_decode(file_get_contents($chatroomurl),TRUE);
    if($chattext == TRUE){
    foreach($chattext as $i){
        echo $i[0] . ": " . $i[1] . "<br>";
    }
    }
} else {
    echo "Chatroom listed does not exist";
}

After I submit a new chattext, the text gets written and on first update it displays, and then on next update it gets deleted from the .json file that holds the chat contents. This makes absolutely no sense to me, and I've written similar chat applications without this problem even remotely existing. This happens on WebMatrix's IIS-Express PHP and on WAMP's PHP.

Here's the chat submit PHP script (with some debugging code left in it -- the debugging code works fine and all the information is correctly written):

$chatroomid = $_POST['id'];
$chatroomtext = $_POST['chattext'];
$clientid = $_POST['clientid'];
$chatroomdir = "../chatrooms/";
$chatroomurl = $chatroomdir . "chatroom_" . $chatroomid . ".json";

$currentchattext = file_get_contents($chatroomurl);

$currentchattext = json_decode($currentchattext, TRUE);

$currentchattext[] = array($clientid,$chatroomtext);
file_put_contents("debug2",json_encode($currentchattext));


$success = file_put_contents($chatroomurl, json_encode($currentchattext));
file_put_contents("debug",json_encode($currentchattext), FILE_APPEND);

if($success == FALSE){
    echo 0;
} else {
    echo 1;
}

This is the JavaScript for posting:

var submitChatTextconfirm;
document.getElementById("S3DTextInput_"+name).addEventListener("keypress",function(event) {
    if(event.keyCode == 13){
        submitChatTextconfirm = AJAX("server/submitChatText.php", "id=" + name + "&chattext=" + document.getElementById("S3DTextInput_"+name).value + "&clientid=" + this.clientid);
        console.log(document.getElementById("S3DTextInput_"+name).value);
        console.log(submitChatTextconfirm);
    }
},true);
if(submitChatTextconfirm == 1){
    console.log("Chat sent");
} else {
    console.log("ERROR: Chat text failed to send");
}
JVE999
  • 3,327
  • 10
  • 54
  • 89
  • how are you writing the json file? are you using "w", "a"? to write or append the document – Liam Sorsby Nov 11 '13 at 16:04
  • Perhaps multiple requests are interleaving, so you `file_get_contents` with one request, then with another, then the first request saves the file back, then the second request saves the file back, effectively removing the entry that was added by the first request. Make sense? Try using a database or something. – Jez Nov 11 '13 at 16:04
  • `file_put_contents($chatroomurl, json_encode($currentchattext), FILE_APPEND)` ? – CD001 Nov 11 '13 at 16:07
  • I added the chat submit php script. I understand there's probably going to be an issue with multiple requests placed too closely together, but for now I'm just focusing on getting it to work with one client open. – JVE999 Nov 11 '13 at 16:07
  • @CD001 I wanted it to be one array, so appending a new array would not work in this case. I think it would not be proper json to just append another array right after the last and I figured it would produce errors upon reading. – JVE999 Nov 11 '13 at 16:08
  • @JVE999 aaaah - so you do want to overwrite everything in the .json file with a new JSON each time holding the complete data... oki ... may need a little more thought then to follow exactly what's happening... – CD001 Nov 11 '13 at 16:10
  • @LiamSorsby What do you mean by using a "w" or and "a"? – JVE999 Nov 11 '13 at 16:10
  • @CD001 Yes, currently I'm reading the file, then appending a new array to the array and then rewriting it. Like I said, the debug works fine, all the information is written and when writing, it write fine, but on the next update (which has no file writing), everything gets deleted. – JVE999 Nov 11 '13 at 16:11
  • @JVE999 basically when you are "appending" the array are you sure you are appending the array and not just writing the array (which would cause it to delete previous data) – Liam Sorsby Nov 11 '13 at 16:12
  • Another peculiarity is the return in the AJAX function is posting to `document.getElementById("S3DChatRoom_" + i).innerHTML`, even though as far as I know, there is no instruction to do so. – JVE999 Nov 11 '13 at 16:12
  • @LiamSorsby Yes, as when writing to the debug file, it works properly. It's just during the update script that it deletes everything. – JVE999 Nov 11 '13 at 16:14
  • if you are appending then shouldnt $currentchattext = json_decode($currentchattext, TRUE); be $currentchattext[] = json_decode($currentchattext, TRUE); and $currentchattext[] = array($clientid,$chatroomtext); be $currentchattext[] .= array($clientid,$chatroomtext); – Liam Sorsby Nov 11 '13 at 16:15
  • Yeah - I'm not liking `$currentchattext = file_get_contents($chatroomurl); $currentchattext = json_decode($currentchattext, TRUE); $currentchattext[] = array($clientid,$chatroomtext);` - it looks as though you're going to have some issues with variable assignment ... try `$sCurrentChatText` for the strings and `$aCurrentChatText` for the arrray - just to make it a little clearer, and so one won't overwrite the other... – CD001 Nov 11 '13 at 16:15
  • @LiamSorsby In PHP, you can add an array key with `array[]= value;`, at least that's how I've been doing it for some time now and it's always worked. In your first example, I'm setting a new array, so `$currentchattext`, which is uninitialized previously, gets initialized as an array and then gets set. – JVE999 Nov 11 '13 at 16:17
  • @LiamSorsby I think the first change you suggested would append the array as a single value, which would cause the next append to not be an extension of the same array, so I'll have `$currentchattext = {previous chat text},{next line};` and then on next update, it would be `$currentchattext = {previous chat text {last line of the last}}{next line};` (that's in pseudocode, of course) – JVE999 Nov 11 '13 at 16:19
  • I've a feeling `$currentchattext[] = array($clientid,$chatroomtext);` is going to effectively overwrite `$currentchattext = json_decode($currentchattext, TRUE);` so you'll simply end up with an array, with a single index, holding `$_POST['chattext'];` – CD001 Nov 11 '13 at 16:20
  • I could use `array_push()`, but `array[] = new value` also works. Here's a reference: http://stackoverflow.com/questions/676677/how-to-add-elements-to-an-empty-array-in-php – JVE999 Nov 11 '13 at 16:22
  • Here's an example: http://phpfiddle.org/lite/code/krv-d16 – JVE999 Nov 11 '13 at 16:25
  • Here's an example with `json_encode` and `json_decode`: http://phpfiddle.org/lite/code/iux-v3i – JVE999 Nov 11 '13 at 16:29
  • Could you put up some example contents of a "chatroom" file? I had a bit of a play on codepad and noticed it breaks if you use the "wrong" quote marks. This casts the file contents to an array to which your new data **is** appended: http://codepad.org/DvdYKBaA ... this **doesn't** http://codepad.org/DSs2aY2P and the only difference in the input JSON is the quote marks. – CD001 Nov 11 '13 at 19:11
  • The most I get is a single line, and that looks like: `["undefined","ffdsafdsfds"]` I'll have to figure out why the client id undefined separately (the variable reads fine in the JavaScript file, but when sending through post, it doesn't send, but that's a different issue). I should escape the strings, but for now I'm not using quotes to test it. – JVE999 Nov 11 '13 at 20:09
  • Also, if it was working, it would look like, `[["undefined","fdsa"],["undefined","fdsa"]]`, which I got in the debug file during one of the tests (I don't remember what parameters I used, but they were not the correct ones for the json file for some reason). – JVE999 Nov 11 '13 at 20:11

1 Answers1

0

This isn't exactly an answer yet (but the comments are getting out of hand and I need to be able to put some code down)... but I don't think it's an issue with the PHP as such. I just refactored your script a bit and cobbled it into a file with a form submission (cutting out the AJAX for the moment) - just to debug.

Made a file called updateChatRoom.php and put it into a folder on my localhost - there's basically no sanity checks, input filtering or anything on this so it would be really, really bad on a live envirnoment, BUT it proves there's nothing really wrong with the concept.

What I've got in the PHP file is this:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>Chatroom test</title>
</head>

<body>

<form action="updateChatRoom.php" method="post">
<div><textarea name="chattext">Some chat text here</textarea></div>
<div><input type="submit" value="submit" /></div>
<div style="margin-top: 50px;"><label>id: <input type="text" name="id" value="<?php echo !empty($_POST['id']) ? (int) $_POST['id'] : "1"; ?>" /></label></div>
<div><label>clientid: <input type="text" name="clientid" value="<?php echo !empty($_POST['clientid']) ? $_POST['clientid'] : "abc123"; ?>" /></label></div>
</form>

<div>
<?php
if(!empty($_POST)) {

    $chatroomid = (int) $_POST['id'];
    $chatroomtext = $_POST['chattext'];
    $clientid = $_POST['clientid'];
    $chatroomdir = "";
    $chatroomurl = $chatroomdir . "chatroom_" . $chatroomid . ".json";

    echo "<p>\$chatroomurl = {$chatroomurl}</p>\n";

    if(file_exists($chatroomurl)) {
        $currentchattext = file_get_contents($chatroomurl);
        $currentchattext = json_decode($currentchattext, TRUE);
    }

    $currentchattext[] = array($clientid,$chatroomtext);
    file_put_contents($chatroomurl, json_encode($currentchattext));

    echo "<pre>" . file_get_contents($chatroomurl) . "</pre>\n";
}
?>
</div>

</body>
</html>

This puts a form on the page with your $_POST vars in it, when you submit the form it'll create a file called chatroom_[X].json where [X] is the value in the <input type="text" name="id" ... /> field.

If the file doesn't exist, it creates it.

This basically works, whenever you submit the form the JSON in the file is extended by another array of the form Array('ID_NUMBER', 'TEXT_INPUT').

What I'm not seeing in your code though is anything that actually POSTs the variables: chattext or clientid to updateChatRoom.php

As far as I can tell:

var chattext = AJAX('server/updateChatRoom.php','id='+i);

Will just POST id=X (where X is a chatroom id number) to updateChatRoom.php without either of your other variables.

CD001
  • 8,332
  • 3
  • 24
  • 28
  • I added the post a new message script to the end of the original post. This is essentially what I've been doing, but to no avail. Hence, I wonder if it could be a problem with both of the PHP installations on my system (although the chances of both of them performing incorrectly the same way are remote). – JVE999 Nov 11 '13 at 23:38