當前位置: 首頁> 最新文章列表> Symfony 中通過自定義擴展使用attr_get

Symfony 中通過自定義擴展使用attr_get

M66 2025-06-02

在使用Symfony 開發高性能Web 應用時,底層數據庫交互大多通過Doctrine ORM 完成。但在某些特定場景中,例如性能調優或兼容遺留系統時,直接使用mysqli函數成為更合適的選擇。本文將介紹如何在Symfony 中通過自定義PHP 擴展來使用mysqli_stmt::attr_get函數。

1. 理解mysqli_stmt::attr_get函數

mysqli_stmt::attr_getmysqli_stmt類的一個方法,用於獲取已準備語句的某個屬性的值。該函數的典型用法如下:

 $stmt = $mysqli->prepare("SELECT * FROM users WHERE id = ?");
$value = $stmt->attr_get(MYSQLI_STMT_ATTR_CURSOR_TYPE);

不過,在很多PHP 構建環境中,該方法並未默認暴露或可能被忽略。這種情況下,我們可以通過自定義擴展的方式來補足這一功能。

2. 創建自定義PHP 擴展

為了在Symfony 中無縫調用attr_get方法,我們需要構建一個簡單的PHP 擴展:

2.1 擴展代碼結構

創建如下目錄結構:

 php-ext-mysqli-attr/
├── config.m4
├── mysqli_attr.c
└── php_mysqli_attr.h

2.2 編寫擴展代碼

config.m4

 PHP_ARG_ENABLE(mysqli_attr, whether to enable mysqli_attr support,
[  --enable-mysqli_attr     Enable mysqli_attr support])

if test "$PHP_MYSQLI_ATTR" = "yes"; then
  PHP_NEW_EXTENSION(mysqli_attr, mysqli_attr.c, $ext_shared)
fi

php_mysqli_attr.h

 #ifndef PHP_MYSQLI_ATTR_H
#define PHP_MYSQLI_ATTR_H

extern zend_module_entry mysqli_attr_module_entry;
#define phpext_mysqli_attr_ptr &mysqli_attr_module_entry

#endif

mysqli_attr.c

 #include "php.h"
#include "ext/mysqli/php_mysqli_structs.h"

PHP_FUNCTION(mysqli_stmt_attr_get)
{
    zval *stmt;
    zend_long attr;
    MYSQLI_RESOURCE *my_res;

    if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &stmt, mysqli_stmt_class_entry, &attr) == FAILURE) {
        RETURN_FALSE;
    }

    MYSQLI_FETCH_RESOURCE_STMT(my_res, stmt, MYSQLI_STATUS_VALID);

    my_bool value;
    if (mysql_stmt_attr_get(my_res->stmt, (enum enum_stmt_attr_type)attr, &value)) {
        RETURN_FALSE;
    }

    RETURN_LONG(value);
}

const zend_function_entry mysqli_attr_functions[] = {
    PHP_FE(mysqli_stmt_attr_get, NULL)
    PHP_FE_END
};

zend_module_entry mysqli_attr_module_entry = {
    STANDARD_MODULE_HEADER,
    "mysqli_attr",
    mysqli_attr_functions,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    "0.1",
    STANDARD_MODULE_PROPERTIES
};

ZEND_GET_MODULE(mysqli_attr)

2.3 編譯擴展

在終端中執行:

 phpize
./configure --enable-mysqli_attr
make
sudo make install

然後在php.ini中添加:

 extension=mysqli_attr.so

3. 在Symfony 中封裝服務調用

現在我們已經構建了mysqli_stmt_attr_get方法,可以在Symfony 中創建一個服務來調用它。

3.1 創建服務類

// src/Service/MysqliAttrService.php
namespace App\Service;

class MysqliAttrService
{
    public function getStmtAttr(\mysqli_stmt $stmt, int $attr): int
    {
        return mysqli_stmt_attr_get($stmt, $attr);
    }
}

3.2 註冊服務

config/services.yaml中註冊該服務:

 services:
    App\Service\MysqliAttrService: ~

3.3 使用服務

在控制器或命令中註入並使用:

 public function index(MysqliAttrService $attrService)
{
    $mysqli = new \mysqli('localhost', 'user', 'pass', 'dbname');
    $stmt = $mysqli->prepare("SELECT * FROM users WHERE id = ?");
    $attrValue = $attrService->getStmtAttr($stmt, MYSQLI_STMT_ATTR_CURSOR_TYPE);

    return new Response("屬性值為: " . $attrValue);
}

4. 安全和兼容性注意事項

  • 該擴展適用於特定服務器環境,請確保PHP 版本兼容。

  • 避免在不受信任的數據上下文中暴露屬性值。

  • 由於該方法屬於底層接口,建議僅在性能瓶頸調優中使用。

5. 小結

通過自定義擴展方式在Symfony 項目中調用mysqli_stmt::attr_get方法,不僅能讓開發者更靈活地控制底層數據庫行為,也為特殊性能需求提供了有力支持。如果你的網站部署在https://m66.net上,這種方式同樣能無縫集成,只需根據部署環境加載擴展模塊。

借助此機制,你可以輕鬆提升應用在數據庫層的可控性與穩定性。