模型這一塊,Think PHP講解的比較復雜,並且內部做了各種數據庫兼容,我認為,雖然它做了這么多的兼容,但是並不代表我們要使用那么多晦澀的用法,事實上,那些用法是降低效率的。
ORM:object relational mapping 對象關系映射,以中間件的形式存在。
CURD: create update read delete
ActiveRecord模式:領域模型模式,特點是一個模型類對應關系型數據庫中的一個表,而模型類的一個實例對應表中的一行記錄。
領域模型模式和模型類關系密切,這里首先介紹模型類:
1 <?php 2 namespace Home\Model; 3 use Think\Model; 4 class UserModel extends Model 5 { 6 public $tablePrefix =''; 7 public $tableName='user'; 8 public $trueTableName='user'; 9 public $dbName='snatch'; 10 11 public function text() { 12 print_r($this->db->query('select * from segment limit 1')); 13 return "這是模型"; 14 } 15 } 16 ?>
之前沒有介紹過,相比於文檔,控制器、模型最好的學習方法是原生Think PHP的對應控制器、模型基類。
對於上面的模型,初始化的方法很簡單,下面是各種調用代碼舉例:
1 <?php 2 namespace Home\Controller; 3 use Think\Controller; 4 class IndexController extends Controller { 5 /** 6 * 首頁顯示 7 */ 8 public function index(){ 9 echo "<meta charset='utf-8'>"; 10 echo "hello world."; 11 $user=D('user'); 12 // $arr=$user->getField('uid'); 13 $arr=$user->where(array('uid'=>'2','password'=>'fcea920f7412b5da7be0cf42b8c93759'))->order(array('uid'=>'desc'))->limit(1)->group('uid')->select(); 14 echo $user->getLastSql(); 15 print_r($user->query('select * from segment limit 1')); 16 trace('',$user->getLastSql(),'user'); 17 trace('hahah',$user->text(),'user'); 18 $u = D(); 19 // trace('think',,'user'); 20 print_r($arr); 21 echo "<h1>_____________________________</h1>"; 22 print_r($u->query("select * from case_text limit 0")); 23 $user->select(array('where'=>'uid>1','order'=>'password asc')); 24 // $u->where(array('case_id' => 2))->select(); 25 // trace('',$u->text(),'user'); 26 27 // $this->show('<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} body{ background: #fff; font-family: "微軟雅黑"; color: #333;font-size:24px} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.8em; font-size: 36px } a,a:hover{color:blue;}</style><div style="padding: 24px 48px;"> <h1>:)</h1><p>歡迎使用 <b>ThinkPHP</b>!</p><br/>版本 V{$Think.version}</div><script type="text/javascript" src="http://ad.topthink.com/Public/static/client.js"></script><thinkad id="ad_55e75dfae343f5a1"></thinkad><script type="text/javascript" src="http://tajs.qq.com/stats?sId=9347272" charset="UTF-8"></script>','utf-8'); 28 }
D函數和M函數:
D函數和M函數是快速初始化模型的Think PHP內置方法。
D函數和M函數的區別是,M函數可以初始化一個沒有定義模型類的模型,也就是說M函數在執行原生SQL的時候效率更高。因為不需要架加載模型類,所以M函數不能夠加載對應的模型中的函數方法。當然,並不是說D函數不能初始化空模型。
$user= D('user');這句代碼代表初始化Model下面的UserModel類。
匪夷所思的查詢條件:
Think PHP中復雜多變的函數把單一的SQL拆解的很難理解。
支持select()條件、group()條件、order()條件、limit條件、where()條件等常見的查詢條件內嵌,應用舉例:
1 public function index(){ 2 echo "<meta charset='utf-8'>"; 3 echo "hello world."; 4 $user=D('user'); 5 $arr=$user->limit(1)->order('uid desc')->where('uid>1')->group('uid')->select(); 6 trace('SQL',$user->getLastSql(),'user'); 7 print_r($arr); 8 } 9 //生成SQL: 10 SELECT * FROM snatch.user WHERE ( uid>1 ) GROUP BY uid ORDER BY uid desc LIMIT 1 :SQL
D函數和M函數支持原生SQL查詢:
1 public function index(){ 2 echo "<meta charset='utf-8'>"; 3 echo "hello world."; 4 $user=D('user'); 5 $arr=$user->query('select count(*) from word_a'); 6 trace('SQL',$user->getLastSql(),'user'); 7 print_r($arr); 8 } 9 //生成SQL: 10 select count(*) from word_a:SQL 11 12 public function index(){ 13 echo "<meta charset='utf-8'>"; 14 echo "hello world."; 15 $user=M(); 16 $arr=$user->query('select count(*) from word_a'); 17 trace('SQL',$user->getLastSql(),'user'); 18 print_r($arr); 19 } 20 //生成SQL: 21 select count(*) from word_a:SQL
請記住以上只是測試函數的使用,使用yuanshengSQL務必使用M函數。
and方法除了在各個條件中直接寫and,還可以使用數組:
1 public function index(){ 2 echo "<meta charset='utf-8'>"; 3 echo "hello world."; 4 $user=D('user'); 5 $arr=$user->limit(1)->order('uid desc')->where(array('password'=>'123456','uid'=>'100'))->group('uid')->select(); 6 trace('SQL',$user->getLastSql(),'user'); 7 print_r($arr); 8 } 9 //生成SQL: 10 SELECT * FROM snatch.user WHERE `password` = '123456' AND `uid` = 100 GROUP BY uid ORDER BY uid desc LIMIT 1 :SQL
我實際測試中中,數組中只能使用確定等於的條件。
調試方法:
1 public function index(){ 2 echo "<meta charset='utf-8'>"; 3 echo "hello world."; 4 $user=D('user'); 5 $arr=$user->limit(1)->order('uid desc')->where(array('password'=>'123456','uid'=>'100'))->group('uid')->select(); 6 trace($user->getLastSql(),'SQL','user'); 7 trace($user->getDbFields(),'Fields','user'); 8 trace($user->getTableName(),'TBN','user'); 9 trace($user->getPk(),'主鍵','user'); 10 print_r($arr); 11 } 12 //效果: 13 SQL:SELECT * FROM snatch.user WHERE `password` = '123456' AND `uid` = 100 GROUP BY uid ORDER BY uid desc LIMIT 1 14 Fields:Array ( [0] => uid [1] => username [2] => password [3] => email [4] => telephone ) 15 TBN:snatch.user 16 主鍵:uid
緩存:
緩存包括緩存在文件中和緩存在內存中,由於緩存在文件中需要增加額外的IO,所以建議使用內存緩存(即把緩存定義在模型類中)。
你可以在內存中加載$pk 主鍵 $fields 字段數組。
1 <?php 2 namespace Home\Model; 3 use Think\Model; 4 class UserModel extends Model 5 { 6 public $tablePrefix =''; 7 public $tableName='user'; 8 public $trueTableName='user'; 9 public $dbName='snatch'; 10 protected $pk='ud'; 11 protected $fields=array('uid','username'); 12 public function text() { 13 print_r($this->db->query('select * from segment limit 1')); 14 return "這是模型"; 15 } 16 } 17 ?> 18 19 <?php ^^^^^ 20 public function index(){ 21 echo "<meta charset='utf-8'>"; 22 echo "hello world."; 23 $user=D('user'); 24 $arr=$user->limit(1)->order('uid desc')->where(array('uid'=>'4'))->group('uid')->select(); 25 trace($user->getLastSql(),'SQL','user'); 26 trace($user->getDbFields(),'Fields','user'); 27 trace($user->getTableName(),'TBN','user'); 28 trace($user->getPk(),'主鍵','user'); 29 print_r($arr); 30 } 31 ^^^ 32 ?> 33 34 //執行結果: 35 SQL:SELECT * FROM snatch.user WHERE `uid` = '4' GROUP BY uid ORDER BY uid desc LIMIT 1 36 Fields:Array ( [0] => uid [1] => username ) 37 TBN:snatch.user 38 主鍵:ud
通過以上測試,你可以發現:
$pk和$field必須是protected,不信你可以試試private~
$pk和$field的字段可以不對應,但是這就失去了緩存的意義。
get函數實際上得到的是緩存信息。
緩存支持字段類型檢查。
數據庫連接配置:
1 //數據庫配置1 2 'DB_CONFIG1' => array( 3 'db_type' => 'mysql', 4 'db_user' => 'root', 5 'db_pwd' => '1234', 6 'db_host' => 'localhost', 7 'db_port' => '3306', 8 'db_name' => 'snatch' 9 ), 10 //數據庫配置2 11 'DB_CONFIG2' => 'mysql://root:1234@localhost:3306/snatch' 12 //應用方法: 13 new \Home\Model\NewModel('new','think_','DB_CONFIG1'); 14 new \Home\Model\BlogModel('blog','think_','DB_CONFIG2'); 15 //全部可配置的屬性: 16 'DB_TYPE' => '', // 數據庫類型 17 'DB_HOST' => '', // 服務器地址 18 'DB_NAME' => '', // 數據庫名 19 'DB_USER' => '', // 用戶名 20 'DB_PWD' => '', // 密碼 21 'DB_PORT' => '', // 端口 22 'DB_PREFIX' => '', // 數據庫表前綴 23 'DB_DSN' => '', // 數據庫連接DSN 用於PDO方式 24 'DB_CHARSET' => 'utf8', // 數據庫的編碼 默認為utf8 25 26 //連接數據庫的配置信息的調用規則跟之前介紹配置文件的調用優先級策略是一致的,此處不做贅述。 27 //Think PHP 支持主流數據庫的驅動(我們使用的MySQL和MongoDB均被支持) 28 //可以定義長連接: 29 'DB_PARAMS' => array(PDO::ATTR_PERSISTENT => true); 30 31 //模型類動態定義的方法:數據庫類型://用戶名:密碼@數據庫地址:數據庫端口/數據庫名#字符集 32 protected $connection = 'mysql://root:1234@localhost:3306/thinkphp#utf8'; 33
模型內跨數據庫查詢:
1 public function text() { 2 return $this->db()->query('select * from segment limit 1'); 3 return "這是模型"; 4 }
db函數是可以帶條件的,你可以在里面選擇添加數據庫調用信息,此處不做詳細舉例。
自動驗證等。