Barebones PHP survey framework with zero client and server side dependencies.
Multi-page, branching survey framework that doesn't require JavaScript nor cookies client-side, and also doesn't need sessions or an SQL back-end server-side.
At each page, hidden form variables persist answers previously given, until the form is completed where results are saved sequentially in a plain CSV file.
See the included example pages and the NanoSurvey class' documentation below for usage.
You can just include NanoSurvey.php
directly in your project or use
Composer:
$ composer require vphantom/nanosurvey
Instantiate the NanoSurvey
class, which will process $_REQUEST
's a
, p
and x
CGI variables to situate itself. Invoke page()
to display the current page inside a <form>
block.
<?php
// Manual
require_once 'NanoSurvey.php';
// Composer
require_once __DIR__ . '/vendor/autoload.php';
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Survey</title>
</head>
<body>
<h1>Survey</h1>
<?php
$survey = new NanoSurvey('/tmp/answers.csv');
echo $survey->page();
?>
</body>
</html>
NanoSurvey class
Initialize a survey
The first CSV column is the timestamp when the responses are saved, the rest are each response in order.
If $savePartial is set true, each time a participant submits a page, a new CSV line is appended with all answers obtained so far. In this mode, 2 extra columns are prepended after the timestamp: a unique participant ID and a page number. This makes it easy to keep only the most complete response from each participant, including those who did not reach the end of the survey.
If $savePartial is omitted or false, only complete surveys will be saved.
Parameters:
$filename
— string — Path and name for the CSV results file$savePartial
— bool|null — Save incomplete rows during progress
Get previous answer, if one was given
Answers count from 1, radios share the same ID, other types increment it each time.
The safest way to refer to a previous page's answer is to build those pages first and view their HTML source client-side.
Parameters:
$id
— int — Serial number of the previous answer
Returns: mixed
— Contents of answer
Save current progress in hidden FORM variables
Returns: string
— HTML with hidden inputs
Begin a new question
Initializes internal data. Every question MUST start with a call to this function.
Parameters:
$type
— string — Normal by default, specify 'radio' for a radio group
Returns: void
End current question
Finalizes internal data. Every question MUST end with a call to this function.
Returns: void
Radio (one of many) checkbox
Parameters:
$value
— mixed — Internal value to save if box is checked$default
— bool|null — Set true to make this the default input
Returns: string
— HTML checkbox
Checkbox (multiple possible)
Parameters:
$value
— mixed — Internal value to save if box is checked
Returns: string
— HTML checkbox
Single line text input box
Parameters:
$placeholder
— string|null — Text to display inside box when it is empty$size
— int|null — How many characters wide the input should be?
Returns: string
— HTML input box
Select one within many
Differs from radio buttons in that a single drop-down is displayed.
Returns: string
— HTML select initialization
Close select one within many
If optional arguments $first and $last are specified, numeric options are automatically created and appended for each possibility. You may still wish to create one "none selected" option with an empty value if you'd like before calling this.
Parameters:
$first
— int|null — First option$last
— int|null — Last option (max: $first + 500)
Returns: string
— HTML select finalization
Placeholder answer
When only a specific question or answer choice should be skipped conditionally, instead of an entire page, display these placeholders where the skipped answers would've been. This preserves the integrity of the answer count at all times.
Returns: string
— HTML hidden input
Create submit button for next page
Parameters:
$label
— string — HTML content of button (Default: "Continue")
Returns: string
— HTML
Display the current/next page
Pages are expected to be sequential, from "page-0.inc", "page-1.inc", etc. until the final page which invokes endSurvey().
Variable $survey is available in these pages, representing $this instance of NanoSurvey.
Returns: string
— HTML of the page
Skip the current page, display next one instead
If, in a page, you assess that it should be skipped (i.e. based on prior answers), call this method.
Returns: void
Terminate survey, saving to CSV if necessary
Returns: void
MIT License
Copyright (c) 2017 Stéphane Lavergne https://github.com/vphantom
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.