Re: Arg info / zpp mismatch on PHP 8.0
| From: | Christoph M. Becker | Date: | Fri, 15 Jan 2021 18:17:13 +0000 |
| Subject: | Re: Arg info / zpp mismatch on PHP 8.0 | ||
| References: | 1 2 3 4 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-112906@lists.php.net to get a copy of this message | ||
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
> );
>
> ...
> }