Please take under consideration this patch to fully utilize cast_object
handlers in the new parameter parsing API.
The old parameter API forced the called function to validate and convert its
arguments using the convert_to_* functions.
The convert_to_* functions make use of cast_object handlers if they exist on
objects which makes passing objects (which implement cast_object) to these
functions possible.
However, with the new parameter parsing API (zend_parse_parameters, et.al.),
it only makes use of the cast_object handler if the expected type is a
string.
This unnecessarily weakens the capability of the cast_object handler.
It makes sense that if an object implements a handler for a string cast,
then it should be able to be used anywhere a string can.
The patch is also attached as a .txt file in case the email really hoses it.
--- zend_API.c 2005-11-03 20:26:02.000000000 -0800
+++ zend_API.c 2005-11-03 20:26:02.000000000 -0800
@@ -312,8 +312,17 @@
*p = Z_LVAL_PP(arg);
break;
-
case IS_OBJECT: {
-
if (Z_OBJ_HANDLER_PP(arg,
cast_object)) {
SEPARATE_ZVAL_IF_NOT_REF(arg);
-
if
(Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_LONG, 0 TSRMLS_CC) ==
SUCCESS) {
-
*p =
Z_LVAL_PP(arg);
-
break;
-
}
-
}
-
}
-
case IS_ARRAY:
-
case IS_OBJECT: case IS_RESOURCE: default: return "long";
@@ -346,8 +355,17 @@
*p = Z_DVAL_PP(arg);
break;
-
case IS_OBJECT: {
-
if (Z_OBJ_HANDLER_PP(arg,
cast_object)) {
SEPARATE_ZVAL_IF_NOT_REF(arg);
-
if
(Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_DOUBLE, 0 TSRMLS_CC) ==
SUCCESS) {
-
*p =
Z_DVAL_PP(arg);
-
break;
-
}
-
}
-
}
-
case IS_ARRAY:
-
case IS_OBJECT: case IS_RESOURCE: default: return "double";
@@ -408,8 +426,17 @@
*p = Z_BVAL_PP(arg);
break;
-
case IS_OBJECT: {
-
if (Z_OBJ_HANDLER_PP(arg,
cast_object)) {
SEPARATE_ZVAL_IF_NOT_REF(arg);
-
if
(Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_BOOL, 0 TSRMLS_CC) ==
SUCCESS) {
-
*p =
Z_BVAL_PP(arg);
-
break;
-
}
-
}
-
}
-
case IS_ARRAY:
-
case IS_OBJECT: case IS_RESOURCE: default: return "boolean";
@@ -434,6 +461,15 @@
case 'a':
{
zval **p = va_arg(*va, zval **);
-
if (Z_TYPE_PP(arg) == IS_OBJECT) {
-
if (Z_OBJ_HANDLER_PP(arg,
cast_object)) {
SEPARATE_ZVAL_IF_NOT_REF(arg);
-
if (Z_OBJ_HANDLER_PP(arg,
cast_object)(*arg, *arg, IS_ARRAY, 0 TSRMLS_CC) == SUCCESS) {
-
*p = *arg;
-
break;
-
}
-
}
-
} if (Z_TYPE_PP(arg) != IS_ARRAY) { if (Z_TYPE_PP(arg) == IS_NULL &&
return_null) {
*p = NULL;
Hello Bob,
this is a) wrong in the way you call the cast handler and b) we will
definitively not add this behavior before the next major release aka
HEAD. However it would be better to call the conversion functions
(zend_operators.h) here to have get handler used when no cast handler
is available to avoid inconsistencies with auto conversions in other
places. I guess I know where you're heading, i am not quite sure this
is essantial or even the rigth thing to for PHP yet at least for stuff
like the array functions and objects that overload ArrayAccess it is
more than usefull.
regards
marcus
p.s.: You still haven't shown me any of your extension code :-/
Friday, November 4, 2005, 9:06:27 AM, you wrote:
--- zend_API.c 2005-11-03 20:26:02.000000000 -0800
+++ zend_API.c 2005-11-03 20:26:02.000000000 -0800
@@ -312,8 +312,17 @@
*p = Z_LVAL_PP(arg);
break;
case IS_OBJECT: {
if (Z_OBJ_HANDLER_PP(arg, cast_object)) {
SEPARATE_ZVAL_IF_NOT_REF(arg);
if
(Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_LONG, 0 TSRMLS_CC) == SUCCESS) {
*p = Z_LVAL_PP(arg);
break;
}
}
}
case IS_ARRAY:
case IS_OBJECT: case IS_RESOURCE: default: return "long";
@@ -346,8 +355,17 @@
*p = Z_DVAL_PP(arg);
break;
case IS_OBJECT: {
if (Z_OBJ_HANDLER_PP(arg, cast_object)) {
SEPARATE_ZVAL_IF_NOT_REF(arg);
if
(Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_DOUBLE, 0 TSRMLS_CC) == SUCCESS) {
*p = Z_DVAL_PP(arg);
break;
}
}
}
case IS_ARRAY:
case IS_OBJECT: case IS_RESOURCE: default: return "double";
@@ -408,8 +426,17 @@
*p = Z_BVAL_PP(arg);
break;
case IS_OBJECT: {
if (Z_OBJ_HANDLER_PP(arg, cast_object)) {
SEPARATE_ZVAL_IF_NOT_REF(arg);
if
(Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_BOOL, 0 TSRMLS_CC) == SUCCESS) {
*p = Z_BVAL_PP(arg);
break;
}
}
}
case IS_ARRAY:
case IS_OBJECT: case IS_RESOURCE: default: return "boolean";
@@ -434,6 +461,15 @@
case 'a':
{
zval **p = va_arg(*va, zval **);
if (Z_TYPE_PP(arg) == IS_OBJECT) {
if (Z_OBJ_HANDLER_PP(arg, cast_object)) {
SEPARATE_ZVAL_IF_NOT_REF(arg);
if (Z_OBJ_HANDLER_PP(arg,
cast_object)(*arg, *arg, IS_ARRAY, 0 TSRMLS_CC) == SUCCESS) {
*p = *arg;
break;
}
}
} if (Z_TYPE_PP(arg) != IS_ARRAY) { if (Z_TYPE_PP(arg) == IS_NULL && return_null) { *p = NULL;
Best regards,
Marcus