在使用Laravel 進行PHP 開發時,框架默認使用Eloquent ORM 和PDO 進行數據庫操作。然而,在某些場景中,出於兼容性或性能的考慮,開發者可能會直接使用mysqli擴展提供的函數與數據庫交互。 mysqli_stmt::attr_get是mysqli_stmt類的一個方法,用於獲取語句屬性,這在調試或者精細化管理數據庫連接行為時非常有用。
為了在Laravel 項目中更方便地使用mysqli_stmt::attr_get ,我們可以對其進行封裝,統一管理數據庫連接與語句處理邏輯。以下是具體的封裝方案和實現步驟。
首先,我們可以在Laravel 項目中創建一個用於封裝原生mysqli操作的服務類,例如MysqliService 。
在app/Services目錄下創建文件MysqliService.php :
<?php
namespace App\Services;
class MysqliService
{
protected $mysqli;
public function __construct()
{
$this->connect();
}
protected function connect()
{
$this->mysqli = new \mysqli(
env('DB_HOST', 'localhost'),
env('DB_USERNAME', 'root'),
env('DB_PASSWORD', ''),
env('DB_DATABASE', 'forge'),
env('DB_PORT', 3306)
);
if ($this->mysqli->connect_error) {
throw new \Exception('Connect Error (' . $this->mysqli->connect_errno . ') ' . $this->mysqli->connect_error);
}
}
public function prepare($query)
{
$stmt = $this->mysqli->prepare($query);
if (!$stmt) {
throw new \Exception('Prepare failed: ' . $this->mysqli->error);
}
return $stmt;
}
public function getStatementAttribute($stmt, int $attr)
{
if (!($stmt instanceof \mysqli_stmt)) {
throw new \InvalidArgumentException('Invalid statement object provided.');
}
return $stmt->attr_get($attr);
}
public function close()
{
if ($this->mysqli) {
$this->mysqli->close();
}
}
}
為了在控制器或其它類中使用MysqliService ,可以在AppServiceProvider中進行服務綁定。
編輯app/Providers/AppServiceProvider.php :
use App\Services\MysqliService;
public function register()
{
$this->app->singleton(MysqliService::class, function ($app) {
return new MysqliService();
});
}
現在我們可以在控制器中直接使用MysqliService ,並調用getStatementAttribute方法來獲取語句屬性。
示例代碼如下:
use App\Services\MysqliService;
class DatabaseController extends Controller
{
protected $mysqliService;
public function __construct(MysqliService $mysqliService)
{
$this->mysqliService = $mysqliService;
}
public function showAttribute()
{
$stmt = $this->mysqliService->prepare("SELECT * FROM users WHERE email = ?");
$stmt->bind_param("s", $email);
$email = "test@m66.net";
$stmt->execute();
// 假設我們要獲取 MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH 屬性
$attrValue = $this->mysqliService->getStatementAttribute($stmt, MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH);
$stmt->close();
$this->mysqliService->close();
return response()->json(['attribute_value' => $attrValue]);
}
}
attr_get是mysqli_stmt的一個相對較少使用的方法,並非所有PHP 環境都默認啟用該擴展方法。在部署前應確認其可用性。
如果你在Laravel 中大量使用原生mysqli操作,建議將其封裝為服務層,並考慮日誌記錄與異常處理,以保證系統的健壯性。
雖然mysqli在某些場景下具備更底層的控制能力,但Laravel 的Eloquent 和Query Builder 提供了更高層級的抽象,在大多數情況下更適合日常開發。
通過上述封裝方式,我們可以在Laravel 中優雅地調用mysqli_stmt::attr_get ,實現對數據庫連接和語句屬性的集中管理,使代碼更清晰、可維護性更高。