mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Add mysqli_error_list() that returns an array with errors. Typically only
one and just one for libmysql. mysqlnd can return generate more than one error during its work and with mysqli_error() only the last error is being reported. In the array returned by mysqli_error_list() / $mysqli->error_list, all errors will be found. The list is reset when the next command is executed
This commit is contained in:
parent
463de70efd
commit
11f198b203
23 changed files with 363 additions and 31 deletions
|
@ -352,6 +352,7 @@ const zend_function_entry mysqli_functions[] = {
|
||||||
#endif
|
#endif
|
||||||
PHP_FE(mysqli_errno, arginfo_mysqli_only_link)
|
PHP_FE(mysqli_errno, arginfo_mysqli_only_link)
|
||||||
PHP_FE(mysqli_error, arginfo_mysqli_only_link)
|
PHP_FE(mysqli_error, arginfo_mysqli_only_link)
|
||||||
|
PHP_FE(mysqli_error_list, arginfo_mysqli_only_link)
|
||||||
PHP_FE(mysqli_stmt_execute, arginfo_mysqli_only_statement)
|
PHP_FE(mysqli_stmt_execute, arginfo_mysqli_only_statement)
|
||||||
PHP_FALIAS(mysqli_execute, mysqli_stmt_execute, arginfo_mysqli_only_statement)
|
PHP_FALIAS(mysqli_execute, mysqli_stmt_execute, arginfo_mysqli_only_statement)
|
||||||
PHP_FE(mysqli_fetch_field, arginfo_mysqli_only_result)
|
PHP_FE(mysqli_fetch_field, arginfo_mysqli_only_result)
|
||||||
|
@ -424,6 +425,7 @@ const zend_function_entry mysqli_functions[] = {
|
||||||
PHP_FE(mysqli_stmt_data_seek, arginfo_mysqli_stmt_data_seek)
|
PHP_FE(mysqli_stmt_data_seek, arginfo_mysqli_stmt_data_seek)
|
||||||
PHP_FE(mysqli_stmt_errno, arginfo_mysqli_only_statement)
|
PHP_FE(mysqli_stmt_errno, arginfo_mysqli_only_statement)
|
||||||
PHP_FE(mysqli_stmt_error, arginfo_mysqli_only_statement)
|
PHP_FE(mysqli_stmt_error, arginfo_mysqli_only_statement)
|
||||||
|
PHP_FE(mysqli_stmt_error_list, arginfo_mysqli_only_statement)
|
||||||
PHP_FE(mysqli_stmt_fetch, arginfo_mysqli_only_statement)
|
PHP_FE(mysqli_stmt_fetch, arginfo_mysqli_only_statement)
|
||||||
PHP_FE(mysqli_stmt_field_count, arginfo_mysqli_only_statement)
|
PHP_FE(mysqli_stmt_field_count, arginfo_mysqli_only_statement)
|
||||||
PHP_FE(mysqli_stmt_free_result, arginfo_mysqli_only_statement)
|
PHP_FE(mysqli_stmt_free_result, arginfo_mysqli_only_statement)
|
||||||
|
|
|
@ -38,6 +38,7 @@ PHP_FUNCTION(mysqli_debug);
|
||||||
PHP_FUNCTION(mysqli_dump_debug_info);
|
PHP_FUNCTION(mysqli_dump_debug_info);
|
||||||
PHP_FUNCTION(mysqli_errno);
|
PHP_FUNCTION(mysqli_errno);
|
||||||
PHP_FUNCTION(mysqli_error);
|
PHP_FUNCTION(mysqli_error);
|
||||||
|
PHP_FUNCTION(mysqli_error_list);
|
||||||
PHP_FUNCTION(mysqli_fetch_all);
|
PHP_FUNCTION(mysqli_fetch_all);
|
||||||
PHP_FUNCTION(mysqli_fetch_array);
|
PHP_FUNCTION(mysqli_fetch_array);
|
||||||
PHP_FUNCTION(mysqli_fetch_assoc);
|
PHP_FUNCTION(mysqli_fetch_assoc);
|
||||||
|
@ -111,6 +112,7 @@ PHP_FUNCTION(mysqli_stmt_close);
|
||||||
PHP_FUNCTION(mysqli_stmt_data_seek);
|
PHP_FUNCTION(mysqli_stmt_data_seek);
|
||||||
PHP_FUNCTION(mysqli_stmt_errno);
|
PHP_FUNCTION(mysqli_stmt_errno);
|
||||||
PHP_FUNCTION(mysqli_stmt_error);
|
PHP_FUNCTION(mysqli_stmt_error);
|
||||||
|
PHP_FUNCTION(mysqli_stmt_error_list);
|
||||||
PHP_FUNCTION(mysqli_stmt_free_result);
|
PHP_FUNCTION(mysqli_stmt_free_result);
|
||||||
PHP_FUNCTION(mysqli_stmt_get_result);
|
PHP_FUNCTION(mysqli_stmt_get_result);
|
||||||
PHP_FUNCTION(mysqli_stmt_get_warnings);
|
PHP_FUNCTION(mysqli_stmt_get_warnings);
|
||||||
|
|
|
@ -385,6 +385,7 @@ PHP_FUNCTION(mysqli_fetch_all)
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* {{{ proto array mysqli_get_client_stats(void)
|
/* {{{ proto array mysqli_get_client_stats(void)
|
||||||
Returns statistics about the zval cache */
|
Returns statistics about the zval cache */
|
||||||
PHP_FUNCTION(mysqli_get_client_stats)
|
PHP_FUNCTION(mysqli_get_client_stats)
|
||||||
|
@ -415,6 +416,93 @@ PHP_FUNCTION(mysqli_get_connection_stats)
|
||||||
#endif
|
#endif
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ proto mixed mysqli_error_list (object connection)
|
||||||
|
Fetches all client errors */
|
||||||
|
PHP_FUNCTION(mysqli_error_list)
|
||||||
|
{
|
||||||
|
MY_MYSQL *mysql;
|
||||||
|
zval *mysql_link;
|
||||||
|
|
||||||
|
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
|
||||||
|
array_init(return_value);
|
||||||
|
#if defined(MYSQLI_USE_MYSQLND)
|
||||||
|
if (mysql->mysql->error_info.error_list) {
|
||||||
|
MYSQLND_ERROR_LIST_ELEMENT * message;
|
||||||
|
zend_llist_position pos;
|
||||||
|
for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->error_info.error_list, &pos);
|
||||||
|
message;
|
||||||
|
message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->error_info.error_list, &pos))
|
||||||
|
{
|
||||||
|
zval * single_error;
|
||||||
|
MAKE_STD_ZVAL(single_error);
|
||||||
|
array_init(single_error);
|
||||||
|
add_assoc_long_ex(single_error, "errno", sizeof("errno"), message->error_no);
|
||||||
|
add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), message->sqlstate, 1);
|
||||||
|
add_assoc_string_ex(single_error, "error", sizeof("error"), message->error, 1);
|
||||||
|
add_next_index_zval(return_value, single_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (mysql_errno(mysql->mysql)) {
|
||||||
|
zval * single_error;
|
||||||
|
MAKE_STD_ZVAL(single_error);
|
||||||
|
array_init(single_error);
|
||||||
|
add_assoc_long_ex(single_error, "errno", sizeof("errno"), mysql_errno(mysql->mysql));
|
||||||
|
add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), mysql_sqlstate(mysql->mysql), 1);
|
||||||
|
add_assoc_string_ex(single_error, "error", sizeof("error"), mysql_error(mysql->mysql), 1);
|
||||||
|
add_next_index_zval(return_value, single_error);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
|
||||||
|
/* {{{ proto string mysqli_stmt_error_list(object stmt)
|
||||||
|
*/
|
||||||
|
PHP_FUNCTION(mysqli_stmt_error_list)
|
||||||
|
{
|
||||||
|
MY_STMT *stmt;
|
||||||
|
zval *mysql_stmt;
|
||||||
|
|
||||||
|
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED);
|
||||||
|
array_init(return_value);
|
||||||
|
#if defined(MYSQLI_USE_MYSQLND)
|
||||||
|
if (stmt->stmt && stmt->stmt->data && stmt->stmt->data->error_info.error_list) {
|
||||||
|
MYSQLND_ERROR_LIST_ELEMENT * message;
|
||||||
|
zend_llist_position pos;
|
||||||
|
for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info.error_list, &pos);
|
||||||
|
message;
|
||||||
|
message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info.error_list, &pos))
|
||||||
|
{
|
||||||
|
zval * single_error;
|
||||||
|
MAKE_STD_ZVAL(single_error);
|
||||||
|
array_init(single_error);
|
||||||
|
add_assoc_long_ex(single_error, "errno", sizeof("errno"), message->error_no);
|
||||||
|
add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), message->sqlstate, 1);
|
||||||
|
add_assoc_string_ex(single_error, "error", sizeof("error"), message->error, 1);
|
||||||
|
add_next_index_zval(return_value, single_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (mysql_stmt_errno(stmt->stmt)) {
|
||||||
|
zval * single_error;
|
||||||
|
MAKE_STD_ZVAL(single_error);
|
||||||
|
array_init(single_error);
|
||||||
|
add_assoc_long_ex(single_error, "errno", sizeof("errno"), mysql_stmt_errno(stmt->stmt));
|
||||||
|
add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), mysql_stmt_sqlstate(stmt->stmt), 1);
|
||||||
|
add_assoc_string_ex(single_error, "error", sizeof("error"), mysql_stmt_error(stmt->stmt), 1);
|
||||||
|
add_next_index_zval(return_value, single_error);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
|
||||||
/* {{{ proto mixed mysqli_fetch_object (object result [, string class_name [, NULL|array ctor_params]])
|
/* {{{ proto mixed mysqli_fetch_object (object result [, string class_name [, NULL|array ctor_params]])
|
||||||
Fetch a result row as an object */
|
Fetch a result row as an object */
|
||||||
|
|
|
@ -189,6 +189,54 @@ static int link_affected_rows_read(mysqli_object *obj, zval **retval TSRMLS_DC)
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
||||||
|
/* {{{ property link_error_list_read */
|
||||||
|
static int link_error_list_read(mysqli_object *obj, zval **retval TSRMLS_DC)
|
||||||
|
{
|
||||||
|
MY_MYSQL *mysql;
|
||||||
|
|
||||||
|
MAKE_STD_ZVAL(*retval);
|
||||||
|
|
||||||
|
CHECK_STATUS(MYSQLI_STATUS_VALID);
|
||||||
|
|
||||||
|
mysql = (MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
|
||||||
|
|
||||||
|
array_init(*retval);
|
||||||
|
if (mysql) {
|
||||||
|
#if defined(MYSQLI_USE_MYSQLND)
|
||||||
|
if (mysql->mysql->error_info.error_list) {
|
||||||
|
MYSQLND_ERROR_LIST_ELEMENT * message;
|
||||||
|
zend_llist_position pos;
|
||||||
|
for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->error_info.error_list, &pos);
|
||||||
|
message;
|
||||||
|
message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->error_info.error_list, &pos))
|
||||||
|
{
|
||||||
|
zval * single_error;
|
||||||
|
MAKE_STD_ZVAL(single_error);
|
||||||
|
array_init(single_error);
|
||||||
|
add_assoc_long_ex(single_error, "errno", sizeof("errno"), message->error_no);
|
||||||
|
add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), message->sqlstate, 1);
|
||||||
|
add_assoc_string_ex(single_error, "error", sizeof("error"), message->error, 1);
|
||||||
|
add_next_index_zval(*retval, single_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (mysql_errno(mysql->mysql)) {
|
||||||
|
zval * single_error;
|
||||||
|
MAKE_STD_ZVAL(single_error);
|
||||||
|
array_init(single_error);
|
||||||
|
add_assoc_long_ex(single_error, "errno", sizeof("errno"), mysql_errno(mysql->mysql));
|
||||||
|
add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), mysql_sqlstate(mysql->mysql), 1);
|
||||||
|
add_assoc_string_ex(single_error, "error", sizeof("error"), mysql_error(mysql->mysql), 1);
|
||||||
|
add_next_index_zval(*retval, single_error);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
|
||||||
/* link properties */
|
/* link properties */
|
||||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_errno_read, mysql_errno, MYSQLI_GET_MYSQL(MYSQLI_STATUS_INITIALIZED), ulong, "%lu")
|
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_errno_read, mysql_errno, MYSQLI_GET_MYSQL(MYSQLI_STATUS_INITIALIZED), ulong, "%lu")
|
||||||
MYSQLI_MAP_PROPERTY_FUNC_STRING(link_error_read, mysql_error, MYSQLI_GET_MYSQL(MYSQLI_STATUS_INITIALIZED))
|
MYSQLI_MAP_PROPERTY_FUNC_STRING(link_error_read, mysql_error, MYSQLI_GET_MYSQL(MYSQLI_STATUS_INITIALIZED))
|
||||||
|
@ -202,6 +250,7 @@ MYSQLI_MAP_PROPERTY_FUNC_LONG(link_server_version_read, mysql_get_server_version
|
||||||
MYSQLI_MAP_PROPERTY_FUNC_STRING(link_sqlstate_read, mysql_sqlstate, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID))
|
MYSQLI_MAP_PROPERTY_FUNC_STRING(link_sqlstate_read, mysql_sqlstate, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID))
|
||||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_thread_id_read, mysql_thread_id, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong, "%lu")
|
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_thread_id_read, mysql_thread_id, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong, "%lu")
|
||||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_warning_count_read, mysql_warning_count, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong, "%lu")
|
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_warning_count_read, mysql_warning_count, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong, "%lu")
|
||||||
|
|
||||||
/* result properties */
|
/* result properties */
|
||||||
|
|
||||||
/* {{{ property result_type_read */
|
/* {{{ property result_type_read */
|
||||||
|
@ -306,6 +355,51 @@ static int stmt_affected_rows_read(mysqli_object *obj, zval **retval TSRMLS_DC)
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ property stmt_error_list_read */
|
||||||
|
static int stmt_error_list_read(mysqli_object *obj, zval **retval TSRMLS_DC)
|
||||||
|
{
|
||||||
|
MY_STMT * stmt;
|
||||||
|
|
||||||
|
MAKE_STD_ZVAL(*retval);
|
||||||
|
CHECK_STATUS(MYSQLI_STATUS_INITIALIZED);
|
||||||
|
|
||||||
|
stmt = (MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
|
||||||
|
array_init(*retval);
|
||||||
|
if (stmt && stmt->stmt) {
|
||||||
|
#if defined(MYSQLI_USE_MYSQLND)
|
||||||
|
if (stmt->stmt->data && stmt->stmt->data->error_info.error_list) {
|
||||||
|
MYSQLND_ERROR_LIST_ELEMENT * message;
|
||||||
|
zend_llist_position pos;
|
||||||
|
for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info.error_list, &pos);
|
||||||
|
message;
|
||||||
|
message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info.error_list, &pos))
|
||||||
|
{
|
||||||
|
zval * single_error;
|
||||||
|
MAKE_STD_ZVAL(single_error);
|
||||||
|
array_init(single_error);
|
||||||
|
add_assoc_long_ex(single_error, "errno", sizeof("errno"), message->error_no);
|
||||||
|
add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), message->sqlstate, 1);
|
||||||
|
add_assoc_string_ex(single_error, "error", sizeof("error"), message->error, 1);
|
||||||
|
add_next_index_zval(*retval, single_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (mysql_stmt_errno(stmt->stmt)) {
|
||||||
|
zval * single_error;
|
||||||
|
MAKE_STD_ZVAL(single_error);
|
||||||
|
array_init(single_error);
|
||||||
|
add_assoc_long_ex(single_error, "errno", sizeof("errno"), mysql_stmt_errno(stmt->stmt));
|
||||||
|
add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), mysql_stmt_sqlstate(stmt->stmt), 1);
|
||||||
|
add_assoc_string_ex(single_error, "error", sizeof("error"), mysql_stmt_error(stmt->stmt), 1);
|
||||||
|
add_next_index_zval(*retval, single_error);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
|
||||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_insert_id_read, mysql_stmt_insert_id, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), my_ulonglong, MYSQLI_LLU_SPEC)
|
MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_insert_id_read, mysql_stmt_insert_id, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), my_ulonglong, MYSQLI_LLU_SPEC)
|
||||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_num_rows_read, mysql_stmt_num_rows, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), my_ulonglong, MYSQLI_LLU_SPEC)
|
MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_num_rows_read, mysql_stmt_num_rows, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), my_ulonglong, MYSQLI_LLU_SPEC)
|
||||||
MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_param_count_read, mysql_stmt_param_count, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), ulong, "%lu")
|
MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_param_count_read, mysql_stmt_param_count, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), ulong, "%lu")
|
||||||
|
@ -323,6 +417,7 @@ const mysqli_property_entry mysqli_link_property_entries[] = {
|
||||||
{"connect_error", sizeof("connect_error") - 1, link_connect_error_read, NULL},
|
{"connect_error", sizeof("connect_error") - 1, link_connect_error_read, NULL},
|
||||||
{"errno", sizeof("errno") - 1, link_errno_read, NULL},
|
{"errno", sizeof("errno") - 1, link_errno_read, NULL},
|
||||||
{"error", sizeof("error") - 1, link_error_read, NULL},
|
{"error", sizeof("error") - 1, link_error_read, NULL},
|
||||||
|
{"error_list", sizeof("error_list") - 1, link_error_list_read, NULL},
|
||||||
{"field_count", sizeof("field_count") - 1, link_field_count_read, NULL},
|
{"field_count", sizeof("field_count") - 1, link_field_count_read, NULL},
|
||||||
{"host_info", sizeof("host_info") - 1, link_host_info_read, NULL},
|
{"host_info", sizeof("host_info") - 1, link_host_info_read, NULL},
|
||||||
{"info", sizeof("info") - 1, link_info_read, NULL},
|
{"info", sizeof("info") - 1, link_info_read, NULL},
|
||||||
|
@ -345,6 +440,7 @@ const zend_property_info mysqli_link_property_info_entries[] = {
|
||||||
{ZEND_ACC_PUBLIC, "connect_error", sizeof("connect_error") - 1, -1, 0, NULL, 0, NULL},
|
{ZEND_ACC_PUBLIC, "connect_error", sizeof("connect_error") - 1, -1, 0, NULL, 0, NULL},
|
||||||
{ZEND_ACC_PUBLIC, "errno", sizeof("errno") - 1, -1, 0, NULL, 0, NULL},
|
{ZEND_ACC_PUBLIC, "errno", sizeof("errno") - 1, -1, 0, NULL, 0, NULL},
|
||||||
{ZEND_ACC_PUBLIC, "error", sizeof("error") - 1, -1, 0, NULL, 0, NULL},
|
{ZEND_ACC_PUBLIC, "error", sizeof("error") - 1, -1, 0, NULL, 0, NULL},
|
||||||
|
{ZEND_ACC_PUBLIC, "error_list", sizeof("error_list") - 1, -1, 0, NULL, 0, NULL},
|
||||||
{ZEND_ACC_PUBLIC, "field_count", sizeof("field_count") - 1, -1, 0, NULL, 0, NULL},
|
{ZEND_ACC_PUBLIC, "field_count", sizeof("field_count") - 1, -1, 0, NULL, 0, NULL},
|
||||||
{ZEND_ACC_PUBLIC, "host_info", sizeof("host_info") - 1, -1, 0, NULL, 0, NULL},
|
{ZEND_ACC_PUBLIC, "host_info", sizeof("host_info") - 1, -1, 0, NULL, 0, NULL},
|
||||||
{ZEND_ACC_PUBLIC, "info", sizeof("info") - 1, -1, 0, NULL, 0, NULL},
|
{ZEND_ACC_PUBLIC, "info", sizeof("info") - 1, -1, 0, NULL, 0, NULL},
|
||||||
|
@ -385,6 +481,7 @@ const mysqli_property_entry mysqli_stmt_property_entries[] = {
|
||||||
{"field_count", sizeof("field_count") - 1, stmt_field_count_read, NULL},
|
{"field_count", sizeof("field_count") - 1, stmt_field_count_read, NULL},
|
||||||
{"errno", sizeof("errno") - 1, stmt_errno_read, NULL},
|
{"errno", sizeof("errno") - 1, stmt_errno_read, NULL},
|
||||||
{"error", sizeof("error") - 1, stmt_error_read, NULL},
|
{"error", sizeof("error") - 1, stmt_error_read, NULL},
|
||||||
|
{"error_list", sizeof("error_list") - 1, stmt_error_list_read, NULL},
|
||||||
{"sqlstate", sizeof("sqlstate") - 1, stmt_sqlstate_read, NULL},
|
{"sqlstate", sizeof("sqlstate") - 1, stmt_sqlstate_read, NULL},
|
||||||
{"id", sizeof("id") - 1, stmt_id_read, NULL},
|
{"id", sizeof("id") - 1, stmt_id_read, NULL},
|
||||||
{NULL, 0, NULL, NULL}
|
{NULL, 0, NULL, NULL}
|
||||||
|
@ -399,6 +496,7 @@ const zend_property_info mysqli_stmt_property_info_entries[] = {
|
||||||
{ZEND_ACC_PUBLIC, "field_count",sizeof("field_count") - 1, -1, 0, NULL, 0, NULL},
|
{ZEND_ACC_PUBLIC, "field_count",sizeof("field_count") - 1, -1, 0, NULL, 0, NULL},
|
||||||
{ZEND_ACC_PUBLIC, "errno", sizeof("errno") - 1, -1, 0, NULL, 0, NULL},
|
{ZEND_ACC_PUBLIC, "errno", sizeof("errno") - 1, -1, 0, NULL, 0, NULL},
|
||||||
{ZEND_ACC_PUBLIC, "error", sizeof("error") - 1, -1, 0, NULL, 0, NULL},
|
{ZEND_ACC_PUBLIC, "error", sizeof("error") - 1, -1, 0, NULL, 0, NULL},
|
||||||
|
{ZEND_ACC_PUBLIC, "error_list", sizeof("error_list") - 1, -1, 0, NULL, 0, NULL},
|
||||||
{ZEND_ACC_PUBLIC, "sqlstate", sizeof("sqlstate") - 1, -1, 0, NULL, 0, NULL},
|
{ZEND_ACC_PUBLIC, "sqlstate", sizeof("sqlstate") - 1, -1, 0, NULL, 0, NULL},
|
||||||
{ZEND_ACC_PUBLIC, "id", sizeof("id") - 1, -1, 0, NULL, 0, NULL},
|
{ZEND_ACC_PUBLIC, "id", sizeof("id") - 1, -1, 0, NULL, 0, NULL},
|
||||||
{0, NULL, 0, -1, 0, NULL, 0, NULL}
|
{0, NULL, 0, -1, 0, NULL, 0, NULL}
|
||||||
|
|
|
@ -91,6 +91,9 @@ object(mysqli_stmt)#%d (%d) {
|
||||||
int(0)
|
int(0)
|
||||||
[%u|b%"error"]=>
|
[%u|b%"error"]=>
|
||||||
%unicode|string%(0) ""
|
%unicode|string%(0) ""
|
||||||
|
[%u|b%"error_list"]=>
|
||||||
|
array(0) {
|
||||||
|
}
|
||||||
[%u|b%"sqlstate"]=>
|
[%u|b%"sqlstate"]=>
|
||||||
%unicode|string%(5) "00000"
|
%unicode|string%(5) "00000"
|
||||||
[%u|b%"id"]=>
|
[%u|b%"id"]=>
|
||||||
|
|
|
@ -77,6 +77,9 @@ object(mysqli)#%d (%d) {
|
||||||
int(0)
|
int(0)
|
||||||
[%u|b%"error"]=>
|
[%u|b%"error"]=>
|
||||||
%unicode|string%(0) ""
|
%unicode|string%(0) ""
|
||||||
|
[%u|b%"error_list"]=>
|
||||||
|
array(0) {
|
||||||
|
}
|
||||||
[%u|b%"field_count"]=>
|
[%u|b%"field_count"]=>
|
||||||
int(0)
|
int(0)
|
||||||
[%u|b%"host_info"]=>
|
[%u|b%"host_info"]=>
|
||||||
|
@ -113,6 +116,8 @@ object(mysqli)#%d (%d) {
|
||||||
int(0)
|
int(0)
|
||||||
[%u|b%"error"]=>
|
[%u|b%"error"]=>
|
||||||
%unicode|string%(0) ""
|
%unicode|string%(0) ""
|
||||||
|
[%u|b%"error_list"]=>
|
||||||
|
NULL
|
||||||
[%u|b%"field_count"]=>
|
[%u|b%"field_count"]=>
|
||||||
NULL
|
NULL
|
||||||
[%u|b%"host_info"]=>
|
[%u|b%"host_info"]=>
|
||||||
|
|
|
@ -131,6 +131,11 @@ require_once('skipifconnectfailure.inc');
|
||||||
$mysqli->error, gettype($mysqli->error),
|
$mysqli->error, gettype($mysqli->error),
|
||||||
mysqli_error($link), gettype(mysqli_error($link)));
|
mysqli_error($link), gettype(mysqli_error($link)));
|
||||||
|
|
||||||
|
assert(mysqli_error_list($link) === $mysqli->error_list);
|
||||||
|
printf("mysqli->error_list = '%s'/%s ('%s'/%s)\n",
|
||||||
|
$mysqli->error_list, gettype($mysqli->error_list),
|
||||||
|
mysqli_error_list($link), gettype(mysqli_error_list($link)));
|
||||||
|
|
||||||
assert(mysqli_field_count($link) === $mysqli->field_count);
|
assert(mysqli_field_count($link) === $mysqli->field_count);
|
||||||
printf("mysqli->field_count = '%s'/%s ('%s'/%s)\n",
|
printf("mysqli->field_count = '%s'/%s ('%s'/%s)\n",
|
||||||
$mysqli->field_count, gettype($mysqli->field_count),
|
$mysqli->field_count, gettype($mysqli->field_count),
|
||||||
|
@ -222,6 +227,7 @@ connect_errno
|
||||||
connect_error
|
connect_error
|
||||||
errno
|
errno
|
||||||
error
|
error
|
||||||
|
error_list
|
||||||
field_count
|
field_count
|
||||||
host_info
|
host_info
|
||||||
info
|
info
|
||||||
|
@ -241,6 +247,7 @@ connect_errno
|
||||||
connect_error
|
connect_error
|
||||||
errno
|
errno
|
||||||
error
|
error
|
||||||
|
error_list
|
||||||
field_count
|
field_count
|
||||||
host_info
|
host_info
|
||||||
info
|
info
|
||||||
|
@ -258,6 +265,7 @@ mysqli->client_info = '%s'/%unicode|string% ('%s'/%unicode|string%)
|
||||||
mysqli->client_version = '%d'/integer ('%d'/integer)
|
mysqli->client_version = '%d'/integer ('%d'/integer)
|
||||||
mysqli->errno = '0'/integer ('0'/integer)
|
mysqli->errno = '0'/integer ('0'/integer)
|
||||||
mysqli->error = ''/%unicode|string% (''/%unicode|string%)
|
mysqli->error = ''/%unicode|string% (''/%unicode|string%)
|
||||||
|
mysqli->error_list = 'Array'/array ('Array'/array)
|
||||||
mysqli->field_count = '0'/integer ('0'/integer)
|
mysqli->field_count = '0'/integer ('0'/integer)
|
||||||
mysqli->insert_id = '0'/integer ('0'/integer)
|
mysqli->insert_id = '0'/integer ('0'/integer)
|
||||||
mysqli->sqlstate = '00000'/%unicode|string% ('00000'/%unicode|string%)
|
mysqli->sqlstate = '00000'/%unicode|string% ('00000'/%unicode|string%)
|
||||||
|
|
|
@ -151,6 +151,7 @@ connect_errno = '%s'
|
||||||
connect_error = ''%s'
|
connect_error = ''%s'
|
||||||
errno = 'NULL'
|
errno = 'NULL'
|
||||||
error = 'NULL'
|
error = 'NULL'
|
||||||
|
error_list = 'NULL'
|
||||||
field_count = 'NULL'
|
field_count = 'NULL'
|
||||||
host_info = 'NULL'
|
host_info = 'NULL'
|
||||||
info = 'NULL'
|
info = 'NULL'
|
||||||
|
@ -170,6 +171,7 @@ connect_errno = '%s'
|
||||||
connect_error = '%s'
|
connect_error = '%s'
|
||||||
errno = 'NULL'
|
errno = 'NULL'
|
||||||
error = 'NULL'
|
error = 'NULL'
|
||||||
|
error_list = 'NULL'
|
||||||
field_count = 'NULL'
|
field_count = 'NULL'
|
||||||
host_info = 'NULL'
|
host_info = 'NULL'
|
||||||
info = 'NULL'
|
info = 'NULL'
|
||||||
|
@ -220,6 +222,7 @@ connect_errno = '%s'
|
||||||
connect_error = '%s'
|
connect_error = '%s'
|
||||||
errno = 'NULL'
|
errno = 'NULL'
|
||||||
error = 'NULL'
|
error = 'NULL'
|
||||||
|
error_list = 'NULL'
|
||||||
field_count = 'NULL'
|
field_count = 'NULL'
|
||||||
host_info = 'NULL'
|
host_info = 'NULL'
|
||||||
info = 'NULL'
|
info = 'NULL'
|
||||||
|
@ -239,6 +242,7 @@ connect_errno = '%s'
|
||||||
connect_error = '%s'
|
connect_error = '%s'
|
||||||
errno = 'NULL'
|
errno = 'NULL'
|
||||||
error = 'NULL'
|
error = 'NULL'
|
||||||
|
error_list = 'NULL'
|
||||||
field_count = 'NULL'
|
field_count = 'NULL'
|
||||||
host_info = 'NULL'
|
host_info = 'NULL'
|
||||||
info = 'NULL'
|
info = 'NULL'
|
||||||
|
|
|
@ -1129,6 +1129,14 @@ isStatic: no
|
||||||
isDefault: yes
|
isDefault: yes
|
||||||
Modifiers: 256
|
Modifiers: 256
|
||||||
|
|
||||||
|
Inspecting property 'error_list'
|
||||||
|
isPublic: yes
|
||||||
|
isPrivate: no
|
||||||
|
isProtected: no
|
||||||
|
isStatic: no
|
||||||
|
isDefault: yes
|
||||||
|
Modifiers: 256
|
||||||
|
|
||||||
Inspecting property 'field_count'
|
Inspecting property 'field_count'
|
||||||
isPublic: yes
|
isPublic: yes
|
||||||
isPrivate: no
|
isPrivate: no
|
||||||
|
@ -1215,6 +1223,7 @@ Default property 'connect_errno'
|
||||||
Default property 'connect_error'
|
Default property 'connect_error'
|
||||||
Default property 'errno'
|
Default property 'errno'
|
||||||
Default property 'error'
|
Default property 'error'
|
||||||
|
Default property 'error_list'
|
||||||
Default property 'field_count'
|
Default property 'field_count'
|
||||||
Default property 'host_info'
|
Default property 'host_info'
|
||||||
Default property 'info'
|
Default property 'info'
|
||||||
|
|
|
@ -97,6 +97,9 @@ printf("stmt->errno = '%s'\n", $stmt->errno);
|
||||||
assert(mysqli_stmt_error($stmt) === $stmt->error);
|
assert(mysqli_stmt_error($stmt) === $stmt->error);
|
||||||
printf("stmt->error = '%s'\n", $stmt->error);
|
printf("stmt->error = '%s'\n", $stmt->error);
|
||||||
|
|
||||||
|
assert(mysqli_stmt_error_list($stmt) === $stmt->error_list);
|
||||||
|
var_dump("stmt->error = ", $stmt->error_list);
|
||||||
|
|
||||||
assert(mysqli_stmt_field_count($stmt) === $stmt->field_count);
|
assert(mysqli_stmt_field_count($stmt) === $stmt->field_count);
|
||||||
printf("stmt->field_count = '%s'\n", $stmt->field_count);
|
printf("stmt->field_count = '%s'\n", $stmt->field_count);
|
||||||
|
|
||||||
|
@ -143,6 +146,7 @@ Class variables:
|
||||||
affected_rows
|
affected_rows
|
||||||
errno
|
errno
|
||||||
error
|
error
|
||||||
|
error_list
|
||||||
field_count
|
field_count
|
||||||
id
|
id
|
||||||
insert_id
|
insert_id
|
||||||
|
@ -158,6 +162,7 @@ param_count
|
||||||
field_count
|
field_count
|
||||||
errno
|
errno
|
||||||
error
|
error
|
||||||
|
error_list
|
||||||
sqlstate
|
sqlstate
|
||||||
id
|
id
|
||||||
|
|
||||||
|
@ -173,6 +178,9 @@ stmt->affected_rows = ''
|
||||||
stmt->affected_rows = '1'
|
stmt->affected_rows = '1'
|
||||||
stmt->errno = '0'
|
stmt->errno = '0'
|
||||||
stmt->error = ''
|
stmt->error = ''
|
||||||
|
string(14) "stmt->error = "
|
||||||
|
array(0) {
|
||||||
|
}
|
||||||
stmt->field_count = '0'
|
stmt->field_count = '0'
|
||||||
stmt->id = '%d'
|
stmt->id = '%d'
|
||||||
stmt->insert_id = '0'
|
stmt->insert_id = '0'
|
||||||
|
|
|
@ -146,7 +146,7 @@ mysqli_connect()
|
||||||
print "done!";
|
print "done!";
|
||||||
?>
|
?>
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Warning: mysqli_connect(): (%d/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d
|
Warning: mysqli_connect(): (%s/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d
|
||||||
array(1) {
|
array(1) {
|
||||||
[%u|b%"testing"]=>
|
[%u|b%"testing"]=>
|
||||||
%unicode|string%(21) "mysqli.default_socket"
|
%unicode|string%(21) "mysqli.default_socket"
|
||||||
|
|
|
@ -144,7 +144,7 @@ new mysqli()
|
||||||
print "done!";
|
print "done!";
|
||||||
?>
|
?>
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Warning: mysqli::mysqli(): (%d/%d): Access denied for user '%sunknown%s'@'%s' (using password: %s) in %s on line %d
|
Warning: mysqli::mysqli(): (%s/%d): Access denied for user '%sunknown%s'@'%s' (using password: %s) in %s on line %d
|
||||||
... and now Exceptions
|
... and now Exceptions
|
||||||
Access denied for user '%s'@'%s' (using password: %s)
|
Access denied for user '%s'@'%s' (using password: %s)
|
||||||
done!
|
done!
|
|
@ -96,6 +96,18 @@ object(mysqli)#%d (%d) {
|
||||||
int(2006)
|
int(2006)
|
||||||
[%u|b%"error"]=>
|
[%u|b%"error"]=>
|
||||||
%unicode|string%(%d) "%s"
|
%unicode|string%(%d) "%s"
|
||||||
|
[%u|b%"error_list"]=>
|
||||||
|
array(1) {
|
||||||
|
[0]=>
|
||||||
|
array(3) {
|
||||||
|
[%u|b%"errno"]=>
|
||||||
|
int(2006)
|
||||||
|
[%u|b%"sqlstate"]=>
|
||||||
|
%unicode|string%(5) "%s"
|
||||||
|
[%u|b%"error"]=>
|
||||||
|
%unicode|string%(%d) "%s"
|
||||||
|
}
|
||||||
|
}
|
||||||
[%u|b%"field_count"]=>
|
[%u|b%"field_count"]=>
|
||||||
int(0)
|
int(0)
|
||||||
[%u|b%"host_info"]=>
|
[%u|b%"host_info"]=>
|
||||||
|
|
|
@ -175,7 +175,7 @@ require_once('skipifconnectfailure.inc');
|
||||||
require_once("clean_table.inc");
|
require_once("clean_table.inc");
|
||||||
?>
|
?>
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Warning: mysqli_real_connect(): (%d/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d
|
Warning: mysqli_real_connect(): (%s/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d
|
||||||
object(mysqli)#%d (%d) {
|
object(mysqli)#%d (%d) {
|
||||||
[%u|b%"affected_rows"]=>
|
[%u|b%"affected_rows"]=>
|
||||||
NULL
|
NULL
|
||||||
|
@ -191,6 +191,8 @@ object(mysqli)#%d (%d) {
|
||||||
%s
|
%s
|
||||||
[%u|b%"error"]=>
|
[%u|b%"error"]=>
|
||||||
%s
|
%s
|
||||||
|
[%u|b%"error_list"]=>
|
||||||
|
NULL
|
||||||
[%u|b%"field_count"]=>
|
[%u|b%"field_count"]=>
|
||||||
NULL
|
NULL
|
||||||
[%u|b%"host_info"]=>
|
[%u|b%"host_info"]=>
|
||||||
|
|
|
@ -151,5 +151,5 @@ mysqli.max_persistent=10
|
||||||
require_once("clean_table.inc");
|
require_once("clean_table.inc");
|
||||||
?>
|
?>
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Warning: mysqli_real_connect(): (%d/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d
|
Warning: mysqli_real_connect(): (%s/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d
|
||||||
done!
|
done!
|
||||||
|
|
|
@ -69,6 +69,21 @@ static struct st_mysqlnd_conn_methods *mysqlnd_conn_methods;
|
||||||
static struct st_mysqlnd_plugin_core mysqlnd_plugin_core;
|
static struct st_mysqlnd_plugin_core mysqlnd_plugin_core;
|
||||||
|
|
||||||
|
|
||||||
|
/* {{{ mysqlnd_error_list_pdtor */
|
||||||
|
static void
|
||||||
|
mysqlnd_error_list_pdtor(void * pDest)
|
||||||
|
{
|
||||||
|
MYSQLND_ERROR_LIST_ELEMENT * element = (MYSQLND_ERROR_LIST_ELEMENT *) pDest;
|
||||||
|
TSRMLS_FETCH();
|
||||||
|
DBG_ENTER("mysqlnd_error_list_pdtor");
|
||||||
|
if (element->error) {
|
||||||
|
mnd_pefree(element->error, TRUE);
|
||||||
|
}
|
||||||
|
DBG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
|
||||||
/* {{{ mysqlnd_library_end */
|
/* {{{ mysqlnd_library_end */
|
||||||
PHPAPI void mysqlnd_library_end(TSRMLS_D)
|
PHPAPI void mysqlnd_library_end(TSRMLS_D)
|
||||||
{
|
{
|
||||||
|
@ -178,6 +193,11 @@ MYSQLND_METHOD(mysqlnd_conn, free_contents)(MYSQLND * conn TSRMLS_DC)
|
||||||
mnd_pefree(conn->last_message, pers);
|
mnd_pefree(conn->last_message, pers);
|
||||||
conn->last_message = NULL;
|
conn->last_message = NULL;
|
||||||
}
|
}
|
||||||
|
if (conn->error_info.error_list) {
|
||||||
|
zend_llist_clean(conn->error_info.error_list);
|
||||||
|
mnd_pefree(conn->error_info.error_list, pers);
|
||||||
|
conn->error_info.error_list = NULL;
|
||||||
|
}
|
||||||
conn->charset = NULL;
|
conn->charset = NULL;
|
||||||
conn->greet_charset = NULL;
|
conn->greet_charset = NULL;
|
||||||
|
|
||||||
|
@ -2492,6 +2512,14 @@ PHPAPI MYSQLND * _mysqlnd_init(zend_bool persistent TSRMLS_DC)
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret->error_info.error_list = mnd_pecalloc(1, sizeof(zend_llist), persistent);
|
||||||
|
if (!ret->error_info.error_list) {
|
||||||
|
ret->m->dtor(ret TSRMLS_CC);
|
||||||
|
ret = NULL;
|
||||||
|
} else {
|
||||||
|
zend_llist_init(ret->error_info.error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t)mysqlnd_error_list_pdtor, persistent);
|
||||||
|
}
|
||||||
|
|
||||||
DBG_RETURN(ret);
|
DBG_RETURN(ret);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
|
@ -137,8 +137,7 @@ mysqlnd_auth_handshake(MYSQLND * conn,
|
||||||
strlcpy(conn->error_info.sqlstate, auth_resp_packet->sqlstate, sizeof(conn->error_info.sqlstate));
|
strlcpy(conn->error_info.sqlstate, auth_resp_packet->sqlstate, sizeof(conn->error_info.sqlstate));
|
||||||
DBG_ERR_FMT("ERROR:%u [SQLSTATE:%s] %s", auth_resp_packet->error_no, auth_resp_packet->sqlstate, auth_resp_packet->error);
|
DBG_ERR_FMT("ERROR:%u [SQLSTATE:%s] %s", auth_resp_packet->error_no, auth_resp_packet->sqlstate, auth_resp_packet->error);
|
||||||
}
|
}
|
||||||
conn->error_info.error_no = auth_resp_packet->error_no;
|
SET_CLIENT_ERROR(conn->error_info, auth_resp_packet->error_no, UNKNOWN_SQLSTATE, auth_resp_packet->error);
|
||||||
strlcpy(conn->error_info.error, auth_resp_packet->error, sizeof(conn->error_info.error));
|
|
||||||
}
|
}
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
@ -235,7 +234,7 @@ mysqlnd_auth_change_user(MYSQLND * const conn,
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = PACKET_READ(chg_user_resp, conn);
|
ret = PACKET_READ(chg_user_resp, conn);
|
||||||
conn->error_info = chg_user_resp->error_info;
|
COPY_CLIENT_ERROR(conn->error_info, chg_user_resp->error_info);
|
||||||
|
|
||||||
if (0xFE == chg_user_resp->response_code) {
|
if (0xFE == chg_user_resp->response_code) {
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
|
|
|
@ -181,11 +181,12 @@ mysqlnd_handle_local_infile(MYSQLND *conn, const char *filename, zend_bool *is_w
|
||||||
|
|
||||||
/* init handler: allocate read buffer and open file */
|
/* init handler: allocate read buffer and open file */
|
||||||
if (infile.local_infile_init(&info, (char *)filename, conn->infile.userdata TSRMLS_CC)) {
|
if (infile.local_infile_init(&info, (char *)filename, conn->infile.userdata TSRMLS_CC)) {
|
||||||
|
char tmp_buf[sizeof(conn->error_info.error)];
|
||||||
|
int tmp_error_no;
|
||||||
*is_warning = TRUE;
|
*is_warning = TRUE;
|
||||||
/* error occured */
|
/* error occured */
|
||||||
strcpy(conn->error_info.sqlstate, UNKNOWN_SQLSTATE);
|
tmp_error_no = infile.local_infile_error(info, tmp_buf, sizeof(tmp_buf) TSRMLS_CC);
|
||||||
conn->error_info.error_no =
|
SET_CLIENT_ERROR(conn->error_info, tmp_error_no, UNKNOWN_SQLSTATE, tmp_buf);
|
||||||
infile.local_infile_error(info, conn->error_info.error, sizeof(conn->error_info.error) TSRMLS_CC);
|
|
||||||
/* write empty packet to server */
|
/* write empty packet to server */
|
||||||
ret = conn->net->m.send(conn, empty_packet, 0 TSRMLS_CC);
|
ret = conn->net->m.send(conn, empty_packet, 0 TSRMLS_CC);
|
||||||
goto infile_error;
|
goto infile_error;
|
||||||
|
@ -208,11 +209,12 @@ mysqlnd_handle_local_infile(MYSQLND *conn, const char *filename, zend_bool *is_w
|
||||||
|
|
||||||
/* error during read occured */
|
/* error during read occured */
|
||||||
if (bufsize < 0) {
|
if (bufsize < 0) {
|
||||||
|
char tmp_buf[sizeof(conn->error_info.error)];
|
||||||
|
int tmp_error_no;
|
||||||
*is_warning = TRUE;
|
*is_warning = TRUE;
|
||||||
DBG_ERR_FMT("Bufsize < 0, warning, %d %s %s", CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
|
DBG_ERR_FMT("Bufsize < 0, warning, %d %s %s", CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
|
||||||
strcpy(conn->error_info.sqlstate, UNKNOWN_SQLSTATE);
|
tmp_error_no = infile.local_infile_error(info, tmp_buf, sizeof(tmp_buf) TSRMLS_CC);
|
||||||
conn->error_info.error_no =
|
SET_CLIENT_ERROR(conn->error_info, tmp_error_no, UNKNOWN_SQLSTATE, tmp_buf);
|
||||||
infile.local_infile_error(info, conn->error_info.error, sizeof(conn->error_info.error) TSRMLS_CC);
|
|
||||||
goto infile_error;
|
goto infile_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,15 +134,41 @@
|
||||||
(error_info).error_no = 0; \
|
(error_info).error_no = 0; \
|
||||||
(error_info).error[0] = '\0'; \
|
(error_info).error[0] = '\0'; \
|
||||||
strlcpy((error_info).sqlstate, "00000", sizeof((error_info).sqlstate)); \
|
strlcpy((error_info).sqlstate, "00000", sizeof((error_info).sqlstate)); \
|
||||||
|
if ((error_info).error_list) { \
|
||||||
|
zend_llist_clean((error_info).error_list); \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define SET_CLIENT_ERROR(error_info, a, b, c) \
|
#define SET_CLIENT_ERROR(error_info, a, b, c) \
|
||||||
{ \
|
{ \
|
||||||
|
if (0 == (a)) { \
|
||||||
|
SET_EMPTY_ERROR((error_info)); \
|
||||||
|
} else { \
|
||||||
(error_info).error_no = (a); \
|
(error_info).error_no = (a); \
|
||||||
strlcpy((error_info).sqlstate, (b), sizeof((error_info).sqlstate)); \
|
strlcpy((error_info).sqlstate, (b), sizeof((error_info).sqlstate)); \
|
||||||
strlcpy((error_info).error, (c), sizeof((error_info).error)); \
|
strlcpy((error_info).error, (c), sizeof((error_info).error)); \
|
||||||
|
if ((error_info).error_list) {\
|
||||||
|
MYSQLND_ERROR_LIST_ELEMENT error_for_the_list = {0}; \
|
||||||
|
\
|
||||||
|
error_for_the_list.error_no = (a); \
|
||||||
|
strlcpy(error_for_the_list.sqlstate, (b), sizeof(error_for_the_list.sqlstate)); \
|
||||||
|
error_for_the_list.error = mnd_pestrdup((c), TRUE); \
|
||||||
|
if (error_for_the_list.error) { \
|
||||||
|
DBG_INF_FMT("adding error [%s] to the list", error_for_the_list.error); \
|
||||||
|
zend_llist_add_element((error_info).error_list, &error_for_the_list); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define COPY_CLIENT_ERROR(error_info_to, error_info_from) \
|
||||||
|
{ \
|
||||||
|
SET_CLIENT_ERROR((error_info_to), (error_info_from).error_no, (error_info_from).sqlstate, (error_info_from).error); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define SET_OOM_ERROR(error_info) SET_CLIENT_ERROR((error_info), CR_OUT_OF_MEMORY, UNKNOWN_SQLSTATE, mysqlnd_out_of_memory)
|
#define SET_OOM_ERROR(error_info) SET_CLIENT_ERROR((error_info), CR_OUT_OF_MEMORY, UNKNOWN_SQLSTATE, mysqlnd_out_of_memory)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,22 @@ enum_func_status mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param,
|
||||||
static void mysqlnd_stmt_separate_result_bind(MYSQLND_STMT * const stmt TSRMLS_DC);
|
static void mysqlnd_stmt_separate_result_bind(MYSQLND_STMT * const stmt TSRMLS_DC);
|
||||||
static void mysqlnd_stmt_separate_one_result_bind(MYSQLND_STMT * const stmt, unsigned int param_no TSRMLS_DC);
|
static void mysqlnd_stmt_separate_one_result_bind(MYSQLND_STMT * const stmt, unsigned int param_no TSRMLS_DC);
|
||||||
|
|
||||||
|
|
||||||
|
/* {{{ mysqlnd_ps_error_list_pdtor */
|
||||||
|
static void
|
||||||
|
mysqlnd_ps_error_list_pdtor(void * pDest)
|
||||||
|
{
|
||||||
|
MYSQLND_ERROR_LIST_ELEMENT * element = (MYSQLND_ERROR_LIST_ELEMENT *) pDest;
|
||||||
|
TSRMLS_FETCH();
|
||||||
|
DBG_ENTER("mysqlnd_ps_error_list_pdtor");
|
||||||
|
if (element->error) {
|
||||||
|
mnd_pefree(element->error, TRUE);
|
||||||
|
}
|
||||||
|
DBG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
|
||||||
/* {{{ mysqlnd_stmt::store_result */
|
/* {{{ mysqlnd_stmt::store_result */
|
||||||
static MYSQLND_RES *
|
static MYSQLND_RES *
|
||||||
MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s TSRMLS_DC)
|
MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s TSRMLS_DC)
|
||||||
|
@ -110,7 +126,7 @@ MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s TSRMLS_DC)
|
||||||
|
|
||||||
stmt->state = MYSQLND_STMT_USE_OR_STORE_CALLED;
|
stmt->state = MYSQLND_STMT_USE_OR_STORE_CALLED;
|
||||||
} else {
|
} else {
|
||||||
conn->error_info = result->stored_data->error_info;
|
COPY_CLIENT_ERROR(conn->error_info, result->stored_data->error_info);
|
||||||
stmt->result->m.free_result_contents(stmt->result TSRMLS_CC);
|
stmt->result->m.free_result_contents(stmt->result TSRMLS_CC);
|
||||||
mnd_efree(stmt->result);
|
mnd_efree(stmt->result);
|
||||||
stmt->result = NULL;
|
stmt->result = NULL;
|
||||||
|
@ -177,7 +193,7 @@ MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const s TSRMLS_DC)
|
||||||
stmt->state = MYSQLND_STMT_PREPARED;
|
stmt->state = MYSQLND_STMT_PREPARED;
|
||||||
result->type = MYSQLND_RES_PS_BUF;
|
result->type = MYSQLND_RES_PS_BUF;
|
||||||
} else {
|
} else {
|
||||||
stmt->error_info = conn->error_info;
|
COPY_CLIENT_ERROR(stmt->error_info, conn->error_info);
|
||||||
stmt->state = MYSQLND_STMT_PREPARED;
|
stmt->state = MYSQLND_STMT_PREPARED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -300,7 +316,8 @@ mysqlnd_stmt_read_prepare_response(MYSQLND_STMT * s TSRMLS_DC)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0xFF == prepare_resp->error_code) {
|
if (0xFF == prepare_resp->error_code) {
|
||||||
stmt->error_info = stmt->conn->error_info = prepare_resp->error_info;
|
COPY_CLIENT_ERROR(stmt->error_info, prepare_resp->error_info);
|
||||||
|
COPY_CLIENT_ERROR(stmt->conn->error_info, prepare_resp->error_info);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
ret = PASS;
|
ret = PASS;
|
||||||
|
@ -484,7 +501,7 @@ mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s TSRMLS_DC)
|
||||||
|
|
||||||
ret = mysqlnd_query_read_result_set_header(stmt->conn, s TSRMLS_CC);
|
ret = mysqlnd_query_read_result_set_header(stmt->conn, s TSRMLS_CC);
|
||||||
if (ret == FAIL) {
|
if (ret == FAIL) {
|
||||||
stmt->error_info = conn->error_info;
|
COPY_CLIENT_ERROR(stmt->error_info, conn->error_info);
|
||||||
stmt->upsert_status.affected_rows = conn->upsert_status.affected_rows;
|
stmt->upsert_status.affected_rows = conn->upsert_status.affected_rows;
|
||||||
if (CONN_GET_STATE(conn) == CONN_QUIT_SENT) {
|
if (CONN_GET_STATE(conn) == CONN_QUIT_SENT) {
|
||||||
/* close the statement here, the connection has been closed */
|
/* close the statement here, the connection has been closed */
|
||||||
|
@ -685,7 +702,7 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s TSRMLS_DC)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == FAIL) {
|
if (ret == FAIL) {
|
||||||
stmt->error_info = conn->error_info;
|
COPY_CLIENT_ERROR(stmt->error_info, conn->error_info);
|
||||||
DBG_INF("FAIL");
|
DBG_INF("FAIL");
|
||||||
DBG_RETURN(FAIL);
|
DBG_RETURN(FAIL);
|
||||||
}
|
}
|
||||||
|
@ -902,8 +919,8 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int
|
||||||
*fetched_anything = TRUE;
|
*fetched_anything = TRUE;
|
||||||
} else if (ret == FAIL) {
|
} else if (ret == FAIL) {
|
||||||
if (row_packet->error_info.error_no) {
|
if (row_packet->error_info.error_no) {
|
||||||
stmt->conn->error_info = row_packet->error_info;
|
COPY_CLIENT_ERROR(stmt->conn->error_info, row_packet->error_info);
|
||||||
stmt->error_info = row_packet->error_info;
|
COPY_CLIENT_ERROR(stmt->error_info, row_packet->error_info);
|
||||||
}
|
}
|
||||||
CONN_SET_STATE(result->conn, CONN_READY);
|
CONN_SET_STATE(result->conn, CONN_READY);
|
||||||
result->unbuf->eof_reached = TRUE; /* so next time we won't get an error */
|
result->unbuf->eof_reached = TRUE; /* so next time we won't get an error */
|
||||||
|
@ -1014,7 +1031,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla
|
||||||
if (FAIL == stmt->conn->m->simple_command(stmt->conn, COM_STMT_FETCH, buf, sizeof(buf),
|
if (FAIL == stmt->conn->m->simple_command(stmt->conn, COM_STMT_FETCH, buf, sizeof(buf),
|
||||||
PROT_LAST /* we will handle the response packet*/,
|
PROT_LAST /* we will handle the response packet*/,
|
||||||
FALSE, TRUE TSRMLS_CC)) {
|
FALSE, TRUE TSRMLS_CC)) {
|
||||||
stmt->error_info = stmt->conn->error_info;
|
COPY_CLIENT_ERROR(stmt->error_info, stmt->conn->error_info);
|
||||||
DBG_RETURN(FAIL);
|
DBG_RETURN(FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1218,7 +1235,7 @@ MYSQLND_METHOD(mysqlnd_stmt, reset)(MYSQLND_STMT * const s TSRMLS_DC)
|
||||||
FAIL == (ret = conn->m->simple_command(conn, COM_STMT_RESET, cmd_buf,
|
FAIL == (ret = conn->m->simple_command(conn, COM_STMT_RESET, cmd_buf,
|
||||||
sizeof(cmd_buf), PROT_OK_PACKET,
|
sizeof(cmd_buf), PROT_OK_PACKET,
|
||||||
FALSE, TRUE TSRMLS_CC))) {
|
FALSE, TRUE TSRMLS_CC))) {
|
||||||
stmt->error_info = conn->error_info;
|
COPY_CLIENT_ERROR(stmt->error_info, conn->error_info);
|
||||||
}
|
}
|
||||||
stmt->upsert_status = conn->upsert_status;
|
stmt->upsert_status = conn->upsert_status;
|
||||||
|
|
||||||
|
@ -1337,7 +1354,7 @@ MYSQLND_METHOD(mysqlnd_stmt, send_long_data)(MYSQLND_STMT * const s, unsigned in
|
||||||
ret = conn->m->simple_command(conn, cmd, cmd_buf, packet_len, PROT_LAST , FALSE, TRUE TSRMLS_CC);
|
ret = conn->m->simple_command(conn, cmd, cmd_buf, packet_len, PROT_LAST , FALSE, TRUE TSRMLS_CC);
|
||||||
mnd_efree(cmd_buf);
|
mnd_efree(cmd_buf);
|
||||||
if (FAIL == ret) {
|
if (FAIL == ret) {
|
||||||
stmt->error_info = conn->error_info;
|
COPY_CLIENT_ERROR(stmt->error_info, conn->error_info);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
|
@ -2117,6 +2134,11 @@ MYSQLND_METHOD(mysqlnd_stmt, free_stmt_content)(MYSQLND_STMT * const s TSRMLS_DC
|
||||||
stmt->result->m.free_result_internal(stmt->result TSRMLS_CC);
|
stmt->result->m.free_result_internal(stmt->result TSRMLS_CC);
|
||||||
stmt->result = NULL;
|
stmt->result = NULL;
|
||||||
}
|
}
|
||||||
|
if (stmt->error_info.error_list) {
|
||||||
|
zend_llist_clean(stmt->error_info.error_list);
|
||||||
|
mnd_pefree(stmt->error_info.error_list, s->persistent);
|
||||||
|
stmt->error_info.error_list = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
DBG_VOID_RETURN;
|
DBG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
@ -2174,7 +2196,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, net_close)(MYSQLND_STMT * const s, zend_boo
|
||||||
FAIL == conn->m->simple_command(conn, COM_STMT_CLOSE, cmd_buf, sizeof(cmd_buf),
|
FAIL == conn->m->simple_command(conn, COM_STMT_CLOSE, cmd_buf, sizeof(cmd_buf),
|
||||||
PROT_LAST /* COM_STMT_CLOSE doesn't send an OK packet*/,
|
PROT_LAST /* COM_STMT_CLOSE doesn't send an OK packet*/,
|
||||||
FALSE, TRUE TSRMLS_CC)) {
|
FALSE, TRUE TSRMLS_CC)) {
|
||||||
stmt->error_info = conn->error_info;
|
COPY_CLIENT_ERROR(stmt->error_info, conn->error_info);
|
||||||
DBG_RETURN(FAIL);
|
DBG_RETURN(FAIL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2375,6 +2397,11 @@ MYSQLND_STMT * _mysqlnd_stmt_init(MYSQLND * const conn TSRMLS_DC)
|
||||||
or normal query result will close it then.
|
or normal query result will close it then.
|
||||||
*/
|
*/
|
||||||
stmt->conn = conn->m->get_reference(conn TSRMLS_CC);
|
stmt->conn = conn->m->get_reference(conn TSRMLS_CC);
|
||||||
|
stmt->error_info.error_list = mnd_pecalloc(1, sizeof(zend_llist), ret->persistent);
|
||||||
|
if (!stmt->error_info.error_list) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
zend_llist_init(stmt->error_info.error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t) mysqlnd_ps_error_list_pdtor, conn->persistent);
|
||||||
|
|
||||||
DBG_RETURN(ret);
|
DBG_RETURN(ret);
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
|
@ -400,7 +400,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT * s TSRMLS_DC)
|
||||||
This will copy the error code and the messages, as they
|
This will copy the error code and the messages, as they
|
||||||
are buffers in the struct
|
are buffers in the struct
|
||||||
*/
|
*/
|
||||||
conn->error_info = rset_header->error_info;
|
COPY_CLIENT_ERROR(conn->error_info, rset_header->error_info);
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
DBG_ERR_FMT("error=%s", rset_header->error_info.error);
|
DBG_ERR_FMT("error=%s", rset_header->error_info.error);
|
||||||
/* Return back from CONN_QUERY_SENT */
|
/* Return back from CONN_QUERY_SENT */
|
||||||
|
@ -705,7 +705,7 @@ mysqlnd_fetch_row_unbuffered_c(MYSQLND_RES * result TSRMLS_DC)
|
||||||
}
|
}
|
||||||
} else if (ret == FAIL) {
|
} else if (ret == FAIL) {
|
||||||
if (row_packet->error_info.error_no) {
|
if (row_packet->error_info.error_no) {
|
||||||
result->conn->error_info = row_packet->error_info;
|
COPY_CLIENT_ERROR(result->conn->error_info, row_packet->error_info);
|
||||||
DBG_ERR_FMT("errorno=%u error=%s", row_packet->error_info.error_no, row_packet->error_info.error);
|
DBG_ERR_FMT("errorno=%u error=%s", row_packet->error_info.error_no, row_packet->error_info.error);
|
||||||
}
|
}
|
||||||
CONN_SET_STATE(result->conn, CONN_READY);
|
CONN_SET_STATE(result->conn, CONN_READY);
|
||||||
|
@ -840,7 +840,7 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES * result, void *param, unsigned int fla
|
||||||
result->unbuf->row_count++;
|
result->unbuf->row_count++;
|
||||||
} else if (ret == FAIL) {
|
} else if (ret == FAIL) {
|
||||||
if (row_packet->error_info.error_no) {
|
if (row_packet->error_info.error_no) {
|
||||||
result->conn->error_info = row_packet->error_info;
|
COPY_CLIENT_ERROR(result->conn->error_info, row_packet->error_info);
|
||||||
DBG_ERR_FMT("errorno=%u error=%s", row_packet->error_info.error_no, row_packet->error_info.error);
|
DBG_ERR_FMT("errorno=%u error=%s", row_packet->error_info.error_no, row_packet->error_info.error);
|
||||||
}
|
}
|
||||||
CONN_SET_STATE(result->conn, CONN_READY);
|
CONN_SET_STATE(result->conn, CONN_READY);
|
||||||
|
@ -1228,7 +1228,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND * const conn, MYSQL
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == FAIL) {
|
if (ret == FAIL) {
|
||||||
set->error_info = row_packet->error_info;
|
COPY_CLIENT_ERROR(set->error_info, row_packet->error_info);
|
||||||
} else {
|
} else {
|
||||||
/* Position at the first row */
|
/* Position at the first row */
|
||||||
set->data_cursor = set->data;
|
set->data_cursor = set->data;
|
||||||
|
@ -1277,7 +1277,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result)(MYSQLND_RES * result,
|
||||||
ret = result->m.store_result_fetch_data(conn, result, result->meta, ps_protocol TSRMLS_CC);
|
ret = result->m.store_result_fetch_data(conn, result, result->meta, ps_protocol TSRMLS_CC);
|
||||||
if (FAIL == ret) {
|
if (FAIL == ret) {
|
||||||
if (result->stored_data) {
|
if (result->stored_data) {
|
||||||
conn->error_info = result->stored_data->error_info;
|
COPY_CLIENT_ERROR(conn->error_info, result->stored_data->error_info);
|
||||||
} else {
|
} else {
|
||||||
SET_OOM_ERROR(conn->error_info);
|
SET_OOM_ERROR(conn->error_info);
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,7 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
|
||||||
DBG_RETURN(FAIL);
|
DBG_RETURN(FAIL);
|
||||||
}
|
}
|
||||||
if (field_packet->error_info.error_no) {
|
if (field_packet->error_info.error_no) {
|
||||||
conn->error_info = field_packet->error_info;
|
COPY_CLIENT_ERROR(conn->error_info, field_packet->error_info);
|
||||||
/* Return back from CONN_QUERY_SENT */
|
/* Return back from CONN_QUERY_SENT */
|
||||||
PACKET_FREE(field_packet);
|
PACKET_FREE(field_packet);
|
||||||
DBG_RETURN(FAIL);
|
DBG_RETURN(FAIL);
|
||||||
|
|
|
@ -102,9 +102,18 @@ typedef struct st_mysqlnd_error_info
|
||||||
char error[MYSQLND_ERRMSG_SIZE+1];
|
char error[MYSQLND_ERRMSG_SIZE+1];
|
||||||
char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
|
char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
|
||||||
unsigned int error_no;
|
unsigned int error_no;
|
||||||
|
zend_llist * error_list;
|
||||||
} MYSQLND_ERROR_INFO;
|
} MYSQLND_ERROR_INFO;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct st_mysqlnd_error_list_element
|
||||||
|
{
|
||||||
|
char * error;
|
||||||
|
char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
|
||||||
|
unsigned int error_no;
|
||||||
|
} MYSQLND_ERROR_LIST_ELEMENT;
|
||||||
|
|
||||||
|
|
||||||
typedef struct st_mysqlnd_infile_info
|
typedef struct st_mysqlnd_infile_info
|
||||||
{
|
{
|
||||||
php_stream *fd;
|
php_stream *fd;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue