2

私は一種の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」を単に「n」に変更する必要がある場合、 getUser( によって返されるオブジェクトを取得しているすべてのコンポーネント) は、その変更を反映するように変更する必要があります。

このような問題を回避するには、この場合どのように機能しますか?

PSこれは正確にはMVCではなく、VMC風の構造であることは知っています。それを行う方法についてのアイデアを得るだけです。説明を間違えた場合は、しばらくお待ちください。びっくりしないでください。私たちは人間であり、ロボットではありません。最も重要なことは、学ぶためにここにいるということです。


なぜ私がそう言ったのかというと、実際にはmysqlではなくmongodbを使用しているためです。これは、基本的にすべてのオブジェクトに対して繰り返される {name:"foo", surname:"fuu"} のようなオブジェクト構造として、スペースを節約するためにデータベースでは、オブジェクトごとに3つのASCII文字を節約して、ある日「名前」から「n」だけに変更することにするかもしれません! 質問の範囲外ですが、なぜこれを使用する必要があるのか​​ 理解できたと思います。

4

4 に答える 4

0

モデルクラスでゲッターとセッターのいずれかを使用できます。

<?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」のような1文字に変更するべきではありません。そのあいまいさは、問題を引き起こしているだけです

于 2013-01-18T13:35:57.657 に答える
0

なぜ私がそれを言ったのかというと、実際にはmysqlではなくmongodbを使用しているためです。これは、基本的にすべてのオブジェクトに対して繰り返される {name:"foo", surname:"fuu"} のようなオブジェクト構造として、スペースを節約するためにデータベースでは、オブジェクトごとに3つのASCII文字を節約して、ある日「名前」から「n」だけに変更することにするかもしれません!

すごい 3 つの ASCII 文字です。

申し訳ありませんが、一部の人々が MongoDB のストレージ全体を行き過ぎているだけです。

インデックスのサイズは減少せず、断片化も停止しません。実際、ドキュメントのサイズが奇妙であるため、その事実が増加する可能性があります (フィールドの非標準名により、ドキュメントのサイズが不規則になります)。MongoDB がファイルを mmap するようになったときに、システムが仮想メモリの面で苦労している場合、実際に得られる唯一のメリットはおそらく数バイトです。

真剣に手間を省いてください。コレクションに非常に多くのドキュメントが含まれているため、このマイクロ最適化が実際に効果を発揮することはないと思います。ここでは、おそらく単一のシャードにある数十億のドキュメントについて話していることを意味します (なぜそうするのですか??)。

事実、ほとんどのフィールドの短縮が発生したのは、何らかの理由で数バイト ( と の差usernameなどn) がストレージとメモリの使用量とインデックスのサイズに深刻な影響を与えるという奇妙な考えがあるためです (MongoDB はキー名をインデックス...) そして、実際にはそうでない場合のすべての偽物。

フィールドに名前を付ける場合my_awesome_really_long_field_that_is_good、はい、フィールドを短くするケースは簡単にありますが、通常、正気の名前付きフィールドと単一文字フィールドの違いは、ほとんどの場合、違います。

単一文字フィールドのユースケースは非常に少ないため、それを使用することが有益なポイントに到達することはないと思います。たとえ使用したとしても、Doctrine のような ORM やあなたのパフォーマンスの高い方法でこれを行う必要があるため、この質問はとにかく有効です。

だから私は冗談を言っているのではありません。気にしないでください。データベース側で節約するよりも、PHP アプリでより多くのリソースを浪費することになります。

于 2013-01-18T15:12:02.480 に答える
0

データベースの構造を、コードの残りの部分で使用する変数/インデックス/プロパティ名から切り離し、システムのこれら 2 つの部分の間に絶縁層を置き、それらの間で変換する必要があります。これは、オブジェクトを使用して行うのが最適です。

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 に答える