模型和数据库(Models & Database)
模型在FuelPHP Web框架中起着重要作用。 它代表应用程序的业务实体。 它们由客户提供或从后端数据库中提取,根据业务规则进行操作并持久保存回数据库。 让我们在本章中了解模型以及它们如何与后端系统交互。
创建模型
在FuelPHP中,模型只是普通的PHP类,扩展了内置的Model类。 默认情况下,模型可以使用类似于控制器的Model_作为前缀,并且应该放在fuel/app/classes/model/文件夹中。 让我们创建一个基本的员工模型,并在我们继续时扩展它。
fuel/app/classes/model/employee.php
<?php
namespace Model;
class Model_Employee extends \Model {
public static function fetchAll() {
// Code to fetch employee from database
}
}
访问模型
一旦定义了模型,它就可以在任何控制器中自由使用,只需将其包含在控制器中,如下所示。
use \Model\Employee;
class Controller_Employee extends Controller {
public function action_index() {
$employees = Employee::fetchAll();
}
}
数据库概述
FuelPHP提供了自己的数据库抽象层来从数据库中获取数据。 它既提供基本的,也提供基于ORM的高级工具。 基本工具包包括基于DB,DBUtil和Query_Builer的类。 高级工具包是Orm。 Orm工具包源自基础工具包,并作为单独的包捆绑在一起。
数据库配置
FuelPHP将数据库设置与主配置文件分开,文件为fuel/app/config/db.php 。 它支持每个环境的单独设置。 目前,FuelPHP支持MySQL,MySQLi和PDO驱动程序。 样本设置如下 -
<?php
return array (
'development' => array (
'type' => 'mysqli',
'connection' => array (
'hostname' => 'localhost',
'port' => '3306',
'database' => 'xnip_fueldb',
'username' => 'root',
'password' => 'password',
'persistent' => false,
'compress' => false,
),
'identifier' => '`',
'table_prefix' => '',
'charset' => 'utf8',
'enable_cache' => true,
'profiling' => false,
'readonly' => false,
),
)
DB-based Toolkit
DB class是从应用程序访问数据库的最简单选项。 它提供了构建数据库查询的选项,针对目标数据库执行它,最后获取结果。 DB类与以下类交互并提供全面的数据库API。
Database_Connection - 与数据库交互的Singleton和主类
Database_Query - 用于执行SQL查询和获取结果的基础,具体类
Database_Query_Builder - 用于构建SQL查询的基础,抽象类
Database_Query_Builder_Join - 构建SQL连接的类
Database_Query_Builder_Where - 用于构建SQL查询条件的抽象类
Database_Query_Builder_Select - 用于构建SQL select查询的具体类
Database_Query_Builder_Insert - 构建SQL插入查询的抽象类
Database_Query_Builder_Update - 用于构建SQL更新查询的抽象类
Database_Query_Builder_Delete - 用于构建SQL删除查询的抽象类
下图描述了类与类提供的方法之间的关系。
DB API
让我们在本节中学习DB类中最重要的方法。
instance
Purpose - 创建并返回新的Database_Connection实例。
Parameter -
$db - 配置文件中定义的数据库连接名称,可选。
Returns - 返回Database_Connection对象
例如,
$db = DB::instance();
$db = DB::instance('test');
查询 (query)
Purpose - 准备提供的SQL语句并返回Database_Query对象,该对象可用于插入,更新,删除或从数据库中获取数据。
Parameter -
$query - SQL语句,可能包含占位符;
$type - SQL类型,可选(DB :: SELECT,DB :: INSERT,DB :: UPDATE和DB :: DELETE)
Returns - 返回Database_Query对象
例如,
$query = DB::query('SELECT * FROM 'employees'');
last_query
Purpose - 获取上次执行的查询
Parameter - 无
Returns - 返回上次执行的查询
例如,
$employees = DB::Select('Select * from 'employee'');
$sql = DB::last_query();
选择
Purpose - 生成查询的选择部分
Parameter -
$columns - 数据库列名列表
Returns - 返回Database_Query_Builder_Select对象
例如,
$query = DB::select(); // Select *
$query = DB::select('id', 'name'); // Select id, name
select_array (DB)
它与select类似,只是我们可以将列作为数组发送。
$query = DB::select_array(array('id', 'name')); // Select id, name
插入
Purpose - 生成查询的插入部分
Parameter -
$table_name - 数据库表的名称;
$columns - 表列数组
Returns - 返回Database_Query_Builder_Insert对象
例如,
$query = DB::insert('employee'); // Insert into employee
$query = DB::insert('employee', array('id', 'name')); // Insert into employee (id, name)
更新
Purpose - 生成查询的更新部分
Parameter -
$table_name - 数据库表的名称
Returns - 返回Database_Query_Builder_Update对象
例如,
$query = DB::update('employee'); // update `employee`
删除
Purpose - 生成查询的删除部分
Parameter -
$table_name - 数据库表的名称
Returns - 返回Database_Query_Builder_Delete对象
例如
$query = DB::delete('employee'); // delete from 'employee'
查询API
Database_Query提供了一个选项来设置数据库连接,执行查询,并将结果作为关联数组或对象获取。 让我们看看Database_Query类提供的方法。
set_connection
Purpose - 设置执行查询的数据库(数据库连接详细信息)
Parameter - $ db - 数据库连接名称
Returns - 返回Database_Query对象
例如,
$query = DB::query('DELETE * FROM employee', DB::DELETE);
$query->set_connection('2nd-db');
param
Purpose - 设置Query对象中定义的参数的值
Parameter -
$param - 参数名称;
$value - 参数的值
Returns - 返回Database_Query对象
例如,
// set some variables
$table = 'employee';
$id = 1;
$name = 'Jon';
// don't use
$query = DB::query('SELECT * FROM '.$table.'. WHERE id = '.$id.' AND name = "'.$name.'"');
// but use
$query = DB::query('SELECT * FROM :tablename WHERE id = :id AND name = :name');
$query->param('tablename', 'employee');
$query->param('id', $id);
$query->param('name', $name);
类似方法
parameters是一个类似的对象,除了它提供了一次赋予多个值的选项。
$query->parameters (array(
'tablename' => $table,
'id' => $id,
'name' => $name
});
bind
Purpose - 将变量设置为Query对象中定义的参数
Parameter -
$param - 参数名称
$var - 将参数绑定到的变量
Returns - 返回Database_Query对象
例如,
// bind a query parameter
$table = 'employee';
$query = DB::query('DELETE * FROM :tablename', DB::DELETE);
$query->bind('tablename', $table);
// update the variable
$table = 'employee_salary';
// DELETE * FROM `employee_salary`;
$sql = $query->compile();
compile
Purpose - 编译定义到SQL查询中的查询对象
Parameter -
$db - 连接字符串,可选
Returns -
例如,
// assign a value to a query parameter
$table = 'employee';
$query = DB::query('DELETE * FROM :tablename', DB::DELETE);
$query->param('tablename', $table);
// compile the query, returns: DELETE * FROM employee
$sql = $query->compile();
执行
Purpose - 执行Query对象中定义的查询并返回结果
Parameter -
$db - 数据库连接名称
Returns - 返回结果
例如,
// assign a value to a query parameter
$table = 'employee';
$query = DB::query('DELETE * FROM :tablename', DB::DELETE);
$query->param('tablename', $table);
// execute the query
$query->execute();
as_assoc
Purpose - 将返回类型设置为关联数组而不是对象
Parameter - 无
Returns - 返回当前对象
例如,
$query = DB::query('SELECT * FROM employee', DB::SELECT);
$result = $query->as_assoc()->execute();
foreach ($result as $row) {
echo $row['id'];
}
as_object
Purpose - 将返回类型设置为对象而不是关联数组
Parameter - 无
Returns - 返回当前对象
例如,
$query = DB::query('SELECT * FROM employee', DB::SELECT);
$result = $query->as_object()->execute();
foreach ($result as $row) {
echo $row->id;
}
// have ORM model objects return instead
$result = $query->as_object('Model_Employee')->execute();
Query Builder API
基于查询构建器(Query_Builder)的类提供了动态构建SQL查询的选项。 它有四个类,每个类都选择(Query_Builder_Select) ,insert (Query_Builder_Insert) ,update (Query_Builder_Update)和delete (Query_Builder_Delete)查询。 这些类派生自Query_Builder_Where类(生成条件的选项),它本身派生自Query_Builder ,是所有类的基础。
我们来看看Query_Builder类提供的方法。
选择
Purpose - 生成选择查询的列。
Parameter -
$columns - $columns列表,可选
Returns - 返回当前实例
例如,
$query = DB::select('name') // select `name`
$query = DB::select(array('first_name', 'name')) // select `first_name` as `name`
from
Purpose - 生成选择查询的表详细信息
Parameter -
$tables - $tables列表
Returns - 返回当前实例
例如,
$query = DB::select('name')->from('employee') // select `name` from `employee`
where
Purpose - 生成选择,插入和更新查询的条件
Parameters -
$column - 列名或数组($ column,$ alias);
$op - logic运算符,=,!=,IN,BETWEEN和LIKE,可选;
$value - 列值
Returns - 返回当前实例
例如,
$query = DB::select('name')->from('employee')
$query = $query->where('name', '=', 'Jon');
// select `name` from `employee` where `name` = `Jon`;
类似方法
类似的方法是where_open(),and_where_open(),or_where_open(),where_close(),and_where_close(),or_where_close()。 它们类似于where()方法,除了它们在条件周围添加额外的关键字和括号。 以下是示例代码。
$query = DB::select('*')->from('employee');
$query->where('email', 'like', '%@gmail.com');
$query->or_where_open();
$query->where('name', 'Jon');
$query->and_where('surname', 'Peter');
$query->or_where_close();
// SELECT * FROM `employee` WHERE `email` LIKE "%gmail.com" OR
(`name` = "Jon" AND `surname` = "Peter")
join
Purpose - 生成选择查询的表连接
Parameters -
$table - 表名或数组($ table,$ alias);
$type - 连接类型(LEFT,RIGHT,INNER等)
Returns - 返回当前实例
例
$query = DB::select('name')->from('employee')->join('employee_salary')
// select `name` from `employee` JOIN `employee_salary`
on
Purpose - 在选择查询中生成联接条件
Parameters -
$c1 - 包含别名的表名或表名;
$op - 逻辑运算符;
$c2 - 包含数组别名的表名或表名
Returns - 返回当前实例
例如,
$query = DB::select('name')->from('employee')->join('employee_salary')
$query = $query->on('employee.employee_id', '=', 'employee_salary.employee_id')
// select `name` from `employee` JOIN `employee_salary` on
// `employee.employee_id` = `employee_salary.employee_id`
类似方法
相关方法是and_on()和or_on()。 它们类似于on(),除了它们在连接周围添加额外的关键字和括号。
group_by
Purpose - 按查询生成组
Parameter - $columns - 用于对结果进行分组的列名
Returns - 返回当前实例
例如,
$query = DB::select('name')->from('employee')
$query = $query->group_by('name');
// select `name` from `employee` group by `name`
having
Purpose - 根据SQL查询条件生成组
Parameter - $column - 列名或数组($ column,$ alias); $op - logic运算符,=,!=,IN,BETWEEN和LIKE,可选; $value - 列值
Returns - 返回当前实例
例
$query = DB::select('name')->from('employee')
$query = $query->group_by('name');
$query = $query->having('name', '!=', 'Jon');
// select `name` from `employee` group by `name` having `name` != `Jon`
类似方法
类似的方法是having_open(),and_having_open(),or_having_open(),having_close(),and_having_close(),or_having_close()。 它们类似于having()方法,除了它们在条件周围添加额外的关键字和括号。
重置 (reset)
Purpose - 重置查询
Parameter - 无
Returns - 返回当前实例
例如,
$query = DB::select('name')->from('employee')
$query->reset()
$query = DB::select('name')->from('employee_salary')
// select `name` from `employee_salary`
DBUtil类
DBUtil类提供了管理和执行例行数据库操作的选项。 一些重要的方法如下 -
- set_connection - 设置默认连接
DBUtil::set_connection('new_database');
- create_database - 创建数据库。
DBUtil::create_database('my_database');
- drop_database - 删除数据库。
DBUtil::drop_database('my_database');
- table_exists - 检查给定的表是否存在。
if(DBUtil::table_exists('my_table')) {
// Table exists
} else {
// Table does NOT exist, create it!
}
- drop_table - 删除表。
DBUtil::drop_table('my_table');
- create_table - 创建一个表。
\DBUtil::create_table (
'users',
array (
'id' => array('type' => 'int', 'auto_increment' => true),
'name' => array('type' => 'text'),
),
);
Orm Toolkit
FuelPHP使用基于流行的Active record pattern ORM概念提供高级数据库层。 该工具包包含在应用程序中,但默认情况下未配置。 它捆绑为一个包,包名称是orm。 我们可以在主配置文件fuel/app/config/config.php添加以下配置来加载orm工具包。
'always_load' => array (
'packages' => array (
'orm',
),
),
创建模型
Orm提供基础模型类Orm\Model。 我们需要使用orm模型扩展我们的模型以使用ORM功能。 以下是示例代码。
class Model_Employee extends Orm\Model {}
配置 (Configuration)
Orm提供了一组设置来配置模型以使用ORM功能。 它们如下 -
connection - 在模型中设置static _connection属性以指定连接名称。
class Model_Employee extends Orm\Model {
protected static $_connection = "production";
}
table name - 在模型中设置静态_table_name属性以指定后端表的表名。
class Model_Employee extends Orm\Model {
protected static $_table_name = 'employee';
}
primary key - 在模型中设置静态_primary_key属性以指定后端表的主键。
class Model_Employee extends Orm\Model {
protected static $_primary_key = array('id');
}
Columns - 在模型中设置静态_properties属性以指定后端表的列。 它支持data_type,label,validation,form elememts等。
class Model_Employee extends Orm\Model {
protected static $_properties = array (
'id',
'name' => array (
'data_type' => 'varchar',
'label' => 'Employee Name',
'validation' => array (
'required',
'min_length' => array(3),
'max_length' > array(80)
),
'form' => array (
'type' => 'text'
),
),
'age' => array (
'data_type' => 'int',
'label' => 'Employee Age',
'validation' => array (
'required',
),
'form' => array (
'type' => 'text'
),
),
);
}
Conditions - 设置静态_conditions属性以按选项设置条件和顺序。
class Model_Employee extends Orm\Model {
protected static $_conditions = array (
'order_by' => array('id' => 'desc'),
'where' => array (
array('is_active', > true),
),
);
}
Observers - Orm提供基于观察者的事件系统来向特定事件添加行为。 要添加行为,请首先在模型中设置_observers属性。 然后,将行为定义为类,并将其与事件一起设置在_observers属性中。 如果未指定任何事件,则将为所有事件调用该行为。 我们也可以指定多个行为。
class Model_Employee {
protected static $_observers = array (
'example', // will call Observer_Example class for all events
'Orm\\Observer_CreatedOn' => array (
'events' => array('before_insert'),
// will only call Orm\Observer_CreatedOn at before_insert event
)
);
}
Create
一旦我们配置了模型,我们就可以立即开始使用这些方法。 Orm提供了一种将对象保存到数据库中的save方法。 我们可以使用配置属性设置数据,如下所示 -
// option 1
$new = new Model_Employee();
$new->name = 'Jon';
$new->save();
// option 2, use forge instead of new
$new = Model_Employee::forge();
$new->name = 'Jon';
$new->save();
// option 3, use array for properties
$props = array('name' => 'Jon');
$new = Model_Employee::forge($props);
$new>save();
Read
Orm提供了一个方法,find从数据库中获取数据并绑定到对象中。 find方法根据输入参数工作。 让我们看看不同的选择 -
by primary key - 指定主键通过匹配已配置表的主键来返回记录。
$employee = Model_Employee::find(1);
first/last record - 指定'first'或'last'将分别获取第一条记录或最后一条记录。 我们也可以通过选项传递订单。
$entry = Model_Employee::find('first');
$entry = Model_Article::find('last', array('order_by' => 'id'));
All - 指定“全部”将从配置的表中获取所有记录。 我们可以通过选项和条件指定订单。
$entry = Model_Employee::find('all');
$entry = Model_Article::find ('all', array (
'where' => array (
array ('name', 'Jon'),
),
'order_by' => array ('id' => 'desc'),
));
我们可以使用基本数据库工具包的查询API以及高级搜索选项的模型如下。
$query = Model_Employee::query()->where('category_id', 1)->order_by('date', 'desc');
$number_of_employees = $query->count();
$latest_employee = $query->max('id');
$young_employee = $query->min('age');
$newest_employee = $query->get_one();
$employees = $query->limit(15)->get();
更新 (Update)
更新模型与创建相同,除了创建新模型而不是使用find方法获取要更新的模型,更新属性然后按如下方式调用save方法。
$entry = Model_Employee:find(4);
$entry->name = 'Peter';
$entry->save();
删除 (Delete)
Orm提供删除方法来删除模型。 只需获取对象并调用delete方法即可。
$entry = Model_Employee:find(4);
$entry->delete();
工作示例 (Working Example)
让我们在本章中创建一个工作示例来理解模型和数据库。
创建数据库
使用以下命令在MySQL服务器中创建新数据库。
create database xnip_fueldb
然后,使用以下命令在数据库中创建一个表。
create table employee(id int primary key, name varchar(20), age int not null);
配置数据库
让我们使用数据库配置文件* fuel/app/config/db.php配置数据库。 添加以下更改以连接MySQL服务器。
<?php
return array (
'development' => array (
'type' => 'mysqli',
'connection' => array (
'hostname' => 'localhost',
'port' => '3306',
'database' => 'xnip_fueldb',
'username' => 'root',
'password' => 'pass',
'persistent' => false,
'compress' => false,
),
'identifier' => '`',
'table_prefix' => '',
'charset' => 'utf8',
'enable_cache' => true,
'profiling' => false,
'readonly' => false,
),
'production' => array (
'type' => 'mysqli',
'connection' => array (
'hostname' => 'localhost',
'port' => '3306',
'database' => 'xnip_fueldb',
'username' => 'root',
'password' => 'pass',
'persistent' => false,
'compress' => false,
),
'identifier' => '`',
'table_prefix' => '',
'charset' => 'utf8',
'enable_cache' => true,
'profiling' => false,
'readonly' => false,
),
);
包括ORM包
通过添加以下配置更新主配置文件fuel/app/config/config.php以包含ORM包。
'always_load' => array (
'packages' => array (
'orm'
),
),
现在,在您的应用程序中启用了ORM
创建员工模型
在模型文件夹“fuel/app/classes/model”下创建一个新模型Employee。 它的定义如下。
Employee.php
<?php
class Model_Employee extends Orm\Model {
protected static $_connection = 'production';
protected static $_table_name = 'employee';
protected static $_primary_key = array('id');
protected static $_properties = array (
'id',
'name' => array (
'data_type' => 'varchar',
'label' => 'Employee Name',
'form' => array (
'type' => 'text'
),
),
'age' => array (
'data_type' => 'int',
'label' => 'Employee Age',
'form' => array (
'type' => 'text'
),
),
);
}
创建动作
在位于fuel/app/classes/controller/employee.php Employee控制器中创建新操作action_model ,如下所示。
class Controller_Employee extends Controller {
public function action_model() {
// db based sql command to delete all employees
$query = db::query('delete from `employee`');
$query->execute('production');
// orm based query to add new employees
$model = new model_employee();
$model->name = "john";
$model->age = 25;
$model->save();
$model = new model_employee();
$model->name = "peter";
$model->age = 20;
$model->save();
// orm based query to fetch all employee data
$data = array();
$data['emps'] = model_employee::find('all');
return response::forge(view::forge('employee/model', $data));
}
}
创建视图
现在,创建一个位于“fuel/app/views/employee”的视图文件model.php 。 在文件中添加以下更改。
<ul>
<?php
foreach($emps as $emp) {
?>
<li><?php echo $emp['name']; ?></li>
<?php
}
?>
</ul>
现在,请求URL, http://localhost:8080/employee/model ,它将产生以下结果。