Moving Form Data to SQL Table...with OOP

Hi,

I’ve been dabbling the past few days with some OOP with PHP. Just from a book I’ve got. Really enjoying the lack of typing involved, but my head’s getting sore at times :slight_smile:

I have a very basic script that I’d like to further develop. It’s a very simple Guestbook right now, which I’ll possibly extend into a Blog in the near future.

Right now it just validates the input, but I’d like to be able to 1) insert the data into a database and then 2) output the data to the user.

add_entry.php


<?php

require_once('validator.class.php');
$validate = new validator;

/* If Form Submitted */
if ($validate->validateIf(isset($_POST['submit']))) {

  /* Validate and Filter Input */
	$validate->length('name', $_POST['name'], 3, 30, 'Your name must be between 3 and 30 characters');	
	$validate->email('email', $_POST['email'], 'Enter a valid email address');
	$validate->length('comments', $_POST['comments'], 3, 500, 'Your comments must be between 3 and 500 characters');	
	
	if ($validate->hasErrors()) {
		$error = $validate->getError();
	} else {
	
  // Clean HTML & Escape SQL for DB Insertion
  
  
  // Escape Output and Send Result to Page
  
    
  }
	
} else {
	// Post not submitted
}

require_once('form.tpl');

?>

form.tpl


<form method="POST" action="add_entry.php">
	<fieldset>
	
  <?php if (isset($error)): ?><p id="error"><?php echo $error ?></p><?php endif; ?>

		<div><label for="name">Name:</label><input type="text" name="name" value="<?php echo $validate->getSafeData('name') ?>" /></div>
		<div><label for="email">Email:</label><input type="text" name="email" value="<?php echo $validate->getSafeData('email') ?>" /></div>
		<div><label for="comments">Comments:</label><textarea name="comments"><?php echo $validate->getSafeData('comments') ?></textarea></div>      
		<div><input type="submit" value="submit" name="submit" /></div>
		
	</fieldset>
</form>

validator.class.php


<?php

class Validator {

var $errors, $data, $doValidation;

// Validate against a value
function equals($label, $data, $must_equal, $case_sensitive, $error) {

  $this->setData($label, $data);
  
  if (!$case_sensitive) {
  $data = strtolower($data);
  $must_equal = strtolower($must_equal);
  }
  
  if ($data != $must_equal)
  $this->setError($label, $error);
  
  return true;

}

// Validate length
function length($label, $data, $min, $max, $error) {

  $this->setData($label, $data);
  
  $length = strlen($data);
  
  if ($min && ($length < $min) || $max && ($length > $max))
  $this->setError($label, $error);
  
  return true;

}

// Validate integer
function integer($label, $data, $error) {

  $this->setData($label, $data);
  
  if ((int)$data."" !== $data."")
  $this->setError($label, $error);
  
  return true;

}

// Validate range
function range($label, $data, $min, $max, $error) {

  $this->setData($label, $data);
  
  if ($data < $min || $data > $max)
  $this->setError($label, $error);
  
  return true;

}

function email($label, $email, $error) {

  $this->setData($label, $email);
  
  if (!preg_match('~[a-z.-_]+@[a-z.-_]+\\.[a-z.]{2,}~i', $email))
  $this->setError($label, $error);
  
  return true;

}

function getData($label) {
  return $this->doValidation ? htmlentities($this->data[$label], ENT_QUOTES) : '';
}

function getSafeData($label) {
  return $this->doValidation ? $this->data[$label] : '';
}

function hasErrors() {
  return count($this->errors);
}

// Set error and return false
function setError($label, $error) {

  if (!$error)
    die(sprintf('You must supply an error for: %s', $label));
    
    $this->errors[$label] = $error;
    
    return false;
  
  }

  function getError($label='') {
    return $label != '' ? $this->errors[$label] : reset($this->errors);
  }
  
  function getErrors() {
    return $this->errors;
  }
  
  // Set data
  function setData($label, $data) {
    $this->data[$label] = $data;
  }
  
  // Only perform validation if condition is met
  function validateIf($if) {
    return $if ? $this->doValidation = true : $this->doValidation = false;
  }

}

?>

Could someone possibly give me some pointers on how I should proceed?

Should I create a DB class for any sort of database interactions, and use a function in this to both clean & move my data to the database?

Some code examples would be greatly appreciated. Very new to OOP, so any help is brilliant.

Many thanks for any suggestions.

seems like book left you in the middle :smiley:
i am surprised to see even now book published now doesnt cover full oop …and writing code in procedural styel where as whole application creaters has move to it…
i am also victim of that late mover to OOP for which i am paying the price now…
any way gald i did ,finally
any way for your answer
have a look at it

append these to your code…
you can definately get what you want from there,if u play wit it for sometime…

Yep, late mover to OOP here. I’ve been trying to clean up my procedural code and I’m at a position now where I’d like to try more OOP.
It’s not essential for my work, but just want to keep learning :slight_smile:

Many thanks for the link.

I will play about with this, and may have to post back(if it’s ok) if I get stuck.

Thanks again.

It looks like your doing too much in that ‘page controller’ to me, of course, I’m probably wrong.

I’d be happier to see something more along these lines…


if($validator->validates($_POST)){
    #saves, then returns user information
    $user = $mapper->save('users', $_POST);
    #load template, assign data, renders
    $template->load('user.register.success.tpl')->assign('username', $user->username)->render();
}else{
    #load template, assign data, renders
    $template->load('user.register.failure')->assign('registration.errors', $validator->getErrors())->render();
}

Hey Anthony,

Do you think that level of validation is too much?

Thanks for the example too. Will have a good think of where I go from here.

Nah, the more validation the better I’d say. However, I’d probably break it down somewhat into smaller, composable and more importantly, resuable objects.


interface IValidate
{
    public function validates($subject);
}

class RegExpValidator implements IValidate
{
    protected
        $pattern;
    
    public function __construct($pattern){
        $this->pattern = $pattern;
    }
    
    public function validate($subject){
        return 1 === preg_match($this->pattern, $subject);
    }
}

class UsernameValidator extends RegExpValidator
{
    public function __construct($pattern = '~[a-z0-9]{6,10}~i'){
        parent::__construct($pattern);
    }
}

So in the end, I’d have a NewUserValidator which is essentially a collection of all our mini ones.

StringLength validator, NotEmpty validator etc etc…

:slight_smile:

Let your templete manage the concerns for outputting/escaping the data too, your controller just ‘controls’ the flow of the application, it doesn’t actually do any escaping (view, sql or otherwise).

Let the other components do this.

Brilliant Anthony, as usual :slight_smile:
Going to take a look over this at lunchtime, try get my head around it.
Think I just need to find a way of doing things in OOP and sticking with it.

Thanks again.

Good luck dude. :wink:

plus i would recommend you looking into validation of some framework like cakephp…
(it is not like step wise you learn oop way and then learn frameworks…you can learn oop through framework and your way of doing things will change a lot after seeing the way those frameworks do it…)

and i think you will copy paste to try the things
small typos here


class RegExpValidator implements IValidate{    
protected        $pattern;        
public function __construct($pattern){      
  $this->pattern = $pattern;    }       
 public function validate($subject){       
 return 1 === preg_match($this->pattern, $subject);    }}

from my understanding & knowledge that
public function validate
should be
public function validates
and interface was designed so…