Rest API v4_1 is not working with my new setup i.e. php 8.0, SuiteCRM 7.13

Hello All,

Rest API v4_1 is not working with my new setup.
PHP 8.0
SuiteCRM 7.13.

Kindly assist.

Thanks in advance

I had problems getting the API to work with PHP 8.0. Not sure if thatā€™s your problem, but switching back to 7.4 magically solved my problem.

Thanks for the reply @pstevens,

Actually, we have to work on PHP8 and that is mandatory we can not use 7.4

You"ll have to track down the PHP error then. I tried and spent some time trying to get to the bottom of it but couldnā€™t find what the problem was exactly.

Hi,
Do SuiteCRM log level to Debug and then see your PHP error logs to find the actual cause. In PHP 8, if a variable is undefined, code crashes.
So you have to find the point, where it is happening.
Thanks

Yes, I am also not getting anything in php errorlog

Hi @suitecrm_developer, I tried this but got nothing in logs

Hi @pgr facing the same issue , unable to get rest api work , tried the solution at REST API v2 issue with suitecrm7.13 and php8 - #8 by crmspace

Any suggestions would be helpful

When I get a minute Iā€™ll try to generate the error again. I was trying to sync Mautic with SuiteCRM and had to roll back to 7.4 to get it to work. I did get a PHP error in the server logs, I think it was a call to undefined function or something. Iā€™ll see if I can re-create the error and get the source of the problem. I did have the function that was causing the problem and the line number. I donā€™t have notes on it though.

Hereā€™s the error Iā€™m getting when I try to connect. Itā€™s not in SuiteCRM error log but in server PHP logs.

[28-Sep-2023 19:20:40 America/New_York] PHP Fatal error:  Uncaught Error: Unknown named parameter $application_name in .../suitecrm/service/core/REST/SugarRestJSON.php:94
Stack trace:
#0 /suitecrm/service/core/SugarRestService.php(136): SugarRestJSON->serve()
#1 /suitecrm/service/core/webservice.php(70): SugarRestService->serve()
#2 /suitecrm/service/v4_1/rest.php(56): require_once('sorry didn't output the full name and path...')
#3 {main}
  thrown in /suitecrm/service/core/REST/SugarRestJSON.php on line 94

Hereā€™s the function thatā€™s the problem, I just donā€™t know enough about the difference between 7.4 and 8.0 to solve.

public function serve(){
		$GLOBALS['log']->info('Begin: SugarRestJSON->serve');
		$json_data = !empty($_REQUEST['rest_data'])? $GLOBALS['RAW_REQUEST']['rest_data']: '';
		if(empty($_REQUEST['method']) || !method_exists($this->implementation, $_REQUEST['method'])){
			$er = new SoapError();
			$er->set_error('invalid_call');
			$this->fault($er);
		}else{
			$method = $_REQUEST['method'];
			$json = getJSONObj();
			$data = $json->decode($json_data);
			if(!is_array($data))$data = array($data);
            if (!isset($data['application_name']) && isset($data['application'])){
                $data['application_name'] = $data['application'];
            }
			$res = call_user_func_array(array( $this->implementation, $method),$data);
			$GLOBALS['log']->info('End: SugarRestJSON->serve');
			return $res;
		} // else
	} // fn

Line 94 is:

$json = getJSONObj();

@pstevens are you sure thatā€™s really what is in line 94?

To me, the error only makes sense if it is coming fromm the line with call_user_func_array. In that case, it would be helpful to know the values of all the arguments there ($this->implementation, $method, $data).

Itā€™s basically a dynamic call to a function somewhere, and a parameter mismatch between the call and the function definition.

Hey @pgr, thanks for chiming in. Yeah thatā€™s the right line. Thatā€™s why Iā€™m kind of stuck because itā€™s not super helpful. I did search call_user_function_array and itā€™s in many places. I think probably in class.soap_server.php or SugarBean.php orutils.php are good candidates that would likely be called from the API.

I also found this:

PHP 8 introduced breaking change to call_user_func_array()

  • call_user_func_array() array keys will now be interpreted as parameter names, instead of being silently ignored.

Iā€™m just not sure where to look next. I can do an output to log, just not sure of what. Are you saying I should output $this->implementation, $method, $data) these variables to log. If so I can do that and report back.

Exactly.

That array( $this->implementation, $method) will be interpreted as a PHP callable

So $this->implementation will be the object, and $method will be the function name for that dynamic call. And $data is an array with parameter names and values.

When we discover what itā€™s calling, we can go and check why it doesnā€™t like the named parameter itā€™s getting.

1 Like

OK hereā€™s the output (also youā€™re right, my line #94 is different from #94 on github) Line 94 in my system is:

$res = call_user_func_array(array( $this->implementation, $method),$data);

Here is the output of the variables (confidential info removed with XXXXXX)

Sat Sep 30 11:34:35 2023 [16880][-none-][FATAL] this->implementation: SugarWebServiceImplv4_1 Object
(
)

Sat Sep 30 11:34:35 2023 [16880][-none-][FATAL] method: login
Sat Sep 30 11:34:35 2023 [16880][-none-][FATAL] data: Array
(
    [user_auth] => Array
        (
            [user_name] => XXXXXXXXXX
            [password] => XXXXXXXXXXX
            [version] => 1
        )

    [application_name] => Mautic
    [name_value_list] => Array
        (
        )

    [method] => login
    [input_type] => JSON
    [response_type] => JSON
)

Thanks @pgr Iā€™m happy to do the legwork if you point me in the right direction. :grin:

ChatGPT (I know you hate it!) suggests this:

$res = $this->implementation->{$method}(...array_values($data));

To bypass the call_user_function_array entirely. Iā€™ll give it a shot and report back.

That seems to solve it! I can successfully run the API call between Mautic and SuiteCRM with this line modified. Looks itā€™s itā€™s ChatGPT for the win!

@pgr, if you think that makes sense, let me know and Iā€™ll put in a PR. (this is a little more complex PHP than Iā€™m comfortable with and I donā€™t totally understand the issue, other than this seems to make it work).

I think that with call_user_function_array itā€™s expecting $data to be an indexed array when itā€™s an associative array. (PHP 8 change). So outputting it without this function allows it to be either an associative or an indexed array which is more flexible and avoids the error. (I think?). They syntax is just kind of new to me.

Iā€™m also not sure if this is specific to my API call from Mautic, or all API calls?

I like ChatGPT and I use it sometimes. Judiciously. I just donā€™t like people who donā€™t use it judiciously and dump cheap, long, mostly wrong, answers here in the Forums.

In this case, I would prefer a fix that keeps a bit more strictness, since I donā€™t know all the cases where this will be called, but I am guessing it will be a very diverse group of dynamic calls. And itā€™s hard to search the code since the dynamic calls (putting a function name in a variable and then calling it from that variable) naturally donā€™t show in text searches, itā€™s a run-time thing.

It all boils down to the parameter name being application or application_name in this function.

So I found that this recent fix was supposed to solve this for the newer PHPā€™s:

It tries to handle the two cases by sending both parameters, and then figuring it out inside the called function.

If you have the latest code, both in the calling side and in the called side, and it doesnā€™t work, I would suggest commenting on that PR, providing the full information you gathered hereā€¦

1 Like

Ok Iā€™ll try that patch and see if it solves as well.

Hi @pstevens,

Is it working for you can you please confirm?

I tried this fix but it is not working and I am getting the same error like before.

Thank you

Changing this line worked for me. I havenā€™t had a chance to try the other fix yet.