FuelPHP - 模型和数据库


模型在 FuelPHP Web 框架中发挥着重要作用。它代表应用程序的业务实体。它们要么由客户提供,要么从后端数据库获取,根据业务规则进行操作并保留回数据库中。让我们在本章中了解模型以及它们如何与后端系统交互。

创建模型

在 FuelPHP 中,模型只是扩展内置 Model 类的普通 PHP 类。默认情况下,模型可能以类似于控制器的 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 删除查询的抽象类

下图描述了类之间的关系以及类提供的方法。

类和方法

数据库接口

让我们在本节中学习 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'');

最后查询

  • 目的- 获取最后执行的查询

  • 参数- 无

  • 返回- 返回最后执行的查询

例如,

$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 类似,只是我们可以将列作为数组发送。

$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类提供的方法。

设置连接

  • 目的- 设置要执行查询的数据库(数据库连接详细信息)

  • 参数- $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);

类似的方法

参数是一个类似的对象,只不过它提供了一次给出多个值的选项。

$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(); 

执行

  • 目的- 执行 Query 对象中定义的查询并返回结果

  • 参数-

    • $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']; 
}

作为对象

  • 目的- 将返回类型设置为对象而不是关联数组

  • 参数- 无

  • 返回- 返回当前对象

例如,

$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类提供的方法。

选择

  • 目的- 生成选择查询的列。

  • 参数-

    • $columns - 列列表,可选

  • 返回- 返回当前实例

例如,

$query = DB::select('name')  // select `name` 
$query = DB::select(array('first_name', 'name')) // select `first_name` as `name`

  • 目的- 生成选择查询的表详细信息

  • 参数-

    • $tables - 表列表

  • 返回- 返回当前实例

例如,

$query = DB::select('name')->from('employee') // select `name` from `employee`

在哪里

  • 目的- 生成选择、插入和更新查询的条件

  • 参数-

    • $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")

加入

  • 目的- 生成选择查询的表连接

  • 参数-

    • $table - 表名或数组($table, $alias);

    • $type - 连接类型(LEFT、RIGHT、INNER 等)

  • 返回- 返回当前实例

例子

$query = DB::select('name')->from('employee')->join('employee_salary') 
// select `name` from `employee` JOIN `employee_salary`

  • 目的- 生成选择查询中的联接条件

  • 参数-

    • $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() 类似,只是它们在连接周围添加了额外的关键字和括号。

通过...分组

  • 目的- 生成分组查询

  • 参数- $columns - 用于对结果进行分组的列名称

  • 返回- 返回当前实例

例如,

$query = DB::select('name')->from('employee')  
$query = $query->group_by('name'); 
// select `name` from `employee` group by `name`

拥有

  • 目的- 生成 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_having_open()、or_having_open()、having_close()、and_having_close()、or_having_close()。它们与having()方法类似,只是它们在条件周围添加了额外的关键字和括号。

重置

  • 目的- 重置查询

  • 参数- 无

  • 返回- 返回当前实例

例如,

$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'), 
   ), 
); 

奥姆工具包

FuelPHP 使用基于流行的Active record 模式的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 {}

配置

Orm 提供了一组设置来配置模型以使用 ORM 功能。它们如下 -

连接-在模型中设置静态_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属性以指定后端表的主键。

class Model_Employee extends Orm\Model { 
   protected static $_primary_key = array('id'); 
} 

- 在模型中设置静态 _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), 
      ), 
   ); 
}

观察者- Orm提供基于观察者的事件系统来向特定事件添加Behave。要添加Behave,首先在模型中设置_observers属性。然后,将Behave定义为一个类,并将其与事件一起设置在_observers属性中。如果未指定事件,则将为所有事件调用该Behave。我们也可以指定多种Behave。

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 
      ) 
   ); 
} 

创造

一旦我们配置了模型,我们就可以立即开始使用这些方法。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();

Orm提供了一个方法find从数据库中获取数据并绑定到对象中。find 方法的工作原理取决于输入参数。让我们看看不同的选项 -

by Primary key - 指定主键通过匹配配置表的主键返回记录。

$employee = Model_Employee::find(1);

第一个/最后一个记录- 指定“第一个”或“最后一个”将分别获取第一条记录或最后一条记录。我们也可以通过选项传递订单。

$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提供了delete方法来删除模型。只需获取对象并调用删除方法即可。

$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 。它的定义如下。

员工.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,它将产生以下结果。

结果

创建视图