1

I've been looking for a way to carry over the variable id from index.php to (amongst others) update-check.php. Initially this caused endless loadtime – i.e. the page waited forever on localhost. I narrowed it down to be session_start(); causing this error. If I remove session_start(); and replace 'stories/'. $_SESSION['id'] .'.txt'; with the actual id variable (like 'stories/film.txt';), there's no trouble loading whatsoever – besides the fact that I need that variable in place.

I've also noticed that I sometimes get Failed to load resource: net::ERR_CACHE_MISS in the console.

I've tried to tinker around and find why this occurs and how to solve it, but my brain hurts and I was hoping someone with more experience in these kind of situations will be able to provide some assistance in this bughunt (It's worth mentioning that I'm not that used to working with PHP or backend, coming from frontend as a designer).

EDIT – so the problem lies not in the PHP but this script Would it be possible to adapt this script to play nice while maintaining functionality?

/**
 * AJAX long-polling
 *
 * 1. sends a request to the server (without a timestamp parameter)
 * 2. waits for an answer from server.php (which can take forever)
 * 3. if server.php responds (whenever), put data_from_file into #response
 * 4. and call the function again
 *
 * @param timestamp
 */
function getContent(timestamp)
{
    var queryString = {'timestamp' : timestamp};

    $.ajax(
        {
        type: 'GET',
        url: 'update-check.php',
        data: queryString,
        success: function(data){
            // put result data into "obj"
            var obj = jQuery.parseJSON(data);
            // put the data_from_file into #response
            $('#response').html(obj.data_from_file);
            // call the function again, this time with the timestamp we just got from server.php
            getContent(obj.timestamp);
                //timeout to avoid endless loading? didn't make a difference
                timeout: 3000 // sets timeout to 3 seconds

            }
        }
    );
}

// initialize jQuery
$(function() {
    getContent();
});

update-check.php

<?php
session_start();


/**
 * Server-side file.
 * This file is an infinitive loop. Seriously.
 * It gets the file data.txt's last-changed timestamp, checks if this is larger than the timestamp of the
 * AJAX-submitted timestamp (time of last ajax request), and if so, it sends back a JSON with the data from
 * data.txt (and a timestamp). If not, it waits for one seconds and then start the next while step.
 *
 * Note: This returns a JSON, containing the content of data.txt and the timestamp of the last data.txt change.
 * This timestamp is used by the client's JavaScript for the next request, so THIS server-side script here only
 * serves new content after the last file change. Sounds weird, but try it out, you'll get into it really fast!
 */

// set php runtime to unlimited
set_time_limit(0);

/* $data_source_file = 'stories/film.txt'; */
$data_source_file = 'stories/'. $_SESSION['id'] .'.txt';

// main loop
while (true) {

    // if ajax request has send a timestamp, then $last_ajax_call = timestamp, else $last_ajax_call = null
    $last_ajax_call = isset($_GET['timestamp']) ? (int)$_GET['timestamp'] : null;

    // PHP caches file data, like requesting the size of a file, by default. clearstatcache() clears that cache
    clearstatcache();
    // get timestamp of when file has been changed the last time
    $last_change_in_data_file = filemtime($data_source_file);

    // if no timestamp delivered via ajax or data.txt has been changed SINCE last ajax timestamp
    if ($last_ajax_call == null || $last_change_in_data_file > $last_ajax_call) {

        // get content of data.txt
        $data = file_get_contents($data_source_file);

        // put data.txt's content and timestamp of last data.txt change into array
        $result = array(
            'data_from_file' => $data,
            'timestamp' => $last_change_in_data_file
        );

        // encode to JSON, render the result (for AJAX)
        $json = json_encode($result);
        echo $json;

        // leave this loop step
        break;

    } else {
        // wait for 1 sec (not very sexy as this blocks the PHP/Apache process, but that's how it goes)
        sleep( 1 );
        continue;
    }
}
Lenny
  • 446
  • 5
  • 21
  • 1
    If this is on Linux, it could be because there the process does not have privileges/permission to create a session file, usually in `/tmp`. – wallyk Jan 27 '15 at 01:26
  • 1
    Is this used in ajax? Note that a session is blocked by the script when you open it so when another script tries to access the same session (simultaneous ajax scripts for example) only one will work and the others will have to wait until it is finished. – jeroen Jan 27 '15 at 01:30
  • @wallyk I'm running it local on my MacBook don't know if that counts as Linux, but I've checked the folders permissions and they seem ok. If I need to, how do I check session file privileges? – Lenny Jan 27 '15 at 01:31
  • @jeroen It is, though I only have a single ajax script. Is there a way to detect simultaneous scripts? – Lenny Jan 27 '15 at 01:42
  • You could check the console – jeroen Jan 27 '15 at 01:43
  • @jeroen Right, I've added the console output (Failed to load resource: net::ERR_CACHE_MISS) to the question now. – Lenny Jan 27 '15 at 01:44
  • @jeroen I found that the script polling for data (see above) causes trouble. Is there a way to work around this, with a timer/timeout of sorts by any chance? – Lenny Jan 27 '15 at 01:52
  • How are you doing it now? You should set a timeOut in the success function of your ajax call opposed to using an interval. – jeroen Jan 27 '15 at 01:55
  • @jeroen You can see for yourself here above. I just updated to include the timeOut, but it didn't solve my problem. What else I should try next? – Lenny Jan 27 '15 at 02:01
  • 1
    `while (true) { ... }` is always just plain asking for trouble. –  Jan 27 '15 at 02:02
  • @holodoc fair enough, what would you recommend to use instead? – Lenny Jan 27 '15 at 02:09
  • I'm going to go with what @jeroen said. Whether you expect it or not, > 1 request is piling on and if you don't time out on the Nth, the N+1th one is going to block until then (from session-start to session-close). If you want this to work you'll need to cancel the Nth before the N+1th. You could also avoid sessions for all but the Nth call and guarantee you set a cookie for N+1th. – Jaimie Sirovich Jan 27 '15 at 04:09
  • You could also keep only what you need within the session-start to session-close and I believe PHP will release the lock, but that may not work for you. – Jaimie Sirovich Jan 27 '15 at 04:12
  • Thank you all for your input on my question. I've made some changes to my code and ended up setting a cookie for `id` in order to carry it over to update-check.php. – Lenny Jan 27 '15 at 17:29

1 Answers1

0

I ended up using setcookie("currentID", $id, time()+3600); instead of passing the variable through AJAX. Might not be the recommended path to follow, but it works fine for what I need it to do.

Lenny
  • 446
  • 5
  • 21