FuelPHP 模型和数据库
模型在 FuelPHP Web 框架中扮演着重要的角色。它代表应用程序的业务实体。它们要么由客户提供,要么从后端数据库获取,根据业务规则进行操作并持久化回数据库中。让我们在本章中了解模型以及它们如何与后端系统交互。
创建模型
在 FuelPHP 中,模型只是简单的 PHP 类扩展内置模型类。默认情况下,模型可能以 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' => 'tutorialspoint_fueldb', 'username' => 'root', 'password' => 'password', 'persistent' => false, 'compress' => false, ), 'identifier' => '`', 'table_prefix' => '', 'charset' => 'utf8', 'enable_cache' => true, 'profiling' => false, 'readonly' => false, ), )
基于数据库的工具包
DB 类 是从应用程序访问数据库的最简单选项。它提供了构建数据库查询、针对目标数据库执行并最终获取结果的选项。 DB 类与以下类交互并提供全面的数据库 API。
- Database_Connection-与数据库交互的单例和主类
- Database_Query-执行 SQL 查询和获取结果的基础、具体类
- Database_Query_Builder-构建 SQL 查询的基础抽象类
- Database_Query_Builder_Join-构建 SQL 连接的类
- Database_Query_Builder_Where-构建 SQL 查询条件的抽象类
- Database_Query_Builder_Select-构建 SQL 选择查询的具体类
- Database_Query_Builder_Insert-构建 SQL 插入查询的抽象类
- Database_Query_Builder_Update-构建 SQL 更新查询的抽象类
- Database_Query_Builder_Delete-构建 SQL 删除查询的抽象类
下图描述了类和类提供的方法之间的关系。
数据库 API
让我们在本节中学习 DB 类中可用的最重要的方法。
实例
- 目的-创建并返回新的 Database_Connection 实例。
- 参数-
- $db-配置文件中定义的数据库连接名称,可选。
- 返回-返回Database_Connection 对象
例如
$db = DB::instance(); $db = DB::instance('test');
查询
- 目的-准备提供的 SQL 语句并返回 Database_Query 对象,该对象可用于插入、更新、删除或从数据库中获取数据。
- 参数-
- $query-SQL 语句,可能包含占位符;
- $type-SQL 类型,可选(DB::SELECT、DB::INSERT、DB::UPDATE 和 DB::DELETE)
- 返回-返回Database_Query 对象
例如
$query = DB::query('SELECT * FROM 'employees'');
last_query
- 目的-获取最后执行的查询
- 参数-无
- Returns-返回最后执行的查询
例如
$employees = DB::Select('Select * from 'employee''); $sql = DB::last_query();
选择
- 目的-生成查询的选择部分
- 参数-
- $columns-数据库列名列表
- 返回-返回 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
插入
- 目的-生成查询的插入部分
- 参数-
- $table_name-数据库表的名称;
- $columns-表列数组
- 返回-返回 Database_Query_Builder_Insert 对象
例如
$query = DB::insert('employee'); // Insert into employee $query = DB::insert('employee', array('id', 'name')); // Insert into employee (id, name)
更新
- 目的-生成查询的更新部分
- 参数-
- $table_name-数据库表名
- 返回-返回 Database_Query_Builder_Update 对象
例如
$query = DB::update('employee'); // update `employee`
删除
- 目的-生成查询的删除部分
- 参数-
- $table_name-数据库表名
- 返回-返回 Database_Query_Builder_Delete 对象
例如
$query = DB::delete('employee'); // delete from 'employee'
查询接口
Database_Query 提供了一个选项来设置数据库连接、执行查询并将结果作为关联数组或对象获取。让我们看看 Database_Query 类提供的方法。
set_connection
- 目的-设置对其执行查询的数据库(数据库连接详细信息)
- 参数-$db-数据库连接名称
- 返回-返回Database_Query 对象
例如
$query = DB::query('DELETE * FROM employee', DB::DELETE); $query->set_connection('2nd-db');
参数
- 目的-设置查询对象中定义的参数值
- 参数-
- $param-参数名称;
- $value-参数的值
- 返回-返回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 });
绑定
- 目的-将变量设置为查询对象中定义的参数
- 参数-
- $param-参数名称
- $var-将参数绑定到的变量
- 返回-返回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();
编译
- 目的-将定义的查询对象编译为 SQL 查询
- 参数-
- $db-连接字符串,可选
- 退货-
例如
// 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();
执行
- 目的-执行查询对象中定义的查询并返回结果
- 参数-
- $db-数据库连接名称
- 返回-返回结果
例如
// 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
- 目的-将返回类型设置为关联数组而不是对象
- 参数-无
- 返回-返回当前对象
例如
$query = DB::query('SELECT * FROM employee', DB::SELECT); $result = $query->as_assoc()->execute(); foreach ($result as $row) { echo $row['id']; }
as_object
- 目的-将返回类型设置为对象而不是关联数组
- 参数-无
- 返回-返回当前对象
例如
$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();
查询生成器 API
查询构建器 (Query_Builder) 基于类提供动态构建 SQL 查询的选项。它有四个类,每个类选择 (Query_Builder_Select)、插入 (Query_Builder_Insert)、更新 (Query_Builder_Update)和删除 (Query_Builder_Delete ) 查询。这些类派生自 Query_Builder_Where 类(生成条件的选项),该类本身派生自所有类的基础 Query_Builder。
让我们看看 Query_Builder 类提供的方法。
select
- 目的-生成选择查询的列。
- 参数-
- $columns-列列表,可选
- 返回-返回当前实例
例如
$query = DB::select('name') // select `name` $query = DB::select(array('first_name', 'name')) // select `first_name` as `name`
from
- 目的-生成选择查询的表详细信息
- 参数-
- $tables-表格列表
- 返回-返回当前实例
例如
$query = DB::select('name')->from('employee') // select `name` from `employee`
where
- 目的-生成选择、插入和更新查询的条件
- 参数-
- $column-列名或数组 ($column, $alias);
- $op-逻辑运算符,=、!=、IN、BETWEEN 和 LIKE,可选;
- $value-列值
- 返回-返回当前实例
例如
$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
- 目的-生成选择查询的表连接
- 参数-
- $table-表名或数组($table, $alias);
- $type-连接类型(LEFT、RIGHT、INNER 等)
- 返回-返回当前实例
示例:
$query = DB::select('name')->from('employee')->join('employee_salary') // select `name` from `employee` JOIN `employee_salary`
on
- 目的-在选择查询中生成连接条件
- 参数-
- $c1-表名或在数组中有别名的表名;
- $op-逻辑运算符;
- $c2-表名或在数组中有别名的表名
- 返回-返回当前实例
例如
$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
- 目的-按查询生成分组
- 参数-$columns-用于对结果进行分组的列名
- 返回-返回当前实例
例如
$query = DB::select('name')->from('employee') $query = $query->group_by('name'); // select `name` from `employee` group by `name`
having
- 目的-根据 SQL 查询条件生成分组
- 参数-$column-列名或数组( $column, $alias ); $op-逻辑运算符,=、!=、IN、BETWEEN 和 LIKE,可选; $value-列值
- 返回-返回当前实例
示例:
$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_sharing_open()、or_sharing_open()、has_have_close()、and_sharing_close()、or_sharing_close()。除了它们在条件周围添加额外的关键字和括号之外,它们与 have() 方法类似。
reset
- 目的-重置查询
- 参数-无
- 返回-返回当前实例
例如
$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 工具包
FuelPHP 使用基于流行的 活动记录模式的 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-在模型中设置静态 _connection 属性以指定连接名称。
class Model_Employee extends Orm\Model { protected static $_connection = "production"; }
表名-在模型中设置静态 _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 属性以指定后端表的列。支持数据类型、标签、验证、表单元素等
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 属性以设置条件和按选项排序。
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-指定"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();
更新
更新模型与创建模型相同,只是不是创建新模型,而是使用 find 方法获取要更新的模型,更新属性,然后调用 save 方法,如下所示。
$entry = Model_Employee:find(4); $entry->name = 'Peter'; $entry->save();
删除
Orm 提供了删除模型的删除方法。只需获取对象并调用删除方法即可。
$entry = Model_Employee:find(4); $entry->delete();
工作示例
让我们在本章中创建一个工作示例来了解模型和数据库。
创建数据库
使用以下命令在 MySQL 服务器中创建一个新数据库。
create database tutorialspoint_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' => 'tutorialspoint_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' => 'tutorialspoint_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' ), ), ); }
Create Action
在位于 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,它将产生以下结果。
结果
下一章:FuelPHP 表单编程
FuelPHP 提供了三个类, Form Fieldset 和 Input,用于执行表单编程。Form 类提供了创建所有 HTML 表单元素的选项。Fieldset 类提供了通过更高级别的方法创建 ht ...