Electronics & Programming

develissimo

Open Source electronics development and programming

  • You are not logged in.
  • Root
  • » PHP
  • » [PHP-DEV] Internal class, read_property() and type == BP_VAR_W [RSS Feed]

#1 Oct. 28, 2005 16:06:57

Michael W.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Internal class, read_property() and type == BP_VAR_W


Hi,

I'm facing an issue I don't know how to overcome.

Short story:
I've an object which properties are connected to the internal struct
whith get_property() and write_property() object handlers.

Now if BP_VAR_W is used to access a property with read_prop() the
following works fine:

// $this->body is a string
$this->body{0} = 'X';

... but the following does nothing than producing a memleak:

$body = &$this->body;
$body = 'X';

Also, it seems impossible to connect *values* (longs or string lengths for
instance) through
that interface, because I cannot tell the zval that the value should point
elsewhere...

Any advice very much appreciated :)
Do I have to disallow referenced writing access?

Long story (sorry):

static zval *_http_message_object_read_prop(zval *object, zval *member, int
type TSRMLS_DC)
{
getObjectEx(http_message_object, obj, object);
http_message *msg = obj->message;
zval *return_value;
#ifdef WONKY
ulong h = zend_get_hash_value(Z_STRVAL_P(member), Z_STRLEN_P(member)+1);
#else
zend_property_info *pinfo = zend_get_property_info(obj->zo.ce, member,
1 TSRMLS_CC);

if (!pinfo || ACC_PROP_PUBLIC(pinfo->flags)) {
return zend_get_std_object_handlers()->read_property(object,
member, type TSRMLS_CC);
}
#endif

if (type == BP_VAR_W) {
return_value = &EG(uninitialized_zval);
return_value->refcount = 1;
return_value->is_ref = 1;
} else {
ALLOC_ZVAL(return_value);
return_value->refcount = 0;
return_value->is_ref = 0;
}

#ifdef WONKY
switch (h)
#else
switch (pinfo->h)
#endif
{
case HTTP_MSG_PROPHASH_TYPE:
case HTTP_MSG_CHILD_PROPHASH_TYPE:
RETVAL_LONG(msg->type);
break;

case HTTP_MSG_PROPHASH_HTTP_VERSION:
case HTTP_MSG_CHILD_PROPHASH_HTTP_VERSION:
RETVAL_DOUBLE(msg->http.version);
break;

case HTTP_MSG_PROPHASH_BODY:
case HTTP_MSG_CHILD_PROPHASH_BODY:
phpstr_fix(PHPSTR(msg));
RETVAL_PHPSTR(PHPSTR(msg), 0, !return_value->is_ref);
break;

case HTTP_MSG_PROPHASH_HEADERS:
case HTTP_MSG_CHILD_PROPHASH_HEADERS:
if (return_value->is_ref) {
Z_TYPE_P(return_value) = IS_ARRAY;
Z_ARRVAL_P(return_value) = &msg->hdrs;
} else {
array_init(return_value);
zend_hash_copy(Z_ARRVAL_P(return_value),
&msg->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
}
break;

case HTTP_MSG_PROPHASH_PARENT_MESSAGE:
case HTTP_MSG_CHILD_PROPHASH_PARENT_MESSAGE:
if (msg->parent) {
RETVAL_OBJVAL(obj->parent);
} else {
RETVAL_NULL();
}
break;

case HTTP_MSG_PROPHASH_REQUEST_METHOD:
case HTTP_MSG_CHILD_PROPHASH_REQUEST_METHOD:
if (HTTP_MSG_TYPE(REQUEST, msg) &&
msg->http.info.request.method) {
RETVAL_STRING(msg->http.info.request.method, 1);
} else {
RETVAL_NULL();
}
break;

case HTTP_MSG_PROPHASH_REQUEST_URI:
if (HTTP_MSG_TYPE(REQUEST, msg) &&
msg->http.info.request.URI) {
RETVAL_STRING(msg->http.info.request.URI,
!return_value->is_ref);
} else {
RETVAL_NULL();
}
break;

case HTTP_MSG_PROPHASH_RESPONSE_CODE:
case HTTP_MSG_CHILD_PROPHASH_RESPONSE_CODE:
if (HTTP_MSG_TYPE(RESPONSE, msg)) {
RETVAL_LONG(msg->http.info.response.code);
} else {
RETVAL_NULL();
}
break;

case HTTP_MSG_PROPHASH_RESPONSE_STATUS:
case HTTP_MSG_CHILD_PROPHASH_RESPONSE_STATUS:
if (HTTP_MSG_TYPE(RESPONSE, msg) &&
msg->http.info.response.status) {
RETVAL_STRING(msg->http.info.response.status,
!return_value->is_ref);
} else {
RETVAL_NULL();
}
break;

default:
#ifdef WONKY
return
zend_get_std_object_handlers()->read_property(object, member, type TSRMLS_CC);
#else
RETVAL_NULL();
#endif
break;
}

return return_value;
}

--
Michael - <mike(@)php.net>http://dev.iworks.at/ext-http/http-functions.html.gz--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit:http://www.php.net/unsub.php

Offline

#2 Oct. 28, 2005 16:19:22

Dmitry S.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Internal class, read_property() and type == BP_VAR_W


Hi Michael,

You should define get_property_ptr_ptr() callback to support such
assignments.

Thanks. Dmitry.

> -----Original Message-----
> From: Michael Wallner
> Sent: Friday, October 28, 2005 7:06 PM
> To: intern***@*ists.php.net
> Subject: Internal class, read_property() and type
> == BP_VAR_W
>
>
> Hi,
>
> I'm facing an issue I don't know how to overcome.
>
> Short story:
> I've an object which properties are connected to the internal
> struct whith get_property() and write_property() object handlers.
>
> Now if BP_VAR_W is used to access a property with read_prop()
> the following works fine:
>
> // $this->body is a string
> $this->body{0} = 'X';
>
> ... but the following does nothing than producing a memleak:
>
> $body = &$this->body;
> $body = 'X';
>
> Also, it seems impossible to connect *values* (longs or
> string lengths for instance) through
> that interface, because I cannot tell the zval that the value
> should point elsewhere...
>
> Any advice very much appreciated :)
> Do I have to disallow referenced writing access?
>
> Long story (sorry):
>
> static zval *_http_message_object_read_prop(zval *object,
> zval *member, int type TSRMLS_DC) {
> getObjectEx(http_message_object, obj, object);
> http_message *msg = obj->message;
> zval *return_value;
> #ifdef WONKY
> ulong h = zend_get_hash_value(Z_STRVAL_P(member),
> Z_STRLEN_P(member)+1); #else
> zend_property_info *pinfo =
> zend_get_property_info(obj->zo.ce, member, 1 TSRMLS_CC);
>
> if (!pinfo || ACC_PROP_PUBLIC(pinfo->flags)) {
> return
> zend_get_std_object_handlers()->read_property(object, member,
> type TSRMLS_CC);
> }
> #endif
>
> if (type == BP_VAR_W) {
> return_value = &EG(uninitialized_zval);
> return_value->refcount = 1;
> return_value->is_ref = 1;
> } else {
> ALLOC_ZVAL(return_value);
> return_value->refcount = 0;
> return_value->is_ref = 0;
> }
>
> #ifdef WONKY
> switch (h)
> #else
> switch (pinfo->h)
> #endif
> {
> case HTTP_MSG_PROPHASH_TYPE:
> case HTTP_MSG_CHILD_PROPHASH_TYPE:
> RETVAL_LONG(msg->type);
> break;
>
> case HTTP_MSG_PROPHASH_HTTP_VERSION:
> case HTTP_MSG_CHILD_PROPHASH_HTTP_VERSION:
> RETVAL_DOUBLE(msg->http.version);
> break;
>
> case HTTP_MSG_PROPHASH_BODY:
> case HTTP_MSG_CHILD_PROPHASH_BODY:
> phpstr_fix(PHPSTR(msg));
> RETVAL_PHPSTR(PHPSTR(msg), 0,
> !return_value->is_ref);
> break;
>
> case HTTP_MSG_PROPHASH_HEADERS:
> case HTTP_MSG_CHILD_PROPHASH_HEADERS:
> if (return_value->is_ref) {
> Z_TYPE_P(return_value) = IS_ARRAY;
> Z_ARRVAL_P(return_value) = &msg->hdrs;
> } else {
> array_init(return_value);
>
> zend_hash_copy(Z_ARRVAL_P(return_value), &msg->hdrs,
> (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
> }
> break;
>
> case HTTP_MSG_PROPHASH_PARENT_MESSAGE:
> case HTTP_MSG_CHILD_PROPHASH_PARENT_MESSAGE:
> if (msg->parent) {
> RETVAL_OBJVAL(obj->parent);
> } else {
> RETVAL_NULL();
> }
> break;
>
> case HTTP_MSG_PROPHASH_REQUEST_METHOD:
> case HTTP_MSG_CHILD_PROPHASH_REQUEST_METHOD:
> if (HTTP_MSG_TYPE(REQUEST, msg) &&
> msg->http.info.request.method) {
>
> RETVAL_STRING(msg->http.info.request.method, 1);
> } else {
> RETVAL_NULL();
> }
> break;
>
> case HTTP_MSG_PROPHASH_REQUEST_URI:
> if (HTTP_MSG_TYPE(REQUEST, msg) &&
> msg->http.info.request.URI) {
>
> RETVAL_STRING(msg->http.info.request.URI, !return_value->is_ref);
> } else {
> RETVAL_NULL();
> }
> break;
>
> case HTTP_MSG_PROPHASH_RESPONSE_CODE:
> case HTTP_MSG_CHILD_PROPHASH_RESPONSE_CODE:
> if (HTTP_MSG_TYPE(RESPONSE, msg)) {
>
> RETVAL_LONG(msg->http.info.response.code);
> } else {
> RETVAL_NULL();
> }
> break;
>
> case HTTP_MSG_PROPHASH_RESPONSE_STATUS:
> case HTTP_MSG_CHILD_PROPHASH_RESPONSE_STATUS:
> if (HTTP_MSG_TYPE(RESPONSE, msg) &&
> msg->http.info.response.status) {
>
> RETVAL_STRING(msg->http.info.response.status, !return_value->is_ref);
> } else {
> RETVAL_NULL();
> }
> break;
>
> default:
> #ifdef WONKY
> return
> zend_get_std_object_handlers()->read_property(object, member,
> type TSRMLS_CC); #else
> RETVAL_NULL();
> #endif
> break;
> }
>
> return return_value;
> }
>
> --
> Michael - <mike(@)php.net>
>http://dev.iworks.at/ext-http/http-functions.html.gz>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit:http://www.php.net/unsub.php>
>

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

Offline

#3 Oct. 28, 2005 16:25:30

Michael W.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Internal class, read_property() and type == BP_VAR_W


Hi Dmitry Stogov, you wrote:

> Hi Michael,
>
> You should define get_property_ptr_ptr() callback to support such
> assignments.

Yeah, I looked at that, but what do I gain? get_property_ptr_ptr() will
be used for both described cases and instead of returning a zval* I'd have
to return a zval**, but I could miss the obvious, and if that's the case,
don't hesitate to drop me a quick pointer in the right direction!

Thanks a lot Dmitry,
--
Michael - <mike(@)php.net>http://dev.iworks.at/ext-http/http-functions.html.gz--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit:http://www.php.net/unsub.php

Offline

#4 Oct. 28, 2005 16:56:21

Dmitry S.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Internal class, read_property() and type == BP_VAR_W


read_property(BP_VAR_W) will never work for all cases.
Probably you can return proxy object with get() and set() callbacks, but I
am not sure if it will work for references too.

So if you can return zval** you should use get_property_ptr_ptr().

Dmitry.

> -----Original Message-----
> From: Michael Wallner
> Sent: Friday, October 28, 2005 7:23 PM
> To: intern***@*ists.php.net
> Subject: Re: Internal class, read_property() and
> type == BP_VAR_W
>
>
> Hi Dmitry Stogov, you wrote:
>
> > Hi Michael,
> >
> > You should define get_property_ptr_ptr() callback to support such
> > assignments.
>
> Yeah, I looked at that, but what do I gain?
> get_property_ptr_ptr() will be used for both described cases
> and instead of returning a zval* I'd have
> to return a zval**, but I could miss the obvious, and if
> that's the case,
> don't hesitate to drop me a quick pointer in the right direction!
>
> Thanks a lot Dmitry,
> --
> Michael - <mike(@)php.net>
>http://dev.iworks.at/ext-http/http-functions.html.gz>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit:http://www.php.net/unsub.php>
>

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

Offline

#5 Oct. 28, 2005 18:42:37

Michael W.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Internal class, read_property() and type == BP_VAR_W


Dmitry Stogov wrote:read_property(BP_VAR_W) will never work for all cases.
Probably you can return proxy object with get() and set() callbacks, but I
am not sure if it will work for references too.

So if you can return zval** you should use get_property_ptr_ptr().Hm... maybe I made not a good start with my question, let me ty again, please:

typedef struct {
zend_object zo;
int i;
} my_obj;Would you say it's possible that one can maintain i as classproperty with write access through references?Thank you,
--
Michael - <mike(@)php.net>http://dev.iworks.at/ext-http/http-functions.html.gz--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit:http://www.php.net/unsub.php

Offline

#6 Oct. 28, 2005 21:26:57

Sara G.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Internal class, read_property() and type == BP_VAR_W


> Hm... maybe I made not a good start with my question, let me ty again,
please:
>
> typedef struct {
> zend_object zo;
> int i;
> } my_obj;
>
> Would you say it's possible that one can maintain i as class
> property with write access through references?
>
Nope, because PHP variables are loose typed.

Say you *did* have some way to bind my_obj->i to a userspace variable (e.g.:
$i =& $this->i; ). The next instruction could say $i = 'foo';, then what is
the engine supposed to do with that?

If you want i to have any visibility in userspace, then it needs to be a
zval, and that means it can be modified, and that means that you'll need to
be prepared to re-cast it back to the right type later. Kinda sucks, but it
sucks for a good reason...

-Sara

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

Offline

#7 Oct. 28, 2005 21:41:28

Michael W.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Internal class, read_property() and type == BP_VAR_W


Sara Golemon wrote:Would you say it's possible that one can maintain i as classproperty with write access through references?Nope, because PHP variables are loose typed.

Say you *did* have some way to bind my_obj->i to a userspace variable
(e.g.: $i =& $this->i; ). The next instruction could say $i =
'foo';, then what is the engine supposed to do with that?

If you want i to have any visibility in userspace, then it needs to
be a zval, and that means it can be modified, and that means that
you'll need to be prepared to re-cast it back to the right type
later. Kinda sucks, but it sucks for a good reason...Uhm... you're so right, thanks, that cleared my mind and makes me remember my
first post to the list ;)

Thank you,
--
Michael - <mike(@)php.net>http://dev.iworks.at/ext-http/http-functions.html.gz--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit:http://www.php.net/unsub.php

Offline

#8 Oct. 29, 2005 00:37:01

Marcus B.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Internal class, read_property() and type == BP_VAR_W


Hello Michael,

actually your class could have another object with get/set handlers
implemented, nothing more. This could be mapped through the handlers
to your int i.

marcus

Friday, October 28, 2005, 10:44:42 PM, you wrote:

> Sara Golemon wrote:

>>> Would you say it's possible that one can maintain i as class
>>> property with write access through references?
>>>
>> Nope, because PHP variables are loose typed.
>>
>> Say you *did* have some way to bind my_obj->i to a userspace variable
>> (e.g.: $i =& $this->i; ). The next instruction could say $i =
>> 'foo';, then what is the engine supposed to do with that?
>>
>> If you want i to have any visibility in userspace, then it needs to
>> be a zval, and that means it can be modified, and that means that
>> you'll need to be prepared to re-cast it back to the right type
>> later. Kinda sucks, but it sucks for a good reason...

> Uhm... you're so right, thanks, that cleared my mind and makes me
> remember my first post to the list ;)

> Thank you,
> --
> Michael - <mike(@)php.net>
>http://dev.iworks.at/ext-http/http-functions.html.gzBest regards,
Marcus

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

Offline

  • Root
  • » PHP
  • » [PHP-DEV] Internal class, read_property() and type == BP_VAR_W [RSS Feed]

Board footer

Moderator control

Enjoy the 18th of November
PoweredBy

The Forums are managed by develissimo stuff members, if you find any issues or misplaced content please help us to fix it. Thank you! Tell us via Contact Options
Leave a Message
Welcome to Develissimo Live Support