Add get_debug_type() function

RFC: https://wiki.php.net/rfc/get_debug_type
This commit is contained in:
Your Name 2020-02-02 21:43:42 +00:00 committed by Nikita Popov
parent 8597ec00d4
commit ef0e4478c5
5 changed files with 114 additions and 0 deletions

View File

@ -534,6 +534,10 @@ PHP 8.0 UPGRADE NOTES
. Added fdiv() function, which performs a floating-point division under
IEEE 754 semantics. Division by zero is considered well-defined and
will return one of Inf, -Inf or NaN.
. Added get_debug_type() function, which returns a type useful for error
messages. Unlike get_type(), it uses canonical type names, returns class
names for objects, and indicates the resource type for resources.
RFC: https://wiki.php.net/rfc/get_debug_type
- Zip:
. ZipArchive::setMtimeName and ZipArchive::setMtimeIndex to set the

View File

@ -1382,6 +1382,9 @@ function socket_set_timeout($socket, int $seconds, int $microseconds = 0): bool
/** @param mixed $var */
function gettype($var): string {}
/** @param mixed $var */
function get_debug_type($var): string {}
function settype(&$var, string $type): bool {}
/** @param mixed $value */

View File

@ -2051,6 +2051,8 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_gettype, 0, 1, IS_STRING, 0)
ZEND_ARG_INFO(0, var)
ZEND_END_ARG_INFO()
#define arginfo_get_debug_type arginfo_gettype
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_settype, 0, 2, _IS_BOOL, 0)
ZEND_ARG_INFO(1, var)
ZEND_ARG_TYPE_INFO(0, type, IS_STRING, 0)
@ -2792,6 +2794,7 @@ ZEND_FUNCTION(stream_set_chunk_size);
ZEND_FUNCTION(stream_set_timeout);
#endif
ZEND_FUNCTION(gettype);
ZEND_FUNCTION(get_debug_type);
ZEND_FUNCTION(settype);
ZEND_FUNCTION(intval);
ZEND_FUNCTION(floatval);
@ -3436,6 +3439,7 @@ static const zend_function_entry ext_functions[] = {
ZEND_FALIAS(socket_set_timeout, stream_set_timeout, arginfo_socket_set_timeout)
#endif
ZEND_FE(gettype, arginfo_gettype)
ZEND_FE(get_debug_type, arginfo_get_debug_type)
ZEND_FE(settype, arginfo_settype)
ZEND_FE(intval, arginfo_intval)
ZEND_FE(floatval, arginfo_floatval)

View File

@ -0,0 +1,57 @@
--TEST--
Test get_debug_type() class reading
--FILE--
<?php
namespace Demo {
class ClassInNamespace {
}
}
namespace {
class ClassInGlobal { }
class ToBeExtended { }
interface ToBeImplemented { }
$fp = fopen(__FILE__, 'r');
$fp_closed = fopen(__FILE__, 'r');
fclose($fp_closed);
/* tests against an object type */
echo get_debug_type(new ClassInGlobal()) . "\n";
echo get_debug_type(new Demo\ClassInNamespace()) . "\n";
echo get_debug_type(new class {}) . "\n";
echo get_debug_type(new class extends ToBeExtended {}) . "\n";
echo get_debug_type(new class implements ToBeImplemented {}) . "\n";
/* scalars */
echo get_debug_type("foo") . "\n";
echo get_debug_type(false) . "\n";
echo get_debug_type(true) . "\n";
echo get_debug_type(1) . "\n";
echo get_debug_type(1.1) . "\n";
echo get_debug_type([]) . "\n";
echo get_debug_type(null) . "\n";
echo get_debug_type($fp) . "\n";
echo get_debug_type($fp_closed) . "\n";
}
--EXPECT--
ClassInGlobal
Demo\ClassInNamespace
class@anonymous
ToBeExtended@anonymous
ToBeImplemented@anonymous
string
bool
bool
int
float
array
null
resource (stream)
resource (closed)

View File

@ -37,6 +37,52 @@ PHP_FUNCTION(gettype)
}
/* }}} */
/* {{{ proto string get_debug_type(mixed var)
Returns the type of the variable resolving class names */
PHP_FUNCTION(get_debug_type)
{
zval *arg;
const char *name;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ZVAL(arg)
ZEND_PARSE_PARAMETERS_END();
switch (Z_TYPE_P(arg)) {
case IS_NULL:
RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_NULL_LOWERCASE));
case IS_FALSE:
case IS_TRUE:
RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_BOOL));
case IS_LONG:
RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_INT));
case IS_DOUBLE:
RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_FLOAT));
case IS_STRING:
RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_STRING));
case IS_ARRAY:
RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_ARRAY));
case IS_OBJECT:
if (Z_OBJ_P(arg)->ce->ce_flags & ZEND_ACC_ANON_CLASS) {
name = ZSTR_VAL(Z_OBJ_P(arg)->ce->name);
RETURN_NEW_STR(zend_string_init(name, strlen(name), 0));
} else {
RETURN_STR_COPY(Z_OBJ_P(arg)->ce->name);
}
case IS_RESOURCE:
name = zend_rsrc_list_get_rsrc_type(Z_RES_P(arg));
if (name) {
RETURN_NEW_STR(zend_strpprintf(0, "resource (%s)", name));
} else {
RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_CLOSED_RESOURCE));
}
default:
RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_UNKNOWN));
}
}
/* }}} */
/* {{{ proto bool settype(mixed &var, string type)
Set the type of the variable */
PHP_FUNCTION(settype)