[b]class.core.php[/b]
<?php
	class core {
		protected $errs;
		protected $msgs;
		
		/*
		* constructor
		*/
		public function __construct () {
			$this->errs = array ();
			$this->msgs = array ();
		}
		
		/*
		* setters
		*/
		public function set_err ($err) {
			array_push ($this->errs, $err);
		}

		public function set_msg ($msg) {
			array_push ($this->msgs, $msg);
		}
		
		/*
		* getters
		*/
		public function get_errs () {
			return $this->errs;
		}
		
		public function get_errs_html () {
			if ($this->has_errs ()) {
				$html = '<div class="errs">';
				foreach ($this->get_errs () as $err) {
					$html .= $err;
				}
				$html .= '</div>';
			}
			else {
				$html = '';
			}
			return $html;
		}

		public function get_msgs () {
			return $this->msgs;
		}
		
		public function get_msgs_html () {
			if ($this->has_msgs ()) {
				$html = '<div class="msgs">';
				foreach ($this->get_msgs () as $msg) {
					$html .= $msg;
				}
				$html .= '</div>';
			}
			else {
				$html = '';
			}
			return $html;
		}

		public function has_msgs () {
			return count ($this->msgs);
		}
		
		public function has_errs () {
			return count ($this->errs);
		}
	}
?>

[b]class.form.php[/b]
<?php
	class formelement extends core {
		private $id;
		private $name;
		private $type;
		private $value;
		private $required;
		private $html;

		public function __construct ($id, $name, $type, $value, $required = false) {
			parent::__construct ();
			$this->id = $id;
			$this->name = $name;
			$this->type = $type;
			$this->value = $value;
			$this->required = $required;
			$this->validate ();
		}
		
		public function get_html () {
			$required = ($this->required) ? ('* ') : ('');
			switch ($this->type) {
				case 'radio_array':
					$this->html .= PHP_EOL . '<fieldset>';
					$this->html .= PHP_EOL . '<legend>' . $required . $this->name . ':</legend>';
					foreach ($this->value as $key => $val) {
						$checked = '';
						if (isset ($_POST[$this->name])) {
							if (in_array ($key, $_POST[$this->name])) {
								$checked = ' checked="checked"';
							}
						}
						$this->html .= PHP_EOL . '<input id="' . $key . '" name="' . $this->name . '[]" type="radio" value="' . $key . '"' . $checked . ' class="col2" />';
						$this->html .= PHP_EOL . '<label for="' . $key . '">' . $val . '</label><br />';
					}
					$this->html .= PHP_EOL . '</fieldset>';
					break;
				case 'checkbox_array':
					$this->html .= PHP_EOL . '<fieldset>';
					$this->html .= PHP_EOL . '<legend>' . $required . $this->name . ':</legend>';
					foreach ($this->value as $key => $val) {
						$checked = '';
						if (isset ($_POST[$this->name])) {
							if (in_array ($key, $_POST[$this->name])) {
								$checked = ' checked="checked"';
							}
						}
						$this->html .= PHP_EOL . '<input id="' . $key . '" name="' . $this->name . '[]" type="checkbox" value="' . $key . '"' . $checked . ' class="col2" />';
						$this->html .= PHP_EOL . '<label for="' . $key . '">' . $val . '</label><br />';
					}
					$this->html .= PHP_EOL . '</fieldset>';
					break;
				case 'checkbox':
					$this->html .= PHP_EOL . '<p>';
					foreach ($this->value as $key => $val) {
						$checked = '';
						if (isset ($_POST[$this->name])) {
							$checked = ' checked="checked"';
						}
						$this->html .= PHP_EOL . '<input id="' . $key . '" name="' . $this->name . '" type="checkbox" value="' . $key . '"' . $checked . ' class="col2" />';
						$this->html .= PHP_EOL . '<label for="' . $key . '">' . $required . $val . '</label><br />';
					}
					$this->html .= PHP_EOL . '</p>';
					break;
				case 'select':
					$selection = (isset ($_POST[$this->name])) ? ($_POST[$this->name]) : ('');
					$this->html .= PHP_EOL . '<p>';
					$this->html .= PHP_EOL . '<label for="' . $this->id . '" class="floated">' . $required . $this->name . ':</label>';
					$this->html .= PHP_EOL . '<select id="' . $this->id . '" name="' . $this->name . '" class="medium">';
					$this->html .= PHP_EOL . '<option value=""> - selecteer een optie - </option>';
					foreach ($this->value as $key => $val) {
						$selected = ($selection == $key) ? (' selected="selected"') : ('');
						$this->html .= PHP_EOL . '<option' . $selected . ' value="' . $key . '">' . $val . '</option>';
					}
					$this->html .= '</select>';
					$this->html .= PHP_EOL . '</p>';
					break;
				case 'text':
					$this->html .= PHP_EOL . '<p>';
					$this->value = (isset ($_POST[$this->name])) ? (trim ($_POST[$this->name])) : ('');
					$this->html .= PHP_EOL . '<label for="' . $this->id . '" class="floated">' . $required . $this->name . ':</label>';
					$this->html .= PHP_EOL . '<input id="' . $this->id . '" name="' . $this->name . '" type="text" value="' . strip_tags ($this->value) . '" class="medium" />';
					$this->html .= PHP_EOL . '</p>';
					break;
				case 'textarea':
					$this->html .= PHP_EOL . '<p>';
					$this->value = (isset ($_POST[$this->name])) ? (trim ($_POST[$this->name])) : ('');
					$this->html .= PHP_EOL . '<label for="' . $this->id . '" class="floated">' . $required . $this->name . ':</label>';
					$this->html .= PHP_EOL . '<textarea id="' . $this->id . '" name="' . $this->name . '" rows="5" cols="20" class="large">' . strip_tags ($this->value) . '</textarea>';
					$this->html .= PHP_EOL . '</p>';
					break;
				case 'submit':
					$this->html .= PHP_EOL . '<p>';
					$this->html .= PHP_EOL . '<input type="submit" value="' . $this->value . '" class="col2" />';
					$this->html .= PHP_EOL . '</p>';
					break;
				default:
					$this->html .= 'Foutje in de switch';
					break;
			}
			return $this->html;
		}
		
		public function validate () {
			if ($this->required) {
				switch ($this->type) {
					case 'radio_array':
						if (!isset ($_POST[$this->name])) {
							$this->set_err ('Klik een optie bij <strong>&quot;' . $this->name . '&quot;</strong> aan');
						}
						break;
					case 'checkbox_array':
						if (!isset ($_POST[$this->name])) {
							$this->set_err ('Vink tenminste 1 van de opties bij <strong>&quot;' . $this->name . '&quot;</strong> aan');
						}
						break;
					case 'checkbox':
						if (!isset ($_POST[$this->name])) {
							$this->set_err ('Het veld <strong>&quot;' . $this->name . '&quot;</strong> moet aangevinkt zijn');
						}
						break;
					case 'select':
					case 'text':
						if (isset ($_POST[$this->name])) {
							$value = trim ($_POST[$this->name]);
							if (empty ($value)) {
								$this->set_err ('Het veld <strong>&quot;' . $this->name . '&quot;</strong> is verplicht');
							}
						}
						break;
					case 'textarea':
						break;
				}
			}
		}
		
		public function get_possible_values () {
			if (is_array ($this->value)) {
				return $this->value;
			}
			return false;
		}
	}
?>

[b]oopform.php[/b]
[code]
<?php
	ini_set ('display_errors', 1);
	error_reporting (E_ALL | E_STRICT);

	require 'classes/class.core.php';
	require 'classes/class.form.php';
	require 'oopform_business_logic.php';
	$title = 'Jan Koehoorn | OOP Form';
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>Jan Koehoorn | <?php echo $title; ?></title>
	
	<link rel="stylesheet" type="text/css" media="screen" href="reset.css" />
	<link rel="stylesheet" type="text/css" media="screen" href="oop.css" />
	<style type="text/css">
		form					{padding: 10px;}
		form p					{overflow: hidden; width: 100%; margin: 5px 0;}
		form p label.floated	{float: left; width: 100px; padding-right: 5px; text-align: right; cursor: pointer;}
		input.col2				{margin-left: 105px;}
		div.errs				{margin: 10px auto; width: 80%; padding: 0 10px; border: 2px solid red; background: #fcc;}
		div.errs h2				{color: #f00; margin: 0; padding: 0;}
		div.errs ol				{list-style-type: decimal; margin: 10px; padding: 0 10px; color: #000;}
		div.errs ol li			{color: #000;}
		fieldset				{border: 1px solid #ccc; margin: 0 10px; padding: 0 10px;}
		legend					{padding: 0 10px;}
		strong					{font-weight: bold;}
		.medium					{width: 200px;}
		.large					{width: 400px;}
	</style>
</head>

<body>
	<div id="container">
		<h1><?php echo $title; ?></h1>
		<?php
			echo $errs_html;
			echo $ok_html;
		?>
		<div id="form"<?php echo $form_style; ?>>
		<p>Vul onderstaand formulier in. Velden met een * zijn verplicht. HTML wordt gefilterd.</p>
		<form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
		<?php
			foreach ($formelements as $element) {
				echo $element->get_html ();
			}
		?>
		</form>
		</div>
	</div>
</body>
</html>
[/code]

[b]oopform_business_logic.php[/b]
<?php
	define ('REQUIRED', true);
	define ('NOT_REQUIRED', false);
	$errs = array ();
	$errs_html = '';
	$ok_html = '';
	$form_style = '';
	
	/*
		hier sleutel je eigenlijk je hele formulier in elkaar
		je prakt al je formulierelementen in deze array
		volgorde van de argumenten die je aan de constructor meegeeft:
		id, naam, type, value, verplicht_veld
		
		let op: bij type geef je:
		- 'checkbox_array' op voor een serie checkboxen. Bij value geef je dan een associatieve array op voor de values en de labelteksten
		- 'checkbox_array' op voor een serie checkboxen. Bij value zelfde verhaal als hierboven
		- 'select' op voor een selectbox. Bij value een associatieve array voor de values en de option-teksten
		
		bij een type 'submit' geef ik nooit een id en een name op, daarom zijn ze daar false
	*/
	$formelements = array (
		'naam' => new formelement ('naam', 'naam', 'text', '', REQUIRED),
		'adres' => new formelement ('adres', 'adres', 'text', '', NOT_REQUIRED),
		'woonplaats' => new formelement ('woonplaats', 'woonplaats', 'text', '', REQUIRED),
		'nieuwsbrief' => new formelement ('nieuwsbrief', 'nieuwsbrief', 'checkbox', array (
			'nieuwsbrief_ontvangen' => 'ik wil de nieuwsbrief ontvangen'
		), NOT_REQUIRED),
		'fruit' => new formelement ('fruit', 'fruit', 'select', array (
			'appel' => 'appel',
			'peer' => 'peer',
			'banaan' => 'banaan',
			'citroen' => 'citroen',
			'sinaasappel' => 'sinaasappel'
		), REQUIRED),
		'vechtsporten' => new formelement ('vechtsporten', 'vechtsporten', 'checkbox_array', array (
			'judo' => 'ik doe aan judo',
			'karate' => 'ik zit op karate',
			'kungfu' => 'ik beoefen kung fu'
		), REQUIRED),
		'geslacht' => new formelement ('geslacht', 'geslacht', 'radio_array', array (
			'man' => 'mannelijk',
			'vrouw' => 'vrouwelijk',
			'weetniet' => 'weet niet'
		), REQUIRED),
		'opmerkingen' => new formelement ('opmerkingen', 'opmerkingen', 'textarea', '', NOT_REQUIRED),
		'voorwaarden' => new formelement ('voorwaarden', 'voorwaarden', 'checkbox', array (
			'voorwaarden' => 'ik ben akkoord met <a href="oopform_voorwaarden.php" title="Lees de voorwaarden">de voorwaarden</a>'
		), REQUIRED),
		'verzenden' => new formelement (false, false, 'submit', 'verzenden')
	);
	if ($_SERVER['REQUEST_METHOD'] == 'POST') {
		// kijken of er met het form geklooid is
		foreach ($_POST as $key => $val) {
			if (!in_array ($key, array_keys ($formelements))) {
				array_push ($errs, 'Er is geklooid met de veldnamen van het formulier');
			}
			else {
				if (is_array ($formelements[$key]->get_possible_values ())) {
					if (is_array ($val)) {
						foreach ($val as $test) {
							if (!in_array ($test, array_keys ($formelements[$key]->get_possible_values ()))) {
								array_push ($errs, 'Er is geklooid met de veldwaarden van het formulier. De waarde <strong>' . $test . '</strong> mag niet voorkomen.');
							}
						}
					}
					else {
						if (!empty ($val) && !in_array ($val, array_keys ($formelements[$key]->get_possible_values ()))) {
							array_push ($errs, 'Er is geklooid met de veldwaarden van het formulier. De waarde <strong>' . $val . '</strong> mag niet voorkomen.');
						}
					}
				}
			}
		}
		foreach ($formelements as $element) {
			foreach ($element->get_errs () as $err) {
				array_push ($errs, $err);
			}
		}
		if (!empty ($errs)) {
			$errs_html = PHP_EOL . '<div class="errs">';
			$errs_html .= '<h2>Gevonden fouten:</h2>';
			$errs_html .= '<ol>';
			foreach ($errs as $err) {
				$errs_html .= '<li>' . $err . '</li>';
			}
			$errs_html .= '</ol></div>';
		}
		else {
			$form_style = ' style="display: none;"';
			$ok_html = PHP_EOL . '<div class="msgs">';
			$ok_html .= PHP_EOL . '<h2>Dankuwel voor het invullen van het formulier</h2>';
			$ok_html .= PHP_EOL . '<p>De volgende waarden zijn verzonden:</p>';
			$ok_html .= PHP_EOL . '<pre>' . htmlentities (print_r ($_POST, true)) . '</pre>';
			$ok_html .= PHP_EOL . '</div>';
		}
	}
?>

[b]oopform_voorwaarden.php[/b] (voor de volledigheid)
[code]<?php
	ini_set ('display_errors', 1);
	error_reporting (E_ALL);
	$title = 'Jan Koehoorn | OOP form voorwaarden';
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>Jan Koehoorn | <?php echo $title; ?></title>
	
	<link rel="stylesheet" type="text/css" media="screen" href="reset.css" />
	<link rel="stylesheet" type="text/css" media="screen" href="oop.css" />
</head>

<body>
	<div id="container">
		<h1><?php echo $title; ?></h1>
		<p>Hier de voorwaarden</p>
	</div>
</body>
</html>[/code]