首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与DataBase的工作安排

与DataBase的工作安排
EN

Stack Overflow用户
提问于 2011-08-16 21:08:31
回答 1查看 101关注 0票数 0

我在PHP方面有一些经验,但在应用程序架构方面没有人。

现在我想组织我自己的“自行车”。这是一些没用的东西,也许是迷你框架或迷你应用,我想在这里得到一些经验。

我现在需要编写用于数据库的类和实体的类(其中一个是User)。

我有下面的数据库代码(为了减少这个问题,省略了一些代码和方法):

代码语言:javascript
复制
namespace DataBase;
class DataBase {
    /**
     *
     * @var \PDO $pdo
     */
    public $pdo;
    public function __construct($host, $dbname, $username, $password=''){

        $this->pdo = new \PDO('mysql:host='.$host.';dbname='.$dbname, $username, $password,
            array(\PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"));
        $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);

    }
    /**
     *
     * @param string $statement
     * @return Statement
     */
    public function prepare($statement){
        return new Statement($this->pdo->prepare($statement));
    }
}


namespace DataBase;

class Statement {
    private $stmt;

    public function __construct(\PDOStatement $stmt) {
        $this->stmt = $stmt;
    }

    public function query() {
    try {
        $this->stmt->execute();
        return $this; //for chaining
    }

    public function bind($key, $value) {
        $this->stmt->bindValue($key, $value, $this->typeof($value));
        return $this; //for chaining
    }
        //some methods for fetching data(works with fetch,fetchAll, fetchColumn and different PDO::FETCH_ methods

    public function fetchUpdate($obj) {
        $this->stmt->setFetchMode(\PDO::FETCH_INTO, $obj);
        $this->stmt->fetch();
    }

    public function fetchRow() {
        return $this->stmt->fetch(\PDO::FETCH_OBJ);
    }
    public function fetchRowClass($class) {
        return $this->stmt->fetchObject($class);
    }
}

和一些用于用户类的虚拟

代码语言:javascript
复制
<?php

/**
 * Description of User
 *
 * @author riad
 */
class User {
    private $id;

    private $name = null;

    private $status = null;

    private $hasInfo = false;

    private static $cache=array();
    public function __construct() {

    }
    public function getId() {
        return $this->id;
    }
    public function getName() {
        if(!$this->hasInfo)
            $this->getInfo ();
        return $this->name;
    }
    public function isAuthorized(){
        return $this->status!="noauth";
    }
    public static function createById($id) {
        // I want this method to cerate user from id, then get info only I will use it after that
        if(array_key_exists($id,self::$cache)){
            return self::$cache[$id];
        }
        $user = new User;
        $user->id = $id;
        return $user;
    }
    private function getInfo(){
        try{
            \FrontController::getInstance()->getDB()->
                prepare('SELECT * FROM `users` WHERE `id`=:id')->
                bind('id', $this->id)->query()->fetchUpdate($this);
            $this->hasInfo = true;
        }
        catch(\DataBase\NotFoundException $dbe){
            $this->status = "deleted";
        }
    }
    public static function createFromRequest($request){
        $user = new User;
        try{
            //try get data from cookie
            \FrontController::getInstance()->getDB()->
                prepare('SELECT * FROM `users` WHERE `session` = :session AND `id`= :id')->
                bind('id', $id)->bind('session',$session)->query()->
                fetchUpdate($user);
        }
        catch(... $e){
            $user->status = "noauth";
            $user->id = 0;
            // make it unregged
        }
        return $user;
    }
}

?>

我有一些问题。

  • 我不想从数据库中设置属性,这些属性没有列在类列表的道具中(当然,并不那么重要)。我知道我可以使用公共函数__call($name,$value){ //什么都不做;}
  • 我希望这个道具是私有的,但也想使用$stmt->fetchUpdate($obj)我知道我可以使用公共函数__call($name,$value){ $ this ->$name=$value;} ,但它是作为声明道具公共的,而且在第一点的道路上,我还可以使用公共函数__call($name,$value){ if($name=‘id’){ $this->id=$value;}如果($name=‘status’){$this->$value=$value;}} 但是,为每个实体类编写它是不舒服的,并且不保存这种方法的公开性
  • 当我从数据库中获得这个类时,我想将$this->hasInfo设置为true。我知道我可以将我的Database类更改为总是将一些变量设置为true,而默认情况下它是假的。但它似乎不雅致。
  • 当我设置id时,我想更新缓存(它可能被用作previos点)
  • 是否有可能避免fetchRowClass直接写入道具和使用setter,就像使用fetchUpdate一样?或者允许fetchUpdate直接访问?

我知道我写了很多代码,但我想听听你的意见:

  • 我应该改进什么?
  • 什么是其他/最好的解决办法,从以前的问题清单?

希望,它不是那么难读和理解。

很高兴看到任何建议

关于亚历克斯

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-08-18 10:21:31

几个小贴士:根据我自己的经验和框架,我已经使用了

基本上,您应该/希望/可能做的是为模型中的所有类创建一个SuperClass。这个类将包含对数据库实例的引用,它将拥有模型的所有常用方法,即getById($id)getAll()getPaginated()等。

这个SuperClass的另一个目标是将来自数据库的结果映射到模型类的实例中。因此,最终,您的用户类将只有特定于该类的属性、访问器和方法,比如特殊的查询或类似的东西。

下面是一个例子,说明这可能是什么样子:

代码语言:javascript
复制
Class Model{
    protected function getById($_id){
        $_table = get_class($this);
        $anonymous = $this->_getObjectById($_table,$_id); //this method will execute a query (unsing PDO) and return a StdClass object with the results
        $this->mapTable($anonymous,$_table); //this method will take the StdClass instance and will transform it into a $_table Instance
    }

    private function mapTable($stdInstance,$model_name){
        foreach($stdInstance as $key => $value){
            try{
                if(property_exists($this,$key)){
                    $this->$key = $value; //you could declare the model's properties     as protected... or you could create accessors and call them here
                }
            } catch(Exception $ex) {
                /* something went wrong o_O */
            }
     }

Class User extends Model{
     protected $id;
     protected $name;
     .....
}

Class Controller{
    public function index(){
         $user = new User();
         $user->getById($_GET['id']);
         print_r($user);
         //now you can pass the $user object to the View to display it
    }
}

几句话..。模型类是一个非常小的奥姆。您可以尝试创建自己的ORM (就像我所做的那样),但是在映射对象之间的关系时会遇到很多问题: Nx1,1xN,NxN,1x1,继承,“更深层次的关系”和n+1问题。您还需要以某种方式定义模型结构,以便ORM能够理解它,可能使用YAML/XML文件,或者直接从数据库的表结构读取结构,或者在属性中有一个命名约定.

这是一个非常有趣的领域:)

希望这能帮助你,祝你好运

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7085043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档