# 

- Thread: https://externals.io/message/19904
- Original archive: https://news-web.php.net/php.internals/19904
- Started by Thies C. Arntzen on 2005-11-04T08:35:08+00:00
- Messages: 5
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #19904 — Thies C. Arntzen — 2005-11-04T08:35:08+00:00

URL: https://externals.io/message/19904#19904

hey,

in zend_object_handlers.c function zend_std_read_property we protect  
against calling the __get function of an object if we're already in a  
__get() function. (look for zobj->in_get) in that function.

i don't think we should be doing this.

simplyfied example:
<?php
class test {
     function __get($offset) {
         echo "__get($offset)\n";
         switch ($offset) {
             case 'name': return "name";
             case 'length': return strlen($this->name);
         }
     }
}

$a = new test;
var_dump($a->length);
?>

outputs:
__get(length)
int(0)

but should say:
__get(length)
__get(name)
int(4)

i think recursive gets are highly useful and should be allowed. if we  
really want to protect against recursion (here) we have two real  
options: -a- protect against __get(ing) the same property more than  
once in the same call-chain (mucho work), or -b- (preferred) have  
some global infinite recursion protection in the engine (needs to be  
done somewhen anyhow, but not now).

so, in one sentence: as we don't protect against recustion elsewhere,  
can we please remove this unneded roadblock?

opinions?
-thies

---

## #19937 — Andi Gutmans — 2005-11-09T22:15:08+00:00

URL: https://externals.io/message/19904#19937 · In reply to: #19904

This is intentional and I think it makes it much more fool-proof for 
developers. Adding recursion protection can be very expensive and 
complicated, and it doesn't seem to make sense here. The idea is that 
once you're in the __get() method, you know exactly how your 
properties are mapped and can do the right thing. It's only this one 
method where you have your mapping anyway, not an entirely different place.

Andi

At 12:35 AM 11/4/2005, Thies C. Arntzen wrote:
>hey,
>
>in zend_object_handlers.c function zend_std_read_property we protect
>against calling the __get function of an object if we're already in a
>__get() function. (look for zobj->in_get) in that function.
>
>i don't think we should be doing this.
>
>simplyfied example:
><?php
>class test {
>     function __get($offset) {
>         echo "__get($offset)\n";
>         switch ($offset) {
>             case 'name': return "name";
>             case 'length': return strlen($this->name);
>         }
>     }
>}
>
>$a = new test;
>var_dump($a->length);
>?>
>
>outputs:
>__get(length)
>int(0)
>
>but should say:
>__get(length)
>__get(name)
>int(4)
>
>i think recursive gets are highly useful and should be allowed. if we
>really want to protect against recursion (here) we have two real
>options: -a- protect against __get(ing) the same property more than
>once in the same call-chain (mucho work), or -b- (preferred) have
>some global infinite recursion protection in the engine (needs to be
>done somewhen anyhow, but not now).
>
>so, in one sentence: as we don't protect against recustion elsewhere,
>can we please remove this unneded roadblock?
>
>opinions?
>-thies

---

## #19938 — Andi Gutmans — 2005-11-09T23:06:55+00:00

URL: https://externals.io/message/19904#19938 · In reply to: #19937

Thies,

I think I might be wrong in my analysis. Seems like the problem is 
worse than what I thought as it seems to cross boundaries between classes.
We'll look into it more.

Andi

At 02:15 PM 11/9/2005, Andi Gutmans wrote:
>This is intentional and I think it makes it much more fool-proof for 
>developers. Adding recursion protection can be very expensive and 
>complicated, and it doesn't seem to make sense here. The idea is 
>that once you're in the __get() method, you know exactly how your 
>properties are mapped and can do the right thing. It's only this one 
>method where you have your mapping anyway, not an entirely different place.
>
>Andi
>
>At 12:35 AM 11/4/2005, Thies C. Arntzen wrote:
> > […]

---

## #19939 — Mike Naberezny — 2005-11-10T00:35:56+00:00

URL: https://externals.io/message/19904#19939 · In reply to: #19938

The problem does not cross class boundaries.  However, here are some 
test cases to better illustrate the question:

<?php
class Test {
     function __get($offset) {
         switch($offset) {
             case 'hello1':
                 return 'there';
             case 'hello2':
                 return $this->hello1;
             case 'hello3':
                 return $this->__get('hello1');
             case 'hello4':
                 return $this->testFunction();
         }
     }

     function testFunction() {
         return $this->hello1;
     }
}


$t = new Test();

// CASE 1: Code from outside class scope gets an undefined property
//         which is proxied by __get().  This is the everyday usage.
// string(5) "there"
var_dump($t->hello1);

// CASE 2: Code inside __get() gets an undefined property,
//         which generates a notice instead of being proxied by __get().
// `NULL` 
var_dump($t->hello2);

// CASE 3: Code inside __get() calls __get()
// string(5) "there"
var_dump($t->hello3);

// CASE 4: Code inside __get gets an undefined property through a
//         function, which generates a notice just like Case 2.
// `NULL` 
var_dump($t->hello4);

// CASE 5: Code from inside a class function gets an undefined
//         property which is proxied by __get()
// string(5) "there"
var_dump($t->testFunction());
?>

I agree with Thies that this should be changed, on the basis that the 
behavior is inconsistent and we don't protect against recursion 
otherwise.  Every test case should return the string.

The above examples were tested against 5.0.5 and the latest 5.1 with the 
same results.

Mike


Andi Gutmans wrote:
> Thies,
> 
> I think I might be wrong in my analysis. Seems like the problem is worse 
> than what I thought as it seems to cross boundaries between classes.
> We'll look into it more.
> 
> Andi
> 
> At 02:15 PM 11/9/2005, Andi Gutmans wrote:
> 
> > […]
> 
> 

-- 
Mike Naberezny
Senior PHP Developer

Zend Technologies, The PHP Company
19200 Stevens Creek Blvd, Suite 100
Cupertino, CA 95014
Tel: 408-342-8891
Fax: 408-253-8801
mike.n@zend.com

---

## #19943 — Marcus Boerger — 2005-11-10T08:00:33+00:00

URL: https://externals.io/message/19904#19943 · In reply to: #19939

Hello Mike, Thies,

  i can only agree here, we just invented another inconsistency to violate
the beloved KISS approach once more for no particular reason. And this also
contradicts the arguments we use elsewhere.

marcus

Thursday, November 10, 2005, 1:35:56 AM, you wrote:

> The problem does not cross class boundaries.  However, here are some 
> test cases to better illustrate the question:

> <?php
> class Test {
>      function __get($offset) {
>          switch($offset) {
>              case 'hello1':
>                  return 'there';
>              case 'hello2':
>                  return $this->hello1;
>              case 'hello3':
>                  return $this->__get('hello1');
>              case 'hello4':
>                  return $this->testFunction();
>          }
>      }

>      function testFunction() {
>          return $this->hello1;
>      }
> }


> $t = new Test();

> // CASE 1: Code from outside class scope gets an undefined property
> //         which is proxied by __get().  This is the everyday usage.
> // string(5) "there"
> var_dump($t->hello1);

> // CASE 2: Code inside __get() gets an undefined property,
> //         which generates a notice instead of being proxied by __get().
> // `NULL` 
> var_dump($t->hello2);

> // CASE 3: Code inside __get() calls __get()
> // string(5) "there"
> var_dump($t->hello3);

> // CASE 4: Code inside __get gets an undefined property through a
> //         function, which generates a notice just like Case 2.
> // `NULL` 
> var_dump($t->hello4);

> // CASE 5: Code from inside a class function gets an undefined
> //         property which is proxied by __get()
> // string(5) "there"
> var_dump($t->testFunction());
?>>

> I agree with Thies that this should be changed, on the basis that the 
> behavior is inconsistent and we don't protect against recursion 
> otherwise.  Every test case should return the string.

> The above examples were tested against 5.0.5 and the latest 5.1 with the 
> same results.

> Mike


> Andi Gutmans wrote:
> > […]

> -- 
> Mike Naberezny
> Senior PHP Developer

> Zend Technologies, The PHP Company
> 19200 Stevens Creek Blvd, Suite 100
> Cupertino, CA 95014
> Tel: 408-342-8891
> Fax: 408-253-8801
> mike.n@zend.com




Best regards,
 Marcus
