On 15.01.2021 at 18:40, James Colannino wrote:

> On 1/15/21 9:20 AM, James Colannino wrote:
>>
>> On 1/15/21 9:15 AM, Nikita Popov wrote:
>>> On Fri, Jan 15, 2021 at 6:11 PM James Colannino <compo...@colannino.dev>
>>> wrote:
>>>
>>>> I have the following method defined in a PHP 8 extension:
>>>>
>>>> ZEND_BEGIN_ARG_INFO(arginfoCtor, 0)
>>>>       ZEND_ARG_TYPE_INFO(0, hostname, IS_STRING, 0)
>>>>       ZEND_ARG_TYPE_INFO(0, port, IS_LONG, 1)
>>>> ZEND_END_ARG_INFO()
>>>>
>>>> PHP_METHOD(Trogdord, __construct) {
>>>>
>>>>       trogdordObject *objWrapper =
>>>> ZOBJ_TO_TROGDORD(Z_OBJ_P(getThis()));
>>>>
>>>>       char *hostname;
>>>>       size_t hostnameLength;
>>>>       long port = TROGDORD_DEFAULT_PORT;
>>>>
>>>>       zend_parse_parameters_throw(
>>>>           ZEND_NUM_ARGS(),
>>>>           "s|l",
>>>>           &hostname,
>>>>           &hostnameLength,
>>>>           &port
>>>>       );
>>>>
>>>>       ...
>>>> }
>>>>
>>>> This works fine on PHP 7, but on PHP 8, I get an "Arg info / zpp
>>>> mismatch" error. I discovered that if I comment out
>>>> "ZEND_ARG_TYPE_INFO(0, port, IS_LONG, 1)", it works, but I'd like to
>>>> type hint that second optional argument if possible. Maybe I was always
>>>> doing this the wrong way, but I thought that the last argument 1 to
>>>> allow null was the proper way to handle this and I'm not sure why it
>>>> results in an error now.
>>>>
>>>> Can anyone tell me the correct way to approach this in PHP 8? Thank
>>>> you!
>>>>
>>> Your arginfo declares the arugment as nullable, but your zpp call
>>> does not.
>>> Thus the error. You need:
>>>
>>>       zend_bool port_is_null = 1;
>>>       zend_parse_parameters_throw(
>>>           ZEND_NUM_ARGS(),
>>>           "s|l!", // ! means nullable
>>>           &hostname,
>>>           &hostnameLength,
>>>           &port,
>>>           &port_is_null // Whether null was actually passed
>>>       );
>>
>>
>> I tried that, but I still get the "Arginfo / zpp mismatch during call"
>> error.
>
>
> This is the code I have now, which is still giving me the error on PHP 8:
>
> ZEND_BEGIN_ARG_INFO(arginfoCtor, 0)

You need to tell arginfo about the optional parameter:

ZEND_BEGIN_ARG_INFO_EX(arginfoCtor, 0, 0, 1)

However, it is much simpler to write a stub file, and to let
build/gen_stub.php generate the arginfo for you.  See e.g.
<https://github.com/php/php-src/blob/master/ext/standard/basic_functions.stub.php>.

>     ZEND_ARG_TYPE_INFO(0, hostname, IS_STRING, 0)
>     ZEND_ARG_TYPE_INFO(0, port, IS_LONG, 1)
> ZEND_END_ARG_INFO()
>
> PHP_METHOD(Trogdord, __construct) {
>
>     trogdordObject *objWrapper = ZOBJ_TO_TROGDORD(Z_OBJ_P(getThis()));
>
>     char *hostname;
>     size_t hostnameLength;
>
>     long port = TROGDORD_DEFAULT_PORT;
>     zend_bool portIsNull = 1;
>
>     zend_parse_parameters_throw(
>         ZEND_NUM_ARGS(),
>         "s|l!",
>         &hostname,
>         &hostnameLength,
>         &port,
>         &portIsNull
>     );
>
>     ...
> }

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to