Array or object for this purpose?

I’ve developed a survey generator. The user describes the survey in a text file, and my application creates and processes the HTML form for that particular survey. There are several types of survey questions. One type asks a question and lets survey participants select multiple answers, while another lets participants select only one answer from the possibilities provided. Yet another type asks a series of questions, providing a scale of this-to-that answers for all the questions (for example, rate your satisfaction on a 1 to 5 scale).

For this application, I was seduced by PHP’s parse_ini_file() function, which easily took the text file and turned it into an array. Here’s a basic sample text file that describes a survey.

; Sample Survey

[section_1]
type = 1
questions[] = "What size Coke do you prefer?"
questions[] = "What size popcorn do you prefer?"
questions[] = "What size candy bar do you prefer?"
questions[] = "What size T-Shirt do you wear?"
answers[] = "S"
answers[] = "M"
answers[] = "L"

[section_2]
type = 2
questions[] = "What kind of car do you drive?"
answers[] = "I don't drive"
answers[] = "Honda"
answers[] = "Toyota"
answers[] = "Ford"
answers[] = "General Motors"
answers[] = "Other"

[section_3]
type = 3
questions[] = "Things you like about your job"
answers[] = "Short commute"
answers[] = "Good supervisor"
answers[] = "Fulfilling"
answers[] = "Fun environment"
answers[] = "Pays well"
answers[] = "I don't like my job"

Of course, a particular survey can have any number of questions of various types, and further, other types of questions could be added (for example, free text questions or conditional questions), so I’m wondering if it might not be better to create a survey object composed of question objects. This would mean that each question type would have its own class, an instance of which would be created as needed when the survey description file is parsed.

Unfortunately, PHP has no function that parses structured text into objects, so this would require writing a parser. But might it be worth it? I’m thinking of an architecture open enough that other people could create their own “driver” files, class files describing and processing survey question types of their own invention.

I realize this is not a specific question but an invitation to brainstorm. I appreciate any insight you have.

Could you do something with serialize and unserialize? http://php.net/manual/en/function.serialize.php

Or maybe use something like JSON encoding or even XML to store the survey details so it can be parsed?

1 Like

First, don’t make objects just for the sake of making objects. But if you can really use different question type classes then consider reading though the Symfony serializer documentation: http://symfony.com/doc/current/components/serializer.html

The component is designed to do exactly what you described while giving you a choice of different file formats.

Even if you decide not to use the component, the documentation is well worth the time spent reading it.

1 Like

First, don’t make objects just for the sake of making objects.

That’s excellent advice, thank you. I’ve heard of Symfony. I’ll look into it.

Yes, I actually do serialize and unserialize the array to persist it between submits. I’ll probably use XML. A pity, though, since the *.INI format was so easily understood by non-technical people. A 70-year-old professor of philosophy who uses my survey generator understood it almost immediately. Thanks!

So idea is basically having a PHP file defining one or more classes for new question types, each implementing a certain interface, providing public functions like getHTML() and the like? A parser for this might look simpler than you’d probably think. :-) Like

// ; sample section
// 
// [section_1]
// type = 'Choice'
// questions[] = "What size Coke do you prefer?"
// questions[] = "What size popcorn do you prefer?"
// questions[] = "What size candy bar do you prefer?"
// questions[] = "What size T-Shirt do you wear?"
// answers[] = "S"
// answers[] = "M"
// answers[] = "L"


interface Question {
  public function getHTML();
}

// Sample class
class Choice implements Question {

  private $details;

  public function __construct($details) {
    $this->details = $details;
  }

  // This function must be implemented
  public function getHTML() {

    // Render $this->details here in a more
    // appropriate way ;-)
    return var_export($this->details, true);
  }
}

// The parser
$survey = parse_ini_file('survey.ini', true);
$questions = [];

foreach ($survey as $question) {
  
  if (class_exists($question['type']) &&
    in_array('Question', class_implements($question['type']))) {

    // Create a new object of the class given by the question type,
    // passing details like answers etc.
    $questions[] = new $question['type']($question);
  }
}

// Then, later
foreach ($questions as $question) {
  echo $question->getHTML();
}

This would be agnostic of how specific question types will be handled or what kind of additional parameters you might want to pass to them; questions types which are not implemented will simply be ignored.

1 Like

The component I linked to allows you to plug in your own file processor. So you could stay with the ini format if you so chose. Just a bit more code.

Wow, thank you so much! That’s definitely a copy-and-save. I had seen interface examples before, but they were hypothetical and I didn’t understand them.

1 Like

That’s good to know. I’ve been using CodeIgniter. I should give Symfony a look.

Keep in mind that the serializer component I posted to does not require any specific framework. Components are more or less independent chunks of code. If CodeIgniter is doing the job for you then there is no need to change just to use this component.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.