views:

466

answers:

6

I have a small application in which i have 9 different forms, and every form have a least 40+ fields where the user must enter some data.

I have written each form in a single php file and made a master PHP file where i only add the form in the middle of the page.

My question is:

I don't want to write 9 different function for each form coz it would be too long and i don't think it's the best practice, so is there a way or idea that can help me make a general function in which i can pass some variables to and add the data to the db.

Can i like iterate through the $_POST array and extarct the data and reformat it somehow? but then again every field have a different name and i seems like this is impossible to do.

+1  A: 

You might be interested in something like Zend_Form.

VolkerK
thanx for is there anyother way? i'm not very familiar with ZF and i started reading about it just a few days ago.
Thamood
A: 

Just 2 small thoughts..

1) Do you show all 9 forms in one page? If yes - I reeeally don't think it's a good idea.
2) Why don't you divide your forms to different pages and give same names to fields on your forms where it is possible?

nightcoder
no, each form is displayed on the separate page, i only want to make a general function for adding data without having to repeating code
Thamood
A: 

You can iterate on the $_POST array with a foreach.

   foreach($_POST as $name => $value) {
      echo $name, ' ', $value, '<br />';
   }
SleepyCod
While you can do this, it's a really dangerous way to write SQL queries.
acrosman
@acrosmanYou can store potentially harmful data inside your database but you have to be careful when you display it back on your website.
SleepyCod
+1  A: 

I've used something similar in one of my projects. Basically, I define all the fields, including how to display them, what data type they have (number, date, etc), as well as what to do with them once posted back. Then you pass that information to one function which generates a HTML form. When that form is submitted, you pass the same information to a different function which performs the necessary tasks.

In my specific case, it was just used to create search forms, so the processing involved creating a SELECT sql statement. Here's a sample of one of the field definitions:

$criteria = array(
    array("label" => "Search clients",
          "type"  => "radio",
          "values"=> array("1" => "Just " . $client->getName(),
                           "2" => "All clients"),
          "where" => array("1" => "c.`clientId` = " . $client->getId(),
                           "2" => "1"), // always true
          "default" => "1"),
    array("label" => "Last Name",
          "type"  => "text",
          "where" => "s.`lastName` LIKE '%s'"),
    array("label" => "First Name",
          "type"  => "text",
          "where" => "s.`firstName` LIKE '%s'")
    // etc...
nickf
+1  A: 

Try this way:

<?php

abstract class FormData
{
    const BOOLEAN = 'bool';
    const INTEGER = 'int';
    const FLOAT = 'float';
    const STRING = 'string';
    protected $_types = array();

    public static function create($data)
    {
     $action = isset($data['action']) ? $data['action'] : '';
     switch ($action)
     {
      case 'form1': return new MyForm1($data);
      default: return null;
     }
     return null;
    }

    protected function loadPostVars($data)
    {
     foreach ($data AS $var=>$value)
     {
      $value = $this->convertVar($var, $value);
      if (!is_null($value) && property_exists($this, $var))
      {
       $this->$var = $value;
      }
     }
    }
    protected function convertVar($var, $value)
    {
     if (array_key_exists($var, $this->_types))
     {
      $type = $this->_types[$var];
      switch ($type)
      {
       case FormData::BOOLEAN: return (bool)(int)$value;
       case FormData::INTEGER: return (int)$value;
       case FormData::FLOAT: return (float)$value;
       case FormData::STRING: // drop down
       default:
        return myEscapeString($value);
      }
     }
     return null;
    }
}

class MyForm1 extends FormData 
{
    public $fld1;
    public $fld2;
    public $fld3;
    // etc...

    public function __construct($data)
    {
     $this->_types = array(
      'fld1' => FormData::INTEGER,
      'fld2' => FormData::STRING,
      'fld3' => FormData::BOOLEAN,
     );
     $this->loadPostVars($data);
    }
}

// And finally process your form data
// You should add hidden input 'action' to each form to identify the form
if ($form = FormData::create($_POST))
{
    echo $form->fld1, $form->fld2, $form->fld3;
}
else 
{
    exit('error: unknown action provided');
}

?>

This solution has to be improved - I've written it very fast. But I hope you'll catch the main idea. Hope this will help. Sure, in each form class you can add specific methods to process the request etc.

Jet
A: 
Nikolai Echternacht