diff --git a/ext/dom/tests/modern/xml/return_scalars_from_xpath.phpt b/ext/dom/tests/modern/xml/return_scalars_from_xpath.phpt new file mode 100644 index 000000000000..a3b0b0a2d683 --- /dev/null +++ b/ext/dom/tests/modern/xml/return_scalars_from_xpath.phpt @@ -0,0 +1,25 @@ +--TEST-- +Returning scalar values from Dom\XPath callback +--EXTENSIONS-- +dom +--FILE-- +'); +$xpath = new Dom\XPath($dom); +$xpath->registerPhpFunctionNs('urn:x', 'get-int', fn(): int => 42); +$xpath->registerPhpFunctionNs('urn:x', 'get-float', fn(): float => 4.2); +$xpath->registerPhpFunctionNs('urn:x', 'get-string', fn(): string => "test"); +$xpath->registerPhpFunctionNs('urn:x', 'get-bool', fn(bool $b): bool => $b); +$xpath->registerNamespace('x', 'urn:x'); +var_dump($xpath->evaluate('x:get-int()')); +var_dump($xpath->evaluate('x:get-float()')); +var_dump($xpath->evaluate('x:get-string()')); +var_dump($xpath->evaluate('x:get-bool(1)')); +var_dump($xpath->evaluate('x:get-bool(0)')); +?> +--EXPECT-- +float(42) +float(4.2) +string(4) "test" +bool(true) +bool(false) diff --git a/ext/dom/xpath_callbacks.c b/ext/dom/xpath_callbacks.c index 90395dc15f2e..c659359d67fc 100644 --- a/ext/dom/xpath_callbacks.c +++ b/ext/dom/xpath_callbacks.c @@ -438,6 +438,10 @@ static zend_result php_dom_xpath_callback_dispatch(php_dom_xpath_callbacks *xpat valuePush(ctxt, xmlXPathNewNodeSet(nodep)); } else if (Z_TYPE(callback_retval) == IS_FALSE || Z_TYPE(callback_retval) == IS_TRUE) { valuePush(ctxt, xmlXPathNewBoolean(Z_TYPE(callback_retval) == IS_TRUE)); + } else if (Z_TYPE(callback_retval) == IS_LONG) { + valuePush(ctxt, xmlXPathNewFloat(Z_LVAL(callback_retval))); + } else if (Z_TYPE(callback_retval) == IS_DOUBLE) { + valuePush(ctxt, xmlXPathNewFloat(Z_DVAL(callback_retval))); } else if (Z_TYPE(callback_retval) == IS_OBJECT) { zend_type_error("Only objects that are instances of DOM nodes can be converted to an XPath expression"); zval_ptr_dtor(&callback_retval);