RE: [PHP-DEV] Internal class, read_property() and type == BP_VAR_W
| From: | Dmitry Stogov | Date: | Fri, 28 Oct 2005 15:16:14 +0000 |
| Subject: | RE: [PHP-DEV] Internal class, read_property() and type == BP_VAR_W | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-19784@lists.php.net to get a copy of this message | ||
Hi Michael,
You should define get_property_ptr_ptr() callback to support such
assignments.
Thanks. Dmitry.
> -----Original Message-----
> From: Michael Wallner [mailto:mike@php.net]
> 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
>
>