php mvc结构与数据库变量

时间:2013-01-18 13:13:00

标签: php mongodb naming-conventions variable-assignment nosql

排序 MVC结构PHP项目上试验

假设我有一个用户模型,如下所示:(我正在使用伪代码

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

在我的控制器里我有:

$user = getUser("foo");

所以我可以像这样轻松访问要打印的用户信息:

$name = $user["name"];
到目前为止,这么容易。如果我继续这样做,我想我可能面临的问题是,如果有一天我将不得不将列'name'改为say,只是'n',getUser返回的所有组件都返回了)必须进行修改以反映这种变化。

在这种情况下如何避免此类问题?

P.S。我知道这不是MVC,而是VMC-ish结构;它只是为了了解如何做到这一点。如果我犯了任何错误的解释,请耐心等待,不要惊慌失措:我们是人类而不是机器人,最重要的是我们在这里学习。


为什么我说的是我实际上并没有使用mysql而是使用mongodb,它的对象结构如下:{name:“foo”,surname:“fuu”}基本上是为每个对象重复的,所以我认为为了节省数据库中的空间,我可能会决定将它从“名称”更改为“n”,每个对象节省3个ascii字符!这超出了问题的范围,但我认为你现在明白为什么我需要使用它。

4 个答案:

答案 0 :(得分: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;
        }
    }
}

但是,你真的不应该更改数据库列名,而且 肯定是之类的单个字母。这种含糊不清只是要求来解决问题。

答案 1 :(得分: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']);
}

如果更改数据库中的列名,则只需更改此层中从数据库中提取的代码,而不是整个代码库中的代码。您可以使用创建定义格式的数组结构的函数,在没有对象的情况下完成此工作。但是很难击败对象为你提供的类型安全

答案 2 :(得分: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查询和程序结构

答案 3 :(得分:0)

  

为什么我说的是我实际上并没有使用mysql而是mongodb,它的对象结构如下:{name:&#34; foo&#34;,surname:&#34; fuu&#34;}对于每个对象基本上都是重复的,所以我认为为了节省数据库中的空间,我可能会决定在某一天更改名称&#39;只是为了每个对象保存3个ascii字符!

哇哇三个ASCII字符。

很抱歉,只是有些人真的把MongoDB的整个存储空间放得太过分了。

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

说真的只是为了省去自己的麻烦,我怀疑你会达到这样一个程度,你的收藏将包含这么多的文件,这个微观选择实际上会产生影响;我的意思是我们在这里讨论数十亿个文件可能在一个碎片上(为什么你会这样做?)。

事实是大多数场缩短已经发生,因为人们有这种奇怪的想法,由于某种原因,几个字节(如usernamen之间的差异)将对存储和记忆产生一些深远的影响用法和索引大小(MongoDB不会在索引中存储键名...)以及所有那些不真实的东西。

如果您要命名一个字段my_awesome_really_long_field_that_is_good然后是,则很容易出现缩短字段的情况,但对于大多数部分,正常,理智,命名字段和单个字母字段之间的区别是NOUT。

单字母字段的使用情况很少,以至于我怀疑你会达到一个有利于你使用它的地步,即使你这样做,你也会为ORM处理过多的数据教条或你自己以高效的方式做到这一点,所以无论如何这个问题都是存在的。

所以我不是在开玩笑,不要为此烦恼。您将在PHP应用程序中浪费更多资源,而不是在数据库端保存。