Skip to content

Commit be2be6d

Browse files
committed
Implement mysqli_fetch_column
1 parent 6adec55 commit be2be6d

File tree

4 files changed

+183
-1
lines changed

4 files changed

+183
-1
lines changed

ext/mysqli/mysqli.stub.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,11 @@ public function fetch_object(string $class = "stdClass", array $constructor_args
428428
*/
429429
public function fetch_row() {}
430430

431+
/**
432+
* @alias mysqli_fetch_column
433+
*/
434+
public function fetch_column(int $column = 0): null|int|string|false {}
435+
431436
/**
432437
* @return bool
433438
* @alias mysqli_field_seek
@@ -667,6 +672,8 @@ function mysqli_fetch_object(mysqli_result $result, string $class = "stdClass",
667672

668673
function mysqli_fetch_row(mysqli_result $result): array|null|false {}
669674

675+
function mysqli_fetch_column(mysqli_result $result, int $column = 0): null|int|string|false {}
676+
670677
function mysqli_field_count(mysqli $mysql): int {}
671678

672679
function mysqli_field_seek(mysqli_result $result, int $index): bool {}

ext/mysqli/mysqli_arginfo.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: b9583854314bc54295c1e1a4ec7f6b8c0ce6187c */
2+
* Stub hash: 744c59d0ae28d46f99e478c903cdf9741f97d134 */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING)
55
ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0)
@@ -114,6 +114,11 @@ ZEND_END_ARG_INFO()
114114

115115
#define arginfo_mysqli_fetch_row arginfo_mysqli_fetch_assoc
116116

117+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_fetch_column, 0, 1, MAY_BE_NULL|MAY_BE_LONG|MAY_BE_STRING|MAY_BE_FALSE)
118+
ZEND_ARG_OBJ_INFO(0, result, mysqli_result, 0)
119+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, column, IS_LONG, 0, "0")
120+
ZEND_END_ARG_INFO()
121+
117122
#define arginfo_mysqli_field_count arginfo_mysqli_errno
118123

119124
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_field_seek, 0, 2, _IS_BOOL, 0)
@@ -606,6 +611,10 @@ ZEND_END_ARG_INFO()
606611

607612
#define arginfo_class_mysqli_result_fetch_row arginfo_class_mysqli_character_set_name
608613

614+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_mysqli_result_fetch_column, 0, 0, MAY_BE_NULL|MAY_BE_LONG|MAY_BE_STRING|MAY_BE_FALSE)
615+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, column, IS_LONG, 0, "0")
616+
ZEND_END_ARG_INFO()
617+
609618
#define arginfo_class_mysqli_result_field_seek arginfo_class_mysqli_result_fetch_field_direct
610619

611620
#define arginfo_class_mysqli_result_free_result arginfo_class_mysqli_character_set_name
@@ -704,6 +713,7 @@ ZEND_FUNCTION(mysqli_fetch_array);
704713
ZEND_FUNCTION(mysqli_fetch_assoc);
705714
ZEND_FUNCTION(mysqli_fetch_object);
706715
ZEND_FUNCTION(mysqli_fetch_row);
716+
ZEND_FUNCTION(mysqli_fetch_column);
707717
ZEND_FUNCTION(mysqli_field_count);
708718
ZEND_FUNCTION(mysqli_field_seek);
709719
ZEND_FUNCTION(mysqli_field_tell);
@@ -828,6 +838,7 @@ static const zend_function_entry ext_functions[] = {
828838
ZEND_FE(mysqli_fetch_assoc, arginfo_mysqli_fetch_assoc)
829839
ZEND_FE(mysqli_fetch_object, arginfo_mysqli_fetch_object)
830840
ZEND_FE(mysqli_fetch_row, arginfo_mysqli_fetch_row)
841+
ZEND_FE(mysqli_fetch_column, arginfo_mysqli_fetch_column)
831842
ZEND_FE(mysqli_field_count, arginfo_mysqli_field_count)
832843
ZEND_FE(mysqli_field_seek, arginfo_mysqli_field_seek)
833844
ZEND_FE(mysqli_field_tell, arginfo_mysqli_field_tell)
@@ -993,6 +1004,7 @@ static const zend_function_entry class_mysqli_result_methods[] = {
9931004
ZEND_ME_MAPPING(fetch_assoc, mysqli_fetch_assoc, arginfo_class_mysqli_result_fetch_assoc, ZEND_ACC_PUBLIC)
9941005
ZEND_ME_MAPPING(fetch_object, mysqli_fetch_object, arginfo_class_mysqli_result_fetch_object, ZEND_ACC_PUBLIC)
9951006
ZEND_ME_MAPPING(fetch_row, mysqli_fetch_row, arginfo_class_mysqli_result_fetch_row, ZEND_ACC_PUBLIC)
1007+
ZEND_ME_MAPPING(fetch_column, mysqli_fetch_column, arginfo_class_mysqli_result_fetch_column, ZEND_ACC_PUBLIC)
9961008
ZEND_ME_MAPPING(field_seek, mysqli_field_seek, arginfo_class_mysqli_result_field_seek, ZEND_ACC_PUBLIC)
9971009
ZEND_ME_MAPPING(free_result, mysqli_free_result, arginfo_class_mysqli_result_free_result, ZEND_ACC_PUBLIC)
9981010
ZEND_ME(mysqli_result, getIterator, arginfo_class_mysqli_result_getIterator, ZEND_ACC_PUBLIC)

ext/mysqli/mysqli_nonapi.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,39 @@ PHP_FUNCTION(mysqli_fetch_assoc)
436436
}
437437
/* }}} */
438438

439+
/* {{{ Fetch a column from the result row */
440+
PHP_FUNCTION(mysqli_fetch_column)
441+
{
442+
MYSQL_RES *result;
443+
zval *mysql_result;
444+
zval row_array;
445+
zend_long col_no = 0;
446+
447+
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &col_no) == FAILURE) {
448+
RETURN_THROWS();
449+
}
450+
MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
451+
452+
if(col_no < 0) {
453+
zend_value_error("Column index must be greater than or equal to 0");
454+
RETURN_THROWS();
455+
}
456+
if(col_no >= result->field_count) {
457+
zend_value_error("Invalid column index");
458+
RETURN_THROWS();
459+
}
460+
461+
php_mysqli_fetch_into_hash_aux(&row_array, result, MYSQLI_NUM);
462+
if (Z_TYPE(row_array) != IS_ARRAY) {
463+
zval_ptr_dtor(&row_array);
464+
RETURN_FALSE;
465+
}
466+
467+
ZVAL_COPY(return_value, zend_hash_index_find(Z_ARR(row_array), col_no));
468+
zval_ptr_dtor(&row_array);
469+
}
470+
/* }}} */
471+
439472
/* {{{ Fetches all result rows as an associative array, a numeric array, or both */
440473
PHP_FUNCTION(mysqli_fetch_all)
441474
{
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
--TEST--
2+
mysqli_fetch_assoc()
3+
--SKIPIF--
4+
<?php
5+
require_once 'skipif.inc';
6+
require_once 'skipifconnectfailure.inc';
7+
?>
8+
--FILE--
9+
<?php
10+
11+
require_once "connect.inc";
12+
require 'table.inc';
13+
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
14+
15+
$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1");
16+
17+
print "[001]\n";
18+
var_dump(mysqli_fetch_column($res));
19+
20+
print "[002]\n";
21+
var_dump(mysqli_fetch_column($res));
22+
23+
24+
$link->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true);
25+
26+
$res = mysqli_query($link, "SELECT
27+
1 AS a,
28+
2 AS a
29+
");
30+
print "[003]\n";
31+
var_dump(mysqli_fetch_column($res, 0));
32+
33+
$res = mysqli_query($link, "SELECT
34+
1 AS a,
35+
2 AS a
36+
");
37+
print "[004]\n";
38+
var_dump(mysqli_fetch_column($res, 1));
39+
40+
$res = mysqli_query($link, "SELECT
41+
1 AS a,
42+
2 AS a,
43+
3
44+
");
45+
print "[005]\n";
46+
var_dump(mysqli_fetch_column($res, 2));
47+
48+
$res = mysqli_query($link, "SELECT
49+
1 AS a,
50+
2 AS a,
51+
3,
52+
NULL AS d
53+
");
54+
print "[006]\n";
55+
var_dump(mysqli_fetch_column($res, 3));
56+
57+
$res = mysqli_query($link, "SELECT
58+
1 AS a,
59+
2 AS a,
60+
3,
61+
NULL AS d,
62+
true AS e
63+
");
64+
print "[007]\n";
65+
var_dump(mysqli_fetch_column($res, 4));
66+
67+
$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1");
68+
print "[008]\n";
69+
try {
70+
var_dump(mysqli_fetch_column($res, -1));
71+
} catch (\ValueError $e) {
72+
echo $e->getMessage(), \PHP_EOL;
73+
}
74+
75+
$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1");
76+
print "[009]\n";
77+
try {
78+
var_dump(mysqli_fetch_column($res, 2));
79+
} catch (\ValueError $e) {
80+
echo $e->getMessage(), \PHP_EOL;
81+
}
82+
83+
mysqli_free_result($res);
84+
try {
85+
mysqli_fetch_column($res);
86+
} catch (Error $exception) {
87+
echo $exception->getMessage() . "\n";
88+
}
89+
90+
$res = $link->query("SELECT id, label FROM test ORDER BY id LIMIT 2");
91+
92+
print "[010]\n";
93+
var_dump($res->fetch_column());
94+
95+
print "[011]\n";
96+
var_dump($res->fetch_column(1));
97+
98+
mysqli_close($link);
99+
100+
print "done!";
101+
?>
102+
--CLEAN--
103+
<?php
104+
require_once "clean_table.inc";
105+
?>
106+
--EXPECT--
107+
[001]
108+
string(1) "1"
109+
[002]
110+
bool(false)
111+
[003]
112+
int(1)
113+
[004]
114+
int(2)
115+
[005]
116+
int(3)
117+
[006]
118+
NULL
119+
[007]
120+
int(1)
121+
[008]
122+
Column index must be greater than or equal to 0
123+
[009]
124+
Invalid column index
125+
mysqli_result object is already closed
126+
[010]
127+
int(1)
128+
[011]
129+
string(1) "b"
130+
done!

0 commit comments

Comments
 (0)