/php-mysql-save-data

Server-side script for writing jsPsych data to MySQL DB

Primary LanguagePHP

A set of PHP / JS functions for helping jsPsych communicate with a MySQL database. These scripts allow you to:

  1. Check if a subject has already started the experiment in a previous session.
  2. Assign the subject to a condition in a (somewhat) balanced manner.
  3. Save data to a MySQL database.

There are three PHP scripts, one for each of the above tasks, plus a PHP config file.

The JS file is a client side library for communicating with the PHP.

How to use this library

  1. Start by editing php/database_config.php. You will need to provide login information for an account with INSERT, SELECT, and SHOW privileges for each of the three tables, $table_register, $table_conditions, and $table_data. You can specify the names of these tables in the configuration file.

  2. Setup the MySQL tables. The PHP file expects three tables to be in the database.

$table_register needs to have the columns row, workerID, and completionCode.

  • row should be an auto incrementing primary key.
  • workerID is the unique ID associated with your subject, e.g., a Mechanical Turk workerID.
  • completionCode is a randomly generated set of letters that you can use as a survey completion code that is unique to that subject, if desired.

$table_conditions needs to have the columns row, subjectID, and assignedCondition.

  • row should be an auto incrementing primary key.
  • subjectID is an ID that you generate, e.g., using jsPsych.randomization.randomID(). You can use a Mechanical Turk workerID, but be aware that such IDs are not anonymous and that this could potentially create confidentiality problems.
  • assignedCondition will be an integer, generated by the server, indicating the condition assignment. If you have a design with multiple factors, then you need to convert this single integer to the appropriate level for each cell. For example, in a 2x2 design, assignedCondition could be 0, 1, 2, or 3. You should convert these 4 values to the 4 different cells in the 2x2.

$table_data needs to have a column for each variable that you want to save from your jsPsych experiment. You can run the command jsPsych.data.get().uniqueNames() after the experiment has completed to get a list of all the different variables that jsPsych is capturing in your experiment.

  1. Upload the js and php files onto the server, in the same directory as your experiment files.

  2. Import the serverComm.js file into your jsPsych experiment.

<script src="js/serverComm.js" type="text/javascript"></script>
  1. This library allows you to perform three different actions. You can register/exclude subjects, assign subjects to a condition, and save data. You can choose to use any of the features independently. My typical workflow is to register a subject and check if they have completed the experiment (excluding them if they have), then assign them to a condition, and finally save data at the end of the experiment.

  2. To register/exclude subjects, use the function serverComm.register_subject(). This function takes a unique permanent identifier for the subject (e.g., a Mechanical Turk Worker ID), and checks to see if there is already a copy of that ID in the database. If there is, the function callback_exclude() is executed. If there is not, then the WorkerID is added and callback_success is called. If there are any technical problems along the way (e.g., can't establish a database connection), callback_failure() is executed. An example is shown below.

// this is an example of how you could extract the unique ID from the URL:
var id = jsPsych.data.getURLVariable('prolific_pid');

serverComm.register_subject(id,
  function(){ // this is the success callback. the function executes if the subject has a unique id
    continue_success();
  },
  function(){ // this is the excluded callback. show excluded message.
    document.querySelector('body').innerHTML = '<p>Our records indicate that you have already started this experiment. Due to the nature of the experiment, restarting is not permitted.</p><p>If you believe this message is in error, you can contact the researchers at jdeleeuw@vassar.edu. Our apologies for the trouble.</p>';
  },
  function(){ // this is the failure callback. show technical error message.
    document.querySelector('body').innerHTML = '<p>Our apologies. There was a technical error on our end while loading the experiment.</p><p>You will not be able to complete the experiment. We are sorry for the trouble.</p>';
  }
);
  1. To assign subjects to a condition, use the function serverComm.assign_condition(). This function takes a subject ID and the number of unique conditions in the experiment. I recommend not using the ID used for registering the subject because permanent IDs like Mechanical Turk worker IDs can lead to personally identifying information. Instead, I typically generate a random ID using the function jsPsych.randomization.randomID(). The function will execute the callback_success(response) function in the absence of technical failure, passing in the assigned condition as response.assignedCondition. The script assigns conditions incrementally from 0 to n-1, where n is the number of unique conditions. If the previous subject had condition n-1, then the next subject will be assigned to condition 0. This sequential assignment of conditions is useful for experiments where an even distribution of subjects is desired and most subjects will complete the experiment in parallel, preventing the assignment of conditions based on the number of completed subjects in each condition. An example is shown below.
var subject_id = jsPsych.randomization.randomID(20);
var assigned_condition = null;
var n_conditions = 3;

serverComm.assign_condition(subject_id, n_conditions,
  function(response){
    assigned_condition = response.assignedCondition;
    start_experiment();
  },
  function(){
    document.querySelector('body').innerHTML = '<p>Our apologies. There was a technical error on our end while loading the experiment.</p><p>You will not be able to complete the experiment. We are sorry for the trouble.</p>';
  }
);
  1. To save data, use the function serverComm.save_data(). This function takes an array of JavaScript objects to write to the database. jsPsych generates an array of objects where each object is a trial. An example is shown below using the call-function plugin to insert a trial that will save data. I prefer this pattern as opposed to using the on_finish callback because it allows me to save the data before the final screen of the experiment, preventing accidental data loss when participants close the experiment at the final screen instead of finishing the experiment by clearing the final screen.
var save = {
  type: 'call-function',
  func: function(){
    serverComm.save_data(jsPsych.data.get().values());
  }
}
timeline.push(save);