當前位置: 首頁> 最新文章列表> 在Laravel 中如何封裝attr_get 使用

在Laravel 中如何封裝attr_get 使用

M66 2025-05-22

在使用Laravel 進行PHP 開發時,框架默認使用Eloquent ORM 和PDO 進行數據庫操作。然而,在某些場景中,出於兼容性或性能的考慮,開發者可能會直接使用mysqli擴展提供的函數與數據庫交互。 mysqli_stmt::attr_getmysqli_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_getmysqli_stmt的一個相對較少使用的方法,並非所有PHP 環境都默認啟用該擴展方法。在部署前應確認其可用性。

  • 如果你在Laravel 中大量使用原生mysqli操作,建議將其封裝為服務層,並考慮日誌記錄與異常處理,以保證系統的健壯性。

  • 雖然mysqli在某些場景下具備更底層的控制能力,但Laravel 的Eloquent 和Query Builder 提供了更高層級的抽象,在大多數情況下更適合日常開發。

通過上述封裝方式,我們可以在Laravel 中優雅地調用mysqli_stmt::attr_get ,實現對數據庫連接和語句屬性的集中管理,使代碼更清晰、可維護性更高。