当前位置: 首页> 最新文章列表> 在 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,实现对数据库连接和语句属性的集中管理,使代码更清晰、可维护性更高。