Re: [SMARTY-DEV] Re: [SMARTY] Re:[SMARTY-DEV]$smarty.session.object doesn't work in 2.5.0
| From: | Monte Ohrt | Date: | Tue, 15 Apr 2003 19:47:03 +0000 |
| Subject: | Re: [SMARTY-DEV] Re: [SMARTY] Re:[SMARTY-DEV]$smarty.session.object doesn't work in 2.5.0 | ||
| References: | 1 2 3 4 5 6 7 | Groups: | php.smarty.dev |
| Request: | Send a blank email to php-smarty-dev+get-1167@lists.php.net to get a copy of this message | ||
The value is not referenced if:
1) the value being assigned is an array
2) the value being assigned is an object
Otherwise you are correct, only a reference counter is incremented.
Monte
On Tue, 2003-04-15 at 14:22, Wom.bat wrote:
> > Right, but Smarty's method of variable assignement always makes a copy
> > regardless of the data type.
> As far as I can see that, Smarty does
>
> $this->_tpl_vars[$tpl_var] = $value;
>
> This creates _definitely_ a reference to $value, as long as $value is not
> altered. Actually, it is not possible to force the copying of a variable.
> Always creating references as long as the assigned variables are not altered
> is a feature which has been introduced with PHP4 in order to avoid
> unnecessary overhead.
> Read http://www.zend.com/zend/art/ref-count.php, especially on
> from
> paragraph "What is variable counting".
>
> You may also look this up in the PHP source, 4.3.1, zend_execute.c, function
> zend_assign_to_variable, lines 413-487 (explanation follows below):
>
> if (PZVAL_IS_REF(variable_ptr)) {
> if (variable_ptr!=value) {
> short refcount=variable_ptr->refcount;
> zval garbage;
> if (type!=IS_TMP_VAR) {
> value->refcount++;
> }
> garbage = *variable_ptr;
> *variable_ptr = *value;
> variable_ptr->refcount = refcount;
> variable_ptr->is_ref = 1;
> if (type!=IS_TMP_VAR) {
> zendi_zval_copy_ctor(*variable_ptr);
> value->refcount--;
> }
> zendi_zval_dtor(garbage);
> }
> } else {
> variable_ptr->refcount--;
> if (variable_ptr->refcount==0) {
> switch (type) {
> case IS_VAR:
> /* break missing intentionally */
> case IS_CONST:
> if (variable_ptr==value) {
> variable_ptr->refcount++;
> } else if (PZVAL_IS_REF(value)) {
> zval tmp;
> tmp = *value;
> zval_copy_ctor(&tmp);
> tmp.refcount=1;
> zendi_zval_dtor(*variable_ptr);
> *variable_ptr = tmp;
> } else {
> value->refcount++;
> zendi_zval_dtor(*variable_ptr);
> safe_free_zval_ptr(variable_ptr);
> *variable_ptr_ptr = value;
> }
> break;
> case IS_TMP_VAR:
> zendi_zval_dtor(*variable_ptr);
> value->refcount=1;
> *variable_ptr = *value;
> break;
> EMPTY_SWITCH_DEFAULT_CASE()
> }
> } else { /* we need to split */
> switch (type) {
> case IS_VAR:
> /* break missing intentionally */
> case IS_CONST:
> if (PZVAL_IS_REF(value) && value->refcount > 0) {
> ALLOC_ZVAL(variable_ptr);
> *variable_ptr_ptr = variable_ptr;
> *variable_ptr = *value;
> zval_copy_ctor(variable_ptr);
> variable_ptr->refcount=1;
> break;
> }
> *variable_ptr_ptr = value;
> value->refcount++;
> break;
> case IS_TMP_VAR:
> ALLOC_ZVAL(*variable_ptr_ptr);
> value->refcount=1;
> **variable_ptr_ptr = *value;
> break;
> EMPTY_SWITCH_DEFAULT_CASE()
> }
> }
> (*variable_ptr_ptr)->is_ref=0;
> }
>
> The first if:
> if the left variable (represented by the pointer variable_ptr) is a
> reference, the value is assigned to the reference.
> Otherwise (here we go, the variable is NOT a reference):
> First, the refcount is decreased, because the variable gets a new value.
> If then the refcount is zero, the allocated memory for variable_ptr is
> reused.
> If the refcount is not zero, we cannot do this, as we would overwrite all
> other variables
> (remember: internally, the variable is still stored as a refernce to the
> value it has been assigned before)
> In this case, it is checked if the value (that shall be assigned to the
> variable) itself is a reference.
> If this is the case, it gets copied to the memory space of the variable
> pointer.
> (NOTE: a TMP_VAR is a literal (i.e. a number, string, NULL or boolean
> written DIRECTLY into the code, like $foo = 5;),
> a CONST is a variable, i.e. sth like $foo = $bar;)
> After that, the memory adress of our variable gets changed to the memory
> adress of the value assigned, and the reference counter is increased :)
> So we have evidence: definitely a reference, even if not explicitely
> assigned as one :)
>
> Well, now I am curious what you're gonna say about that ;)
>
> Regards,
> David
--
Monte Ohrt <monte@ispi.net>