Hi Michael,

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

Thanks. Dmitry.

> -----Original Message-----
> From: Michael Wallner [mailto:[EMAIL PROTECTED] 
> Sent: Friday, October 28, 2005 7:06 PM
> To: internals@lists.php.net
> Subject: [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
> 
> 

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

Reply via email to