php手册阅读之int,float坑

一. 类型转换
根据前一篇的内容,找到强制类型转换成int的函数在zend_operators.c的convert_to_long_base, 实现如下:

ZEND_API void convert_to_long_base(zval *op, int base) /* {{{ */
{
	long tmp;

	switch (Z_TYPE_P(op)) {
		case IS_NULL:
			Z_LVAL_P(op) = 0;
			break;
		case IS_RESOURCE: {
				TSRMLS_FETCH();

				zend_list_delete(Z_LVAL_P(op));
			}
			/* break missing intentionally */
		case IS_BOOL:
		case IS_LONG:
			break;
		case IS_DOUBLE:
			Z_LVAL_P(op) = zend_dval_to_lval(Z_DVAL_P(op));
			break;
		case IS_STRING:
			{
				char *strval = Z_STRVAL_P(op);

				Z_LVAL_P(op) = strtol(strval, NULL, base);
				STR_FREE(strval);
			}
			break;
		case IS_ARRAY:
			tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
			zval_dtor(op);
			Z_LVAL_P(op) = tmp;
			break;
		case IS_OBJECT:
			{
				int retval = 1;
				TSRMLS_FETCH();

				convert_object_to_type(op, IS_LONG, convert_to_long);

				if (Z_TYPE_P(op) == IS_LONG) {
					return;
				}
				zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name);

				zval_dtor(op);
				ZVAL_LONG(op, retval);
				return;
			}
		default:
			zend_error(E_WARNING, "Cannot convert to ordinal value");
			zval_dtor(op);
			Z_LVAL_P(op) = 0;
			break;
	}

	Z_TYPE_P(op) = IS_LONG;
}

总结如下:
1. null => 0
2. bool => 由于bool在php内部也是用0,1来表示的。所以true为1, false为0
3. double => 强制转换为long,即向下取整
4. string => Z_LVAL_P(op) = strtol(strval, NULL, base); 使用c语言的strtol函数来处理。即总为0
5. array => 数组不为空则为1否则为0

二. 字符串的前导符为0不是八进制

$x = 0123; // 83
$y = “0123” + 0 // 123

三. 边界
var_dump(-2147483648); //float(-2147483648)
var_dump(-2147483647 – 1); //int(-2147483648)