【问题标题】:PHP OOP: Using Construct To Create New RecordPHP OOP:使用构造创建新记录
【发布时间】:2012-01-02 19:10:17
【问题描述】:

我应该使用 __construct 选项来创建新记录吗?下面是我称之为“课程”的课程。我实际上只会在 25% 的时间里“创建”一门课程,其余时间我会想查找课程等等。

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");
        }
    }
}

我打算创建一个名为“getCourseInfo”的函数,我可以在其中传递一个 ID,它会返回课程对象。这是最好的方法吗,或者,我应该改变 __construct 行为来创建。另外,你能给我一个如何创建/查找的例子吗?

谢谢!

【问题讨论】:

  • 对于构造函数来说太忙了,并且假设您总是想插入一条记录。为什么不简单地让构造函数做一些基本的设置,然后提供“createRecord”和“validateData”方法?

标签: php


【解决方案1】:

没有。构造函数的主要目的是使新创建的对象进入稳定状态。它应该从不“做”任何事情。

【讨论】:

    【解决方案2】:

    没有。您应该有一个单独的方法来创建记录,您可以将参数作为函数参数或作为数组传递。例如:

    <?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
        }
    }
    

    然后您可以按如下方式使用您的课程:

    <?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.';
    }
    

    确保对所有发布的数据进行转义和清理。

    【讨论】:

      【解决方案3】:

      我更喜欢将创建功能留在构造函数之外,因为它的目的应该是确定对象的存在......而不是执行一堆切线操作。

      此外,您可以通过在 setter 方法中返回 $this 来实现方法链接(这几乎完全抵消了在构造函数中填充对象属性所获得的虚假“代码缩短效率”):

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

      如果你确实实现了一个__construct(),它允许你使用其他对象方法的快捷方式,你至少应该为参数定义默认值。允许默认 NULL 值将显着提高代码的可测试性。

      因此,如果您确实将参数传递给构造函数,它应该如下所示......尽管您可能不应该

      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;
        }
      }
      

      【讨论】:

        【解决方案4】:

        如果类本身的目的是操作,则在构造函数中执行一些操作是好的。换句话说,当该类需要该函数的任何内容时,在您的情况下需要插入数据库中...

        因此,如果您的课程的唯一目的是在数据库中插入数据,那么请执行此操作..否则为相同的定义一个函数...:)

        【讨论】:

          猜你喜欢
          • 2018-10-02
          • 1970-01-01
          • 1970-01-01
          • 2012-05-09
          • 2021-08-19
          • 2021-11-15
          • 1970-01-01
          • 1970-01-01
          • 2013-12-16
          相关资源
          最近更新 更多