Commit 9d30bd57251 for php.net

commit 9d30bd57251147c3af70fe6ee6001558bef6bc10
Author: Calvin Buckley <calvinb@php.net>
Date:   Mon Apr 13 12:48:24 2026 -0400

    Finish deprecation of $row < 1 (#21053)

    odbc_fetch_row was changed to have $row be nullable and null by default
    instead of using 0, but still accepted 0 due to old code being explicit. Use
    ValueError for non-null $row < 1 instead.

diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c
index 96e1b879614..95c872c293f 100644
--- a/ext/odbc/php_odbc.c
+++ b/ext/odbc/php_odbc.c
@@ -1340,12 +1340,11 @@ static void php_odbc_fetch(INTERNAL_FUNCTION_PARAMETERS, bool return_array, php_
 	result = Z_ODBC_RESULT_P(pv_res);
 	CHECK_ODBC_RESULT(result);

-	/* TODO deprecate $row argument values less than 1 after PHP 8.4
-	 * for functions other than odbc_fetch_row (see GH-13910)
-	 */
-	if (!result_type && !pv_row_is_null && pv_row < 1) {
-		php_error_docref(NULL, E_WARNING, "Argument #3 ($row) must be greater than or equal to 1");
-		RETURN_FALSE;
+	if (!pv_row_is_null && pv_row < 1) {
+		/* row arg no differs between callers */
+		zend_argument_value_error(pv_res_arr == return_value ? 2 : 3,
+				"must be greater than or equal to 1");
+		RETURN_THROWS();
 	}

 	if (result->numcols == 0) {
diff --git a/ext/odbc/tests/odbc_fetch_array_001.phpt b/ext/odbc/tests/odbc_fetch_array_001.phpt
index bf13ed25e4d..e7d4ccf328b 100644
--- a/ext/odbc/tests/odbc_fetch_array_001.phpt
+++ b/ext/odbc/tests/odbc_fetch_array_001.phpt
@@ -17,7 +17,7 @@
 $res = odbc_exec($conn, 'SELECT * FROM fetch_array');

 var_dump(odbc_fetch_array($res));
-var_dump(odbc_fetch_array($res, 0));
+var_dump(odbc_fetch_array($res, null));
 var_dump(odbc_fetch_array($res, 2));
 var_dump(odbc_fetch_array($res, 4));

diff --git a/ext/odbc/tests/odbc_fetch_into_001.phpt b/ext/odbc/tests/odbc_fetch_into_001.phpt
index 19f7f79268c..e420475f02c 100644
--- a/ext/odbc/tests/odbc_fetch_into_001.phpt
+++ b/ext/odbc/tests/odbc_fetch_into_001.phpt
@@ -20,7 +20,7 @@
 var_dump(odbc_fetch_into($res, $arr));
 var_dump($arr);
 $arr = [];
-var_dump(odbc_fetch_into($res, $arr, 0));
+var_dump(odbc_fetch_into($res, $arr, null));
 var_dump($arr);
 $arr = [];
 var_dump(odbc_fetch_into($res, $arr, 2));
diff --git a/ext/odbc/tests/odbc_fetch_object_001.phpt b/ext/odbc/tests/odbc_fetch_object_001.phpt
index 62a8fc3b2c7..eb553409639 100644
--- a/ext/odbc/tests/odbc_fetch_object_001.phpt
+++ b/ext/odbc/tests/odbc_fetch_object_001.phpt
@@ -17,7 +17,7 @@
 $res = odbc_exec($conn, 'SELECT * FROM fetch_object');

 var_dump(odbc_fetch_object($res));
-var_dump(odbc_fetch_object($res, 0));
+var_dump(odbc_fetch_object($res, null));
 var_dump(odbc_fetch_object($res, 2));
 var_dump(odbc_fetch_object($res, 4));

diff --git a/ext/odbc/tests/odbc_fetch_row_001.phpt b/ext/odbc/tests/odbc_fetch_row_001.phpt
index 576bb15414c..fbadc827259 100644
--- a/ext/odbc/tests/odbc_fetch_row_001.phpt
+++ b/ext/odbc/tests/odbc_fetch_row_001.phpt
@@ -17,7 +17,11 @@

 $res = odbc_exec($conn, 'SELECT * FROM fetch_row');

-var_dump(odbc_fetch_row($res, 0));
+try {
+    var_dump(odbc_fetch_row($res, 0));
+} catch (\ValueError $e) {
+    echo $e->getMessage() . \PHP_EOL;
+}

 var_dump(odbc_fetch_row($res, null));
 var_dump(odbc_result($res, 'test'));
@@ -39,9 +43,8 @@
 $conn = odbc_connect($dsn, $user, $pass);
 odbc_exec($conn, 'DROP TABLE fetch_row');
 ?>
---EXPECTF--
-Warning: odbc_fetch_row(): Argument #3 ($row) must be greater than or equal to 1 in %s on line %d
-bool(false)
+--EXPECT--
+odbc_fetch_row(): Argument #2 ($row) must be greater than or equal to 1
 bool(true)
 string(1) "1"
 bool(true)