F3-fatfree小型php框架教程(六)数据库篇

既然是讲数据库的,那首先天然是链接数据库了。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
    ));
相关文章
相关标签/搜索