【问题标题】:Returning database row as an object - is this a good way to do it?将数据库行作为对象返回 - 这是一个好方法吗?
【发布时间】:2014-08-01 03:09:03
【问题描述】:

我正在用 PHP 构建一个 Web 应用程序。通常,对象将与数据库中的特定行相关。我想编写一些类来允许操作这些行。以这个为例:

编辑:我认为这总结了我正在尝试做的事情,只是在 PHP http://martinfowler.com/eaaCatalog/dataMapper.html 中寻找一个实际的例子@

// Create a new company record in the database
$data = array(
    'name' => 'My Test Company';
);
try {
    $companyId = Company_Common::create($data);
} catch (Exception $e) {
    exit('Error: ' . $e->getMessage() . "\n");
}

// Load the record from the database
try {
    $company = new Company($companyId);
} catch (Exception $e) {
    exit('Error: ' . $e->getMessage() . "\n");
}

// Rename the company
$company->name = 'Company Name New';
$company->save();


class Company_Common {

    function create($data) {
        // add code here to check required fields, insert company record into database, then return row id
    }

}

class Company {

    public function __construct($id) {
        // add code here to load database row from company table based on id
        // throw exception if id not found in database table
        if (mysql_num_rows($result) < 1) { // something like this depending on database
            throw new Exception('Company Not Found');
        }
        // dynamically set properties from database row
        $row = mysql_fetch_assoc($result);
        foreach($row as $key => $value) {
            $this->{$key} = $value;
            $this->original->{$key} = $value;
        }

    }

    function save() {
        // load another copy from database
        $original = new Company($this->id);
        // add code here to compare $this with $original, build update query, and update any fields that have changed
    }

    function delete() {
        // add code here to delete company record from database
    }

}

除此之外,上面的类将包括 getContactIds 之类的函数,它会根据公司 ID 从联系人表中检索一堆行 ID。

我真的只是在获得一些关于其他人对这种方法的看法的反馈,以及应该或可以以不同的方式/更有效地做些什么。谢谢。

【问题讨论】:

  • 你可以使用 PDO_FETCH_OBJ
  • 您应该考虑停止使用已弃用的 mysql_* 函数,特别是因为与 mysql 相比,PDO 提供了如此多的乐趣。还有更多的oop

标签: php oop


【解决方案1】:

我个人更喜欢创建一个显式的函数调用来从数据库中提取数据,而不是将其放入构造函数中。这允许我创建类的虚拟实例以用于测试和模拟目的。一般类可能如下所示:

class Car {
     // optionally prevent cars from being instantiated any other way
     private function __construct() {}

    // get car from db
    public static function find($id) {
        // your db stuff here
        $data = $db->where('id', $id)->get();
        return self::make($data);     
    }

    // mock car - create instance and return with data
    public static function make(array $data) {
         $instance = new self();
         return $instance->fill($data);
    }

    // set the provided data to the model
    private function fill(array $data) {
         $this->make = isset($data['make']) ? $data['make'] : false;
         $this->model = isset($data['model']) ? $data['model'] : false;
         return $this;
    }

    public function save() {
        // save to db
    }

}

用法如下:

// car with data from db
$car = Car::find(1);


// car with data from input    
$make = $_GET['make'];
$model = $_GET['model'];

$car = Car::make(array('make' => $make, 'model' => $model));
$car->save();



// car with no data
$car = Car::make(array());

这里的主要好处是您可以为单元测试创​​建模拟对象,并且可以使用来自 db 以外的源的数据创建模型

【讨论】:

    【解决方案2】:

    了解PDO

    为此,我喜欢使用PDO::FETCH_CLASS,因为它可以提供很酷的功能。考虑这个类:

    class myClass
     {private $foo,$bar;}
    

    假设我有一个包含字段 foo 和 bar 的表,我想用这些字段实例化此类的一个对象。我会这样做:

    $stmt = $db->prepare( "SELECT foo,bar,'magic' as custom FROM table WHERE id=28");
    $stmt->setFecthMode(PDO::FETCH_CLASS,'myClass');
    $object = $stmt->fetch();
    var_dump($object);
    

    $object 现在是 myClass 的实例化对象,具有三个属性,两个来自数据库,一个是我在 sql 中手动输入的

    Here 是我使用 oop 析构函数将这些对象保存回数据库的方式

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-07
      • 2020-11-13
      相关资源
      最近更新 更多