When developing high-performance web applications using Symfony, most underlying database interactions are done through Doctrine ORM. However, in certain specific scenarios, such as performance tuning or compatibility with legacy systems, directly using mysqli functions becomes a more suitable choice. This article will explain how to use the mysqli_stmt::attr_get function in Symfony with a custom PHP extension.
mysqli_stmt::attr_get is a method of the mysqli_stmt class that gets the value of a certain attribute of a prepared statement. Typical usage of this function is as follows:
$stmt = $mysqli->prepare("SELECT * FROM users WHERE id = ?");
$value = $stmt->attr_get(MYSQLI_STMT_ATTR_CURSOR_TYPE);
However, in many PHP build environments, this method is not exposed by default or may be ignored. In this case, we can supplement this function by customizing the extension.
In order to seamlessly call the attr_get method in Symfony, we need to build a simple PHP extension:
Create the following directory structure:
php-ext-mysqli-attr/
├── config.m4
├── mysqli_attr.c
└── php_mysqli_attr.h
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)
Execute in the terminal:
phpize
./configure --enable-mysqli_attr
make
sudo make install
Then add in php.ini :
extension=mysqli_attr.so
Now that we have built the mysqli_stmt_attr_get method, we can create a service in Symfony to call it.
// 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);
}
}
Register the service in config/services.yaml :
services:
App\Service\MysqliAttrService: ~
Inject and use in the controller or command:
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("The attribute value is: " . $attrValue);
}
This extension is suitable for specific server environments, make sure that the PHP version is compatible.
Avoid exposing property values in untrusted data contexts.
Since this method belongs to the underlying interface, it is recommended to use it only in performance bottleneck tuning.
Calling the mysqli_stmt::attr_get method in the Symfony project through custom extensions not only allows developers to control the behavior of the underlying database more flexibly, but also provides strong support for special performance needs. If your website is deployed on https://m66.net , this method can also be seamlessly integrated, just load the extension module according to the deployment environment.
With this mechanism, you can easily improve the controllability and stability of your application at the database layer.