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: [email protected]
> 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