既然是講數據庫的,那首先天然是鏈接數據庫了。php
這裏舉兩個例子,mysql數據庫:mysql
$db=new DB\SQL( 'mysql:host=localhost;port=3306;dbname=mysqldb', 'admin', 'p455w0rD');
sqlite數據庫: web
$db=new DB\SQL('sqlite:/absolute/path/to/your/database.sqlite'));
數據庫查詢:sql
很簡單的,fatfree的數據庫是不用配置的,不少東西都是內置的,當你須要改再去改就行,咱們首先學習查詢,就一步:數據庫
$f3->set('result',$db->exec('SELECT brandName FROM wherever'));
這樣就好了,select 和 from是數據庫語言,咱們這就把數據庫中符合條件的變量放到了result數組裏面了。 數組
而後咱們用以前學的repeat調用試試看:安全
<repeat group="{{ @result }}" value="{{ @item }}"> <span>{{ @item.brandName }}</span></repeat>
最後再echo一下就能夠了。注意一下,這裏實際上是個二維數組,結構大概是result -> brandName -> value。能夠用以前學過的嵌入repeat,可是這裏既然brandName只有一個,那麼就用 . 符號就能夠解決問題了。 app
深造:框架
若是要執行一組命令怎麼辦?兩種方法:函數
$db->exec( array( 'DELETE FROM diet WHERE food="cola"', 'INSERT INTO diet (food) VALUES ("carrot")', 'SELECT * FROM diet' ));
還有
$db->begin();$db->exec('DELETE FROM diet WHERE food="cola"');$db->exec('INSERT INTO diet (food) VALUES ("carrot")');$db->exec('SELECT * FROM diet');$db->commit();
固然,若是指令出錯的話,調用就會回捲,咱們能夠經過調用:
echo $db->log();
來查看指令的調用情況。
數據庫安全:
爲了方式用戶惡意修改數據庫,咱們應該用下面這個方法代替上面的代碼:
$db->exec( array( 'DELETE FROM diet WHERE food=:name', 'INSERT INTO diet (food) VALUES (?)', 'SELECT * FROM diet' ), array( array(':name'=>'cola'), array(1=>'carrot'), NULL ));
數據庫的增刪查改:
首先數據庫文件的大概形式是這樣的:
CREATE TABLE users ( userID VARCHAR(30), password VARCHAR(30), visits INT, PRIMARY KEY(userID) );
好,首先咱們一步一步來,鏈接數據庫
$db=new DB\SQL( 'mysql:host=localhost;port=3306;dbname=mysqldb', 'admin', 'wh4t3v3r');
而後
$user=new DB\SQL\Mapper($db,'users');$user->load(array('userID=?','tarzan'));
上面的這個$user是咱們創建的一個‘users’屬性的結構對象(也就是上面那個數據庫文件的形式),裏面是空的。
第二行就是把userID = tarzan 的給讀出來的,附屬的信息都一塊兒讀出來了。
數據庫的插入修改:
繼續上面的那個例子,若是我要修改這個類裏面的訪問量visits怎麼辦呢?
$user->visits++;$user->save();
這樣就能夠了。
若是要增長一個新的記錄呢:
$user=new DB\SQL\Mapper($db,'users');// or $user=new DB\Mongo\Mapper($db,'users');// or $user=new DB\Jig\Mapper($db,'users');$user->userID='jane';$user->password=md5('secret');$user->visits=0;$user->save();
有沒有發現咱們一直都在用save函數,由於若是不save的話這裏修改的值就會在腳本運行結束的時候恢復回去的。
fatfree框架是很自動的,若是這裏增長的userID是已經存在的用戶,這裏的增長就會自動變成修改操做,畢竟咱們文件裏最重要的那句
PRIMARY KEY(userID)
不是白白加上去的,這句話既是監控key值的做用(知道究竟是插入仍是修改操做)又是映射變量的做用。
固然,還有一點要注意的,若是你要連續修改(插入)須要reset一下:
$user->reset();$user->userID='cheetah';$user->password=md5('unknown');$user->save();
原理說一下,由於若是是進行了操做的話,映射類裏面就會包含這個最新的操做,咱們這個save就是把映射類裏面的操做commit到數據庫裏面,可是若是你要繼續下一個操做就要從新clear一下映射類,因此咱們須要reset一下。養成良好習慣就是每當操做前reset一下,操做後save一下。
刪除用戶:
$user=new DB\SQL\Mapper($db,'users');$user->load(array('userID=? AND password=?','cheetah','ch1mp'));$user->erase();
很簡單,首先load該用戶,而後erase就好了。用?是爲了保護數據庫不被看到。
POST變量與數據庫傳遞:
POST跟GET同樣是全局變量,都是被set過的,能夠近似地看做一個tmp,不過POST是不對用戶公開的,因此經常使用語數據庫。
從POST讀取到新變量user裏面:
$f3->set('user',new DB\SQL\Mapper($db,'users'));$f3->get('user')->copyFrom('POST');$f3->get('user')->save();
把user裏面的東西給POST:
$f3->set('user',new DB\SQL\Mapper($db,'users'));$f3->get('user')->load(array('userID=?','jane'));$f3->get('user')->copyTo('POST');
這裏就是讀取了jane的相關信息給了post。別忘了在php裏面調用post是$_post,在fatfree裏面就只要@POST就行。
繼續,這裏讀取了jane的相關信息後,能夠經過@POST.userID來調用信息。
例子:
<input type="text" name="userID" value="{{ @POST.userID }}">
這裏的input類型是text文本輸入,輸入的信息存儲到userID變量裏,然後面那個value則是會在空格里顯示的默認數據,就像咱們登錄qq那樣記錄上一次登錄的用戶名,用的就是上面這種方法。
條件篩選:
$user=new DB\SQL\Mapper($db,'users');$user->load('visits>3');// Rewritten as a parameterized query$user->load(array('visits>?',3));// For MongoDB users:// $user=new DB\Mongo\Mapper($db,'users');// $user->load(array('visits'=>array('$gt'=>3)));// If you prefer Jig:// $user=new DB\Jig\Mapper($db,'users');// $user->load('@visits>?',3);// Display the userID of the first record that matches the criteriaecho $user->userID;// Go to the next record that matches the same criteria$user->skip(); // Same as $user->skip(1);// Back to the first record$user->skip(-1);// Move three records forward$user->skip(3);
例子就說明得很清楚了,首先篩選出visits > 3 的user 而後再skip,其實skip就至關因而next,你要跳幾步就skip幾個,若是要回跳就skip(-1)。
能夠用dry()函數來檢驗是否越界,若是在第一個skip(-1)或者在最後一個next,那麼dry()都會返回一個true來表示已經越界了。
固然load函數還有一個特別的讀取形式,相似於重載過同樣:
$user->load( array('visits>?',3), array( 'order'=>'userID DESC' 'offset'=>5, 'limit'=>3 ));
這句話的意思就至關於數據庫語言裏的:
SELECT * FROM users WHERE visits>3 ORDER BY userID DESC LIMIT 3 OFFSET 5;
還有個更簡單的寫法:
$page=$user->paginate(2,5,array('visits>?',3));
那個2跟5就是從第2個開始數5個
虛領域:
首先給個表單:
CREATE TABLE products ( productID VARCHAR(30), description VARCHAR(255), supplierID VARCHAR(30), unitprice DECIMAL(10,2), quantity INT, PRIMARY KEY(productID) );
所謂的虛領域就是本身設定規則,舉個例子:
$item=new DB\SQL\Mapper($db,'products');$item->totalprice='unitprice*quantity';$item->load(array('productID=:pid',':pid'=>'apple'));echo $item->totalprice;
這裏設定的totalprice就是虛領域,默認等於unitprice * quantity 這個虛領域設定了以後其實就至關於裏面的一個元素了,能夠直接經過 -》 來調用。接着讀取productID等於apple的元素而後返回這個虛領域也就是他們兩個的乘積。
固然了,除了讀取單個元素以外虛領域還能夠在宏觀上一些操做,例如取最大的數量:
$item->mostNumber='MAX(quantity)';$item->load();echo $item->mostNumber;
注意這裏的load沒有涉及任何變量,表示直接在全局裏面load,而後就能夠輸出最大數字的元素了。
固然了,有時候你沒法用一些現有的函數來表達你想要的東西,咱們就能夠經過數據庫的語言來本身設立篩選條件:
$item->supplierName= 'SELECT name FROM suppliers '. 'WHERE products.supplierID=suppliers.supplierID';$item->load();echo $item->supplierName;
這裏本身設定了篩選條件,就是把同名的找出來(通常若是有多個就默認第一個)
數據庫查找:
數據庫查找要用到find函數:
$frequentUsers=$user->find(array('visits>?',3),array('order'=>'userID'));
要注意,load跟find是徹底不同的,看名字就知道用途了,load是找出全部符合要求的而後我要對它進行操做或者運算,而find函數只要find到了就完事了,就只要看結果,不操做。並且還有一點不一樣,find由於工做是查找,因此會把找到的東西存起來,存到一個定義好的數組裏面(後面會說)。也就是說哪些用於操做的skip,虛領域什麼的都不能經過find實現。
咱們來看看find函數的定義:
find( $criteria, array( 'group'=>'foo', 'order'=>'foo,bar', 'limit'=>5, 'offset'=>0 ));
第一個是基本條件,做爲第一步篩選,而後下面的都是額外篩選的條件,放在一個數組裏面。
$place=new DB\SQL\Mapper($db,'places');$list=$place->find('state="New York"');foreach ($list as $obj) echo $obj->city.', '.$obj->country;
這裏假設定義好了一個城市的表,而後這裏吧state = NEW York 的全部符合條件的映射都存到list數組裏面了,而後下面經過foreach來調用查看結果。
接着上面的定義,若是咱們不要篩選條件,要整個表搬走,能夠用上cast()
$array=$place->cast();echo $array['city'].', '.$array['country'];
還有一個特別好用的函數count:
if (!$user->count(array('visits>?',10))) echo 'We need a better ad campaign!';
這裏是若是連一個訪問量大於10的用戶都沒有,那咱們就確實須要投廣告了。。。
還有能夠經過select來作一些比find更復雜的篩選,看看select的定義:
select( 'foo, bar, MIN(baz) AS lowest', 'foo > ?', array( 'group'=>'foo, bar', 'order'=>'baz ASC', 'limit'=>5, 'offset'=>3 ));