FuelPHP - 模型與資料庫



模型在 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'    => 'tutorialspoint_fueldb', 
            'username'    => 'root', 
            'password'    => 'password', 
            'persistent'  => false, 
            'compress'    => false, 
         ), 
         
         'identifier'     => '`', 
         'table_prefix'   => '', 
         'charset'        => 'utf8', 
         'enable_cache'   => true, 
         'profiling'      => false, 
         'readonly'       => false, 
      ), 
   )

基於 DB 的工具包

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 刪除查詢的抽象類

下圖描述了類之間的關係以及類提供的方法。

Classes and Methods

DB API

在本節中,讓我們學習 DB 類中可用的最重要方法。

instance

  • 用途 - 建立並返回新的 Database_Connection 例項。

  • 引數 -

    • $db - 配置檔案中定義的資料庫連線名稱,可選。

  • 返回值 - 返回 Database_Connection 物件

例如,

$db = DB::instance(); 
$db = DB::instance('test');

query

  • 用途 - 準備提供的 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

  • 用途 - 獲取最後執行的查詢

  • 引數 - 無

  • 返回值 - 返回最後執行的查詢

例如,

$employees = DB::Select('Select * from 'employee''); 
$sql = DB::last_query();

select

  • 用途 - 生成查詢的選擇部分

  • 引數 -

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

insert

  • 用途 - 生成查詢的插入部分

  • 引數 -

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

update

  • 用途 - 生成查詢的更新部分

  • 引數 -

    • $table_name - 資料庫表名

  • 返回值 - 返回 Database_Query_Builder_Update 物件

例如,

$query = DB::update('employee'); // update `employee`

delete

  • 用途 - 生成查詢的刪除部分

  • 引數 -

    • $table_name - 資料庫表名

  • 返回值 - 返回 Database_Query_Builder_Delete 物件

例如

$query = DB::delete('employee');  // delete from 'employee'

Query API

Database_Query 提供了一個選項來設定資料庫連線、執行查詢並將結果作為關聯陣列或物件獲取。讓我們看看 Database_Query 類提供的方法。

set_connection

  • 用途 - 設定要針對其執行查詢的資料庫(資料庫連線詳細資訊)

  • 引數 - $db - 資料庫連線名稱

  • 返回值 - 返回 Database_Query 物件

例如,

$query = DB::query('DELETE * FROM employee', DB::DELETE); 
$query->set_connection('2nd-db');

param

  • 用途 - 設定 Query 物件中定義的引數的值

  • 引數 -

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

bind

  • 用途 - 將變數設定為 Query 物件中定義的引數

  • 引數 -

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

compile

  • 用途 - 將定義的 Query 物件編譯成 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(); 

execute

  • 用途 - 執行 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']; 
}

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

Query Builder API

基於 Query builder (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

  • 用途 - 生成 group by 查詢

  • 引數 - $columns - 要根據其對結果進行分組的列名

  • 返回值 - 返回當前例項

例如,

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

having

  • 用途 - 生成 SQL 查詢的 group by 條件

  • 引數 - $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() 方法,除了它們在條件周圍新增額外的關鍵字和括號。

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 提供了基於流行的**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 提供了基於觀察者的事件系統,以便為特定事件新增行為。要新增行為,首先在模型中設定一個 _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 
      ) 
   ); 
} 

建立

一旦我們配置了模型,就可以直接開始使用這些方法了。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 方法根據輸入引數工作。讓我們看看不同的選項:

**按主鍵** - 指定主鍵將透過匹配配置表的自主鍵返回記錄。

$employee = Model_Employee::find(1);

**第一/最後一條記錄** - 指定“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'), 
));

我們可以將基本資料庫工具包的 Query 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 方法來刪除模型。只需獲取物件並呼叫 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。它定義如下。

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 **https://:8080/employee/model**,它將產生以下結果。

結果

Create View
廣告

© . All rights reserved.