2

I am experimenting on a sort-of MVC structure PHP project.

Suppose I have a model for users, that looks like this: (I am using pseudocode)

function addUser($name, $surname) {
  mysql_query("insert into users name=$name surname=$surname");
  return true;
}

function getUser($id) {
  $object = mysql_query("select from users where id=$id limit 1");
  return $object;
}

and in my controller I have:

$user = getUser("foo");

so I can access user information to be printed out easily like this:

$name = $user["name"];

so far, so easy. The problem which I suppose I might face if I keep going this way is that, if one day I will have to change the column 'name' into say, just 'n', all the components that are getting the object returned by getUser() will have to be modified to reflect that change.

How does it work in this cases to avoid such problem?

P.S. I know this is not exactly MVC but a VMC-ish structure; it's just to get the idea on how to do it. If I made any mistake explaining please be patient and don't freak out: we are humans and not robots and most importantly we are here to LEARN.


why I said that is that I am actually not using mysql but mongodb, which as the object structure like this: {name:"foo", surname:"fuu"} that is basically repeated for every object so I thought that to save space in the db I might just decide to change it one day from 'name' to just 'n', saving 3 ascii chars per object! It's out of the scope of the question but I think you understand now why I need to use this.

4

4 回答 4

0

您可以在模型类中使用 getter 和 setter:

<?php
class User {

    public function setName($name) {
        $this->n= $name;
    }

    public function getName() {
        return $this->n;
    }
}

或者你可以使用__get__set魔法函数:

<?php
class User {

    public function __get($key) {
        if ($key == 'name') {
            return $this->n;
        }
        else {
            return $this->$key;
        }
    }

    public function __set($key, $value) {
        if ($key == 'name') {
            $this->n = $value;
        }
        else {
            $this->$key = $value;
        }
    }
}

但是,您真的应该更改数据库列名,绝对应该更改像“n”这样的单个字母。这种模棱两可只是自找麻烦

于 2013-01-18T13:35:57.657 回答
0

您希望将数据库的结构与您在其余代码中使用的变量/索引/属性名称分离,在系统的这两个部分之间有一个绝缘层,可以在它们之间进行转换。最好使用对象来完成:

class User {

    protected $name;

    public function __construct($name) {
        $this->setName($name);
    }

    public function setName($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }

}

从数据库获取数据的函数现在不会按原样返回该数据,具体取决于数据库今天返回数据的感觉,但它返回特定的已定义对象的实例User

function getUser() {
    $data = query('SELECT ...');
    return new User($data['n']);
}

如果您更改数据库中的列名,您只需更改从数据库获取的这一层中的代码,而不是在整个代码库中的任何地方。您可以在没有对象的情况下完成这项工作,而是使用创建定义格式的数组结构的函数。但是很难超越对象为您提供的类型安全性。

于 2013-01-18T13:49:30.717 回答
0

我想对您的代码提出一些建议。但至于更改列名,为什么要更改它呢?如果你做了是,你必须更正查询。我有点担心您的函数的卫生以及 PHP 5.0 + 中已删除的 mySQL 的使用。您可能想查看 mySQLi,它是等效的替代品。我在基于过程的代码方面不是那么出色,所以如果我犯了任何错误,请原谅我。

使用您的函数,无需返回 true;或返回 mysql_query。这些是在没有回报的情况下遵守的。此外,在您的查询中,最好将关键字大写,例如:SELECT, FROM, WHERE, INSERT INTO, LIMIT. 即使您选择了所有列,也应始终声明您的选择列。查询字符串示例:

"SELECT * FROM table WHERE id = '{$id}'"//Variables should be entered in this way
//I don\'t know why they just do lol 
"SELECT id,name FROM table WHERE table.id = '{$id}'"//This will only return the id and name from the table named table

因此,对于您的脚本,我建议使用 mysqli 程序样式。这是程序样式:

$DBH = new mysqli('localhost','user','pass','optional Database selection');
mysqli_select_db($DBH,'selection of the data can be done this way also');
mysqli_prepare($DBH,"SELECT * FROM table WHERE id = ?");//note the question mark instead of your $id variable.
mysqli_bind_param($DBH,'i',$id);//this replaces your question mark with the variable $id. This is a lot more sanitised that your example.
//bind_param() expects 3 parameters. first the database, second the variables datatype
// 'iiss' would be int int string string third comes your vars 
mysqli_execute($DBH);
mysqli_bind_results($tableID,$tableName,$otherColumns);//your columns will be returned in order. Selecting * will return all columns. Selecting id,name will return only id and name column.
while(myslqi_fetch_result($DBH)){
    //this is basically saying while there are results fro the database.
    echo $tableID.' '.$tableName.' '.$otherColumns;
}

现在,我还建议您使用 OOP(面向对象程序)来构建函数。看起来有点像这样:

Class users{
    private $DBH;//makes sure our database handler is secure 
    public function __construct(){
        //public so that this function is ran at the start of the class
        $this->DBH;//how to access your variables and functions in OOP in other words
        //$addUser->DBH; which would be private and inaccessible. 
        $this->DBH = new mysqli('local','user','pass','database');
    }
    public function addUser($name,$surname){
        $query = $this->DBH->prepare('INSERT INTO users VALUES(NULL,?,?');
        $query->bind_param('ss',$name,$surname);
        $query->execute();
        //you can also run a check query returned true function :)
    }
    public function returnUser($id){
        $data = array();
        $query = $this->DBH->prepare('SELECT * FROM users WHERE id = ?');
        $query->bind_param('i',$id);
        $query->execute();
        $query->bind_result($ID,$name,$surname,$other);
        while($query->fetch_result()){
            $data[] = array('ID'=>$ID,'name'=>$name,'surname'=>$surname,'other'=>$other);
        }
        return $data;
    }
}
$userHandler = new users(); //adding an instance of the class users();
$usersInfo = $userHander->returnUser($id);//userinfo will now contain an array of arrays of users that have an id of $id. Depends how you use it :p

抱歉,如果我一口气做了太多,或者你已经知道了,我只是个家伙,哈哈,我希望我对你的程序的 mysqli 查询和结构有所帮助

于 2013-01-18T13:51:53.130 回答
0

为什么我这么说是因为我实际上不是使用mysql而是mongodb,它作为像这样的对象结构:{name:"foo", surname:"fuu"} 基本上对每个对象都重复所以我认为这是为了节省空间在数据库中,我可能决定有一天将其从“name”更改为“n”,每个对象节省 3 个 ascii 字符!

哇整整三个 ASCII 字符。

对不起,只是有些人真的把 MongoDB 的整个存储东西走得太远了。

它不会减少索引的大小,也不会停止碎片化,事实上由于奇怪的文档大小,它可能会增加这一事实(导致文档大小不规则的字段的非标准名称)。当 MongoDB 来映射文件时,如果您的系统在虚拟内存方面很难完成,那么您将看到的唯一真正好处可能是几个字节。

认真地为自己省去麻烦,我怀疑您是否会达到您的收藏包含如此多文档的程度,以至于这种微优化实际上会产生效果;我的意思是我们在这里谈论的可能是在一个分片上的数十亿个文档(你为什么要这样做??)。

username事实是大多数字段缩短已经发生,因为人们有一种奇怪的想法,即出于某种原因,几个字节(如和之间的差异n)将对存储和内存使用以及索引大小产生一些深远的影响(MongoDB 不会将键名存储在索引...)以及所有虚假的东西,但实际上并非如此。

如果你要命名一个字段my_awesome_really_long_field_that_is_good,那么是的,很容易有一个案例来缩短你的字段,但是通常,理智的命名字段和单个字母字段之间的区别是,在大多数情况下,nout。

单字母字段的用例减少到如此之少,以至于我怀疑您是否会达到使用它对您有益的程度,即使您这样做了,您也会为像 Doctrine 或您的 ORM 这样的 ORM 处理太多数据自己以高效的方式执行此操作,因此无论如何这个问题都存在。

所以我不是在开玩笑,不要理会这个。您在 PHP 应用程序中浪费的资源将比在数据库端节省的资源多。

于 2013-01-18T15:12:02.480 回答