Hi Marcus,

OK, I got my learning cap on, why is it the wrong way to call cast_object? I
just copied it from the example for a string param and it worked so I am
curious why it is wrong. I agree the convert_to_* functions are a better
solution for the reasons you mentioned, again, I just followed the example
for the string case.

I guess I don't see what this modification has to do with the future of PHP
though. Why restrict the parameter API to objects that can only convert to a
string value? I'd say the current behavior is almost worthy of a bug.


Imagine we have a class that represents a String and supports the
cast_object handler for all base types. We'll name it ZString.

The following code works fine: (Ignore the fact that I should be using an
integer, not a string equivalent)

$str = new ZString('PHP Object Wrappers');
$start = new ZString('4');
$length = new ZString('6');

echo substr($str, $start, $length);

Result: Object

however, this will fail:

echo wordwrap($str, $length);

Result: Warning: wordwrap() expects parameter 2 to be long

The only difference is the method it uses to get its parameters.

substr() uses zend_get_parameters_ex and wordwrap() uses
zend_parse_parameters

I can work around this restriction by pulling in my parameters as zvals and
doing my own conversion, but IMHO, the engine really should handle it using
the built-in capabilities that already exist and aren't being used.

In regards to the extension, I have the base objects complete: ZArray,
ZChar, ZBoolean, ZDouble, ZInt, ZString. They all work interchangeably (for
the most part) with their PHP native counterparts as long as you aren't
using them on the left side of an expression.

$a = new ZString('PHP ');
$b = new ZString('Object ');
$c = new ZString('Wrappers');

echo $a.$b.$c; (no reliance on __toString, so concatenation is possible)
PHP Object Wrappers 

$int = new ZInt(5);
echo $int + 5;
10

They make extended use of the ArrayAccess interface to implement properties
and indexers.

$a = new ZString('PHP');
echo $a['Length']; 3
echo $a[0]; P
echo $a['Chars']{1}; H
echo $a->offsetGet(2); P

Properties are also supported for derived user classes by defining
accessors.

class MyClass extends ZObject
{
        function setMyProp($value)
        {
                if ($value is valid)
                        $this->_props['MyProp'] = $value;
        }
        function getMyProp()
        {
                return $this->_props['MyProp'];
        }

}

$e = new MyClass;
$e['MyProp'] = 'PHP Object Wrappers';
echo $e['MyProp'];


Where appropriate, they implement Iterator or IteratorAggregate with C# type
wrappers.
foreach ($a as $c)
        echo $c;

PHP

$enum = $a->GetEnumerator();
while ($enum->MoveNext())
        echo $enum->GetCurrent();

PHP


Its also completely exception based, no PHP errors surface during runtime.
As you can tell, I am using C# as my model for the objects. They actually
flow pretty well in a real application as well. One last addition that would
be cool but likely to never happen in the PHP distro is the following:

$a = "some string";
$a->Substring(5,1);

$b = 5;
$b->Equals(3); (false)
$b++;
$b->Equals(6); (true)
echo gettype($b); "object"

Implicit conversion via cast handlers.


I still have a couple weeks of work left on them. This is my first dabble in
C so I have a lot of cleanup to do as well as learn how to turn it into a
PECL extension.

Why program if you can't have fun doing it?

Bob



> -----Original Message-----
> From: Marcus Boerger [mailto:[EMAIL PROTECTED]
> Sent: Friday, November 04, 2005 12:29 AM
> To: Bob Silva
> Cc: internals@lists.php.net
> Subject: Re: [PHP-DEV] [PATCH] - Standardize argument parsing of objects
> 
> 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

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to