0

Should I be using the __construct option to create a new record? Below is the class I have called 'Course'. I will only actually be "creating" a course 25% of the time, the rest of the time I'll want to lookup courses and what not.

class Course {
    private $db;

    function __construct($db, $data) {
        global $error, $mysqli;

        $this->db = $db;

        requireOrError($data['course_type_id'], "Course Type Required");
        requireOrError($data['instructor_id'], "Instructor Required");
        requireOrError($data['dz_name'], "DZ Name Required");
        requireOrError($data['dz_address'], "DZ Address Required");
        requireOrError($data['dz_city'], "DZ City Required");
        requireOrError($data['dz_state'], "DZ State Required");
        requireOrError($data['dz_zip'], "DZ Zip Required");
        requireOrError($data['dz_email'], "DZ Email Required");     
        requireOrError($data['start_date'], "Course Start Date Required");
        requireOrError($data['end_date'], "Course End Date Required");
        requireOrError($data['student_slots'], "Number Of Student Slots Required");

        if(! is_numeric($data['student_slots'])) {
            $error[] = "Invalid Student Slots - Must be a number";
        }

        setError($error);

        if(empty($error)) {
            $add = $mysqli->query("INSERT INTO " . $this->db['courses'] . " (course_type_id, instructor_id, dz_name, dz_address, dz_city, dz_state, dz_zip, dz_email, start_date, end_date, student_slots, notes) VALUES ('$data[course_type_id]', '$data[instructor_id]', '$data[dz_name]', '$data[dz_address]', '$data[dz_city]', '$data[dz_state]', '$data[dz_zip]', '$data[dz_email]', '$data[start_date]', '$data[end_date]', '$data[student_slots]', '$data[notes]')");
            redirectTo("instructors.php");
        }
    }
}

I was going to create a function called "getCourseInfo" where I could pass an ID and it'll return the course object. Is this the best way to do it, or, should I change the __construct behavior to create. Also, could you give me an example of how I would create/lookup?

Thanks!

1
  • That's far too busy for a constructor, and assumes you always want to insert a record. Why not simply have the constructor do some basic setup, then provide "createRecord" and "validateData" methods? Commented Jan 2, 2012 at 19:11

4 Answers 4

2

No. A constructors main purpose is to bring the newly created object into a stable state. It should never "do" anything.

Sign up to request clarification or add additional context in comments.

Comments

1

No. You should have a separate method to create a record that you either pass the parameters as function arguments, or as an array. For example:

<?php
class Course {

    protected $db;    

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

    public function fetchById($id) {
        // perform database query; look-up on ID
    }

    public function create($data) {
        // validate your $data
        // create your record
        // return either boolean true or the ID of the newly-created record
        // and errors, either return boolean false or throw an exception
    }
}

You can then use your class as follows:

<?php

// create PDO instance in $pdo variable

$course = new Course($pdo);

$data = array(
    'course_type_id' => $_POST['course_type_id'],
    'instructor_id'  => $_POST['instructor_id'],
    // and so on...
);

if ($course->create($data)) {
    echo 'Course created.';
}
else {
    echo 'Error creating course.';
}

Make sure to escape and sanitize any posted data.

Comments

1

I prefer to leave the creation functionality out of the constructor because it's purpose should be to establish the object's existence ... not to perform a bunch of tangential operations.

Further, you can implement method chaining by returning $this in your setter methods (which almost completely invalidates the faux "code shortening efficiency" gains from populating object properties in the constructor):

$obj = new Course;
$obj->setDb($db)->setData($data);

If you do implement a __construct() that allows you to shortcut the other object methods, you should at least define default values for the arguments. Allowing default NULL values will SIGNIFICANTLY improve the testability of your code.

So if you did pass arguments to the constructor it should look something like the below ... though you probably shouldn't:

class Course {

  private $db;

  private $data;

  function __construct($db=NULL, $data=NULL)
  {
    if ($db) {
      $this->setDb($db);
    }
    if ($data) {
      $this->setData($data);
    }
  }

  function setDb(DbConn $db)
  {
    $this->db = $db;
    return $this;
  }

  function setData($data)
  {
    if ($data !== (string)$data) {
      throw new InvalidArgumentException('data argument must be a string');
    }
    $this->data = $data;
    return $this;
  }
}

Comments

-1

Doing some operation in the constructor is good if the purpose of the class itself is the operation..in other words when anything is needed from that class that function, in your case insertion in database is needed...

So if the solo purpose of your class is to insert the data in the database then do it..else define a function for the same...:)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.