[ZBX-18984] >>Required parameter $sql_parts follows optional parameter<< when running zabbix web on php 8.0.2 Created: 2021 Feb 08  Updated: 2022 Jan 07  Resolved: 2021 May 05

Status: Closed
Project: ZABBIX BUGS AND ISSUES
Component/s: Frontend (F)
Affects Version/s: 5.2.4
Fix Version/s: None

Type: Problem report Priority: Critical
Reporter: Stev Leibelt Assignee: Zabbix Development Team
Resolution: Duplicate Votes: 2
Labels: PHP8
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

uname -a
Linux rh-414-pc-43 5.10.13-arch1-2 #1 SMP PREEMPT Sat, 06 Feb 2021 11:07:29 +0000 x86_64 GNU/Linux

php -v
PHP 8.0.2 (cli) (built: Feb 2 2021 18:26:02) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.2, Copyright (c) Zend Technologies

apachectl -v
Server version: Apache/2.4.46 (Unix)
Server built: Oct 14 2020 18:59:56

MariaDB [(none)]> SELECT VERSION();
----------------

VERSION()

----------------

10.5.8-MariaDB

----------------
1 row in set (0.000 sec)


Attachments: Text File 0001-ZBX-18984-fixed.patch     PNG File image-2021-02-08-10-16-35-370.png     PNG File image-2021-02-08-10-17-30-178.png    
Issue Links:
Duplicate
duplicates ZBXNEXT-7080 Provide Frontend support for the upco... Closed
is duplicated by ZBX-19086 Zabbix deprication issues with PHP 8.0+ Closed

 Description   

Steps to reproduce:

  1. Open Dashboard (http://my.host/zabbix)
  2. Login as Administrator
  3. Open any page

Result:

Not on all `dashbrd-grid-widget` but on a lot, you get the following error output.

 

 Required parameter $sql_parts follows optional parameter $table_alias [zabbix.php:22 → require_once() → ZBase->run() → CSettingsHelper::getGlobal() → CSettingsHelper::loadParams() → API::getApiService() → CRegistryFactory->getObject() → CApiService->__construct() → CApiService->pk() → CApiService->getTableSchema() → CAutoloader->loadClass() → require() in include/classes/core/CAutoloader.php:77]
 Required parameter $sql_parts follows optional parameter $table_alias [zabbix.php:22 → require_once() → ZBase->run() → CSettingsHelper::getGlobal() → CSettingsHelper::loadParams() → API::getApiService() → CRegistryFactory->getObject() → CApiService->__construct() → CApiService->pk() → CApiService->getTableSchema() → CAutoloader->loadClass() → require() in include/classes/core/CAutoloader.php:77]
 Required parameter $sql_parts follows optional parameter $table_alias [zabbix.php:22 → require_once() → ZBase->run() → CSettingsHelper::getGlobal() → CSettingsHelper::loadParams() → API::getApiService() → CRegistryFactory->getObject() → CApiService->__construct() → CApiService->pk() → CApiService->getTableSchema() → CAutoloader->loadClass() → require() in include/classes/core/CAutoloader.php:77]
 Required parameter $sql_parts follows optional parameter $table_alias [zabbix.php:22 → require_once() → ZBase->run() → CSettingsHelper::getGlobal() → CSettingsHelper::loadParams() → API::getApiService() → CRegistryFactory->getObject() → CApiService->__construct() → CApiService->pk() → CApiService->getTableSchema() → CAutoloader->loadClass() → require() in include/classes/core/CAutoloader.php:77]

 

I tried to find the right place, but couldn't find the function.

I know that since php 8, there is a quite similar [deprecation](https://php.watch/versions/8.0/deprecate-required-param-after-optional) notice if a function defines a mandatory parameter after an optional.

Apache `error_log` is silent so far. I am using apache with php-fpm.

The error exists since I've upgraded to php 8 (because arch did it this way).

Buzz me if you need more information.

I was not able to find a repostiory for this code, could you please point me to it, if possible?

Expected:

No error is displayed.



 Comments   
Comment by Stev Leibelt [ 2021 Feb 08 ]

Damn, sorry for the bad formatting. Looks like I am not able to edit my own post.

Following my system information.

uname -a
Linux rh-414-pc-43 5.10.13-arch1-2 #1 SMP PREEMPT Sat, 06 Feb 2021 11:07:29 +0000 x86_64 GNU/Linux

apachectl -v
Server version: Apache/2.4.46 (Unix)
Server built:   Oct 14 2020 18:59:56

php -v
PHP 8.0.2 (cli) (built: Feb  2 2021 18:26:02) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.2, Copyright (c) Zend Technologies

SELECT VERSION();
+----------------+
| VERSION()      |
+----------------+
| 10.5.8-MariaDB |
+----------------+
1 row in set (0.000 sec)

Following a screenshot if you are logged in as admin.

And a screenshot if you are logged in as regular user.

 

Comment by Stev Leibelt [ 2021 Feb 08 ]

After searching for the "evil" file, I think I found it.

The file path is `ui/include/classes/db/DB.php`.
This class contains three private methods triggering the output.
The methods are:

  • `private static function applyQueryOutputOptions($table_name, array $options, $table_alias = null, array $sql_parts)`
  • `private static function applyQueryFilterOptions($table_name, array $options, $table_alias = null, array $sql_parts)`
  • `private static function applyQuerySortOptions($table_name, array $options, $table_alias = null, array $sql_parts)`
    As you see, the notice is correct, `$sql_parts` is behind the optional parameter `table_alias`.
    From inside the code, `$sql_parts` needs to be an array plus needs to contain the key `'order'`.
    Good thing, it is a private method and it is only used at one place.

With the patch from below, I was able to reduce the amount of Errors to one. I will try to find the last one tomorrow.

diff --git a/ui/include/classes/db/DB.php b/ui/include/classes/db/DB.php
index 4bb3a50050..59b84fc0a8 100644
--- a/ui/include/classes/db/DB.php
+++ b/ui/include/classes/db/DB.php
@@ -990,13 +990,13 @@ class DB {
                ];

                // add output options
-               $sql_parts = self::applyQueryOutputOptions($table_name, $options, $table_alias, $sql_parts);
+               $sql_parts = self::applyQueryOutputOptions($table_name, $options, $sql_parts, $table_alias);

                // add filter options
-               $sql_parts = self::applyQueryFilterOptions($table_name, $options, $table_alias, $sql_parts);
+               $sql_parts = self::applyQueryFilterOptions($table_name, $options, $sql_parts, $table_alias);

                // add sort options
-               $sql_parts = self::applyQuerySortOptions($table_name, $options, $table_alias, $sql_parts);
+               $sql_parts = self::applyQuerySortOptions($table_name, $options, $sql_parts, $table_alias);

                return $sql_parts;
        }
@@ -1006,13 +1006,13 @@ class DB {
         *
         * @param string $table_name
         * @param array  $options
-        * @param string $table_alias
         * @param array  $sql_parts
+     * @param string $table_alias
         *
         * @return array
         */
-       private static function applyQueryOutputOptions($table_name, array $options, $table_alias = null,
-                       array $sql_parts) {
+       private static function applyQueryOutputOptions($table_name, array $options, array $sql_parts,
+            $table_alias = null) {
                if ($options['countOutput']) {
                        $sql_parts['select'][] = 'COUNT('.self::fieldId('*', $table_alias).') AS rowscount';
                }
@@ -1042,13 +1042,13 @@ class DB {
         *
         * @param string $table_name
         * @param array  $options
-        * @param string $table_alias
         * @param array  $sql_parts
+     * @param string $table_alias
         *
         * @return array
         */
-       private static function applyQueryFilterOptions($table_name, array $options, $table_alias = null,
-                       array $sql_parts) {
+       private static function applyQueryFilterOptions($table_name, array $options, array $sql_parts,
+            $table_alias = null) {
                $table_schema = self::getSchema($table_name);
                $pk = self::getPk($table_name);
                $pk_option = $pk.'s';
@@ -1149,12 +1149,12 @@ class DB {
         *
         * @param string $table_name
         * @param array  $options
-        * @param string $table_alias
         * @param array  $sql_parts
+     * @param string $table_alias
         *
         * @return array
         */
-       private static function applyQuerySortOptions($table_name, array $options, $table_alias = null, array $sql_parts) {
+       private static function applyQuerySortOptions($table_name, array $options, array $sql_parts, $table_alias = null) {
                $table_schema = self::getSchema($table_name);

                foreach ($options['sortfield'] as $index => $field_name) {

Side note, today was the first time I looked into the php code of zabbix and I really liked what I saw. Keep up the good coding guideline.
 

Comment by Stev Leibelt [ 2021 Feb 08 ]

Found the last method, `DB::dbFilter`. Same adaptation as before and now the frontend is working perfectly with php 8.0.2.

Comment by Stev Leibelt [ 2021 Feb 08 ]

Pull request created. Pofta Buna!

Comment by Stev Leibelt [ 2021 Feb 09 ]

Since, for good reasons, I have not write access to the official official git repository, I will try to ease up things by providing the patchfile here too.

0001-ZBX-18984-fixed.patch

Comment by Stev Leibelt [ 2021 Mar 04 ]

Hey,

 

is there any plan when this issue will be solved/my fix will be merged?

I've just upgraded to Zabbix 5.2.5-1 and the issue still exists.

Comment by Rostislav Palivoda [ 2021 Mar 26 ]

Hi artodeto, thank you for the provided patch. We will start work on PHP8 support after 5.4.0rc1 release. Apart of running frontend there are also auto tests migration to PHP8. Please follow status of ZBX-17930 for migration progress. A PHP8 patch for phpunit zabbix tests would be nice contribution. 

Comment by Stev Leibelt [ 2021 May 05 ]

Thank you for your great @Rostislav Palivoda and @dimir feedback and being transparent with the upcoming status. I am happy when my patch was a help. I will try to support as much as possible. Your product is great and well done, I can totally feel your passion whenever I figure out something new that is already built in.

Comment by Stev Leibelt [ 2021 Jun 14 ]

Hello,

 

so zabbix 5.4 was released but the issue still exists. Any progress or time schedule planned here?

Comment by Stev Leibelt [ 2021 Jun 14 ]

With Zabbix 5.4, there where introduced two more erros.

 

Clickpath: Configuration -> Hosts -> $HOST

You get the error message, that the mandatory parameter "$context" is behind the optional parameter "$items".

 

To fix this, you have to adapt two files.

 

//file path: include/forms.inc.php
//you have to replace this line
function makeItemSubfilter(array &$filter_data, array $items = [], string $context) {

//with that line
function makeItemSubfilter(array &$filter_data, string $context, array $items = []) {
//file path: items.php
//you have to replace this line
$data['subfilter'] = makeItemSubfilter($data['filter_data'], $data['items'], $data['context']);

//with that line
$data['subfilter'] = makeItemSubfilter($data['filter_data'], $data['context'], $data['items']);

I will try to update my github push request.

Comment by Stev Leibelt [ 2021 Jun 14 ]

FYI: I've updated my pull request on github.com with my fix. Is there anyone maintaining the github pull requests?

Comment by Hugo [ 2021 Jun 30 ]

For version 5.2.6 I can't open maps. Show a blank screen

http://xxxx/zabbix.php?action=map.view

 

PHP Fatal error:  Uncaught ArgumentCountError: array_merge() does not accept unknown named parameters in /usr/share/webapps/zabbix/include/classes/macros/CMacrosResolver.php:2118\nStack trace:\n#0 /usr/share/webapps/zabbix/include/classes/macros/CMacrosResolver.php(2118): array_merge()\n#1 [internal function]: CMacrosResolver->{closure}()\n#2 /usr/share/webapps/zabbix/include/classes/macros/CMacrosResolver.php(2119): array_map()\n#3 /usr/share/webapps/zabbix/include/classes/macros/CMacrosResolverHelper.php(674): CMacrosResolver->resolveMacrosInMapElements()\n#4 /usr/share/webapps/zabbix/include/classes/helpers/CMapHelper.php(103): CMacrosResolverHelper::resolveMacrosInMapElements()\n#5 /usr/share/webapps/zabbix/include/classes/screens/CScreenMap.php(36): CMapHelper::get()\n#6 /usr/share/webapps/zabbix/app/views/monitoring.map.view.php(91): CScreenMap->get()\n#7 /usr/share/webapps/zabbix/include/classes/mvc/CView.php(122): include('...')\n#8 /usr/share/webapps/zabbix/include/classes/core/ZBase.php(618): CView->getOutput()\n#9 /usr/share/webapps/zabbix/include/classes/core/ZBase.php(547): ZBase->processResponseFinal()\n#10 /usr/share/webapps/zabbix/include/classes/core/ZBase.php(211): ZBase->processRequest()\n#11 /usr/share/webapps/zabbix/include/config.inc.php(25): ZBase->run()\n#12 /usr/share/webapps/zabbix/zabbix.php(22): require_once('...')\n#13 {main}\n  thrown in /usr/share/webapps/zabbix/include/classes/macros/CMacrosResolver.php on line 2118

 

Comment by Stev Leibelt [ 2021 Jul 15 ]

@Hugo

 

Is your issue a general one or does this happen after you've patched your local installation with my changes?

Do you also run a php 8.0 environment?

At least I have the same issue like you said. Let's see when I find the time to provide a fix and merge it into my pull request.

 

[Edit: 20210715 10:37]

After searching the internet, the fix might be a simple onel.

Generated at Mon May 05 07:30:23 EEST 2025 using Jira 9.12.4#9120004-sha1:625303b708afdb767e17cb2838290c41888e9ff0.