On 1/15/21 10:17 AM, Christoph M. Becker wrote:
> 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 <composer@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
>> );
>>
>> ...
>> }
Ahh, okay. That fixed it. Also, I didn't know about build/gen_stub.php.
That will help me out a lot in the future. Thank you!