[PHP] [PHP5] paradox ? Bug ?

2004-09-03 Thread Frédéric Hardy
Hello -
I think there is a bug or a paradox in the php 5 object model 
implementation.

This is an example :
?php
class foo implements arrayAccess
{
   private $array = array();
   function __construct() {}
   function __get($key)
   {
  return $this-offsetGet($key);
   }
   function __set($key, $value)
   {
  $this-offsetSet($key, $value);
   }
   function offsetExists($key)
   {
  return isset($this-array[$key]);
   }
   function offsetGet($key)
   {
  return $this-array[$key];
   }
   function offsetSet($key, $value)
   {
  $this-array[$key] = $value;
   }
   function offsetUnset($key)
   {
  unset($this-array[$key];
   }
}
$foo = new foo();
echo (isset($foo['bar']) == true ? 'set' : 'not set');
$foo['bar'] = 'bar';
echo (isset($foo['bar']) == true ? 'set' : 'not set');
echo $foo['bar'];
#Expected result :
# not set
# set
# bar
#Real result
# not set
# set
# bar
# !! GREAT !!
#Now, the same thing with __get() and __set()
unset($foo);
$foo = new foo();
echo (isset($foo-array) == true ? 'array is set' : 'array is not set');
echo (isset($foo-bar) == true ? 'bar is set' : 'bar is not set');
$foo-bar = 'bar';
echo (isset($foo['bar']) == true ? 'bar is set' : 'bar is not set');
echo $foo-bar;
#Expected result :
# array is set
# bar is not set
# bar is set
# bar
#Real result
# array is set # Ok !
# bar is not set # Ok !
# bar is not set # PROBLEM PROBLEM
# bar
# !! NOT GREAT !!
?
It is very strange.
isset() does not return the good value on property wich was set with 
__set() !!
But isset() return the good value on property wich was set in the class !!
And isset() return the good value on value wich was set with offsetSet() 
method !!
It is a paradox !

I think that isset MUST return the same value in all case.
What do you think of ?
Fred.
Warning : the php code may be wrong (parse error...), i can not validate 
it in php5 currently

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


Re: [PHP] [PHP5] paradox ? Bug ?

2004-09-03 Thread Marek Kilimajer
Frédéric Hardy wrote:
Hello -
I think there is a bug or a paradox in the php 5 object model 
implementation.

This is an example :
?php
class foo implements arrayAccess
{
   private $array = array();
   function __construct() {}
   function __get($key)
   {
  return $this-offsetGet($key);
   }
   function __set($key, $value)
   {
  $this-offsetSet($key, $value);
   }
   function offsetExists($key)
   {
  return isset($this-array[$key]);
   }
   function offsetGet($key)
   {
  return $this-array[$key];
   }
   function offsetSet($key, $value)
   {
  $this-array[$key] = $value;
   }
   function offsetUnset($key)
   {
  unset($this-array[$key];
   }
}
$foo = new foo();
echo (isset($foo['bar']) == true ? 'set' : 'not set');
$foo['bar'] = 'bar';
echo (isset($foo['bar']) == true ? 'set' : 'not set');
echo $foo['bar'];
#Expected result :
# not set
# set
# bar
#Real result
# not set
# set
# bar
# !! GREAT !!
#Now, the same thing with __get() and __set()
unset($foo);
$foo = new foo();
echo (isset($foo-array) == true ? 'array is set' : 'array is not set');
echo (isset($foo-bar) == true ? 'bar is set' : 'bar is not set');
$foo-bar = 'bar';
echo (isset($foo['bar']) == true ? 'bar is set' : 'bar is not set');
echo $foo-bar;
#Expected result :
# array is set
# bar is not set
# bar is set
# bar
#Real result
# array is set # Ok !
# bar is not set # Ok !
# bar is not set # PROBLEM PROBLEM
# bar
# !! NOT GREAT !!
?
It is very strange.
isset() does not return the good value on property wich was set with 
__set() !!
But isset() return the good value on property wich was set in the class !!
And isset() return the good value on value wich was set with offsetSet() 
method !!
It is a paradox !

I think that isset MUST return the same value in all case.
What do you think of ?
Fred.
See recent discusion on this list about this behavior. You can find it 
in the archives if you look for __isset.

Anyways, line
echo (isset($foo-array) == true ? 'array is set' : 'array is not set');
should give you this fatal error:
Fatal error:  Cannot access private property foo::$array in ...
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


Re: [PHP] [PHP5] paradox ? Bug ?

2004-09-03 Thread Frédéric Hardy
Marek Kilimajer wrote:
 See recent discusion on this list about this behavior. You can find 
it in the archives if you look for __isset.

I know, I am the author of this recent discussion.
Current discussion is an extension.

 echo (isset($foo-array) == true ? 'array is set' : 'array is not set');

 should give you this fatal error:

 Fatal error:  Cannot access private property foo::$array in ...

Yes. I am agree with you.
Add a public property in foo class and replace isset($foo-array) by 
your public property.

Fred.
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


Re: [PHP] [PHP5] paradox ? Bug ?

2004-09-03 Thread Marek Kilimajer
Frédéric Hardy wrote:
Marek Kilimajer wrote:
  See recent discusion on this list about this behavior. You can find 
it in the archives if you look for __isset.

I know, I am the author of this recent discussion.
Current discussion is an extension.
isset($foo['bar']) tests for existance of $foo['bar'], however, you 
created $foo-array['bar'] in you __set() method. It's the same as 
before - isset() does not call __get().

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


Re: [PHP] [PHP5] paradox ? Bug ?

2004-09-03 Thread Daniel Schierbeck
I think this basically sums up the problems of the current handling of 
existence-checking in overloaded objects: We have an object that has 
user-defined methods for getting and setting object properties (__get() 
and __set(), respectively). These methods get and set the properties in 
a private array (private: can only be access from within the object 
itself). Example (mostly stolen from php.net):

?php
class Foo
{
// This array holds the properties
private $elem = array();
// This method is automatically called when an
// undefined (or inaccessible, as $array) property is
// called. The name of the called property is the only
// argument.
public function __get ($prop)
{
if (isset($this-elem[$prop])) {
return $this-elem[$prop];
} else {
trigger_error(Oooops, E_USER_WARNING);
}
}
// Same as before, but is called when setting a
// property
public function __set ($prop, $val)
{
$this-elem[$prop] = $val;
}
}
// Instantiate the class
$foo = new Foo();
// Check if $foo-bar ($foo-elem['bar']) is set
if (isset($foo-bar)) {
echo \$bar is set\n;
} else {
echo \$bar is not set\n;
}
// Set $foo-bar to 'foobar'
$foo-bar = 'foobar';
// Print the value of $foo-bar
echo $foo-bar, \n; // foobar

// Check if $foo-bar ($foo-elem['bar']) is set
if (isset($foo-bar)) {
echo \$bar is set\n;
} else {
echo \$bar is not set\n;
}
?
Now, since we access the properties of $foo in a 'virtual' manner - 
meaning $foo-bar doesn't really exist, it's actually $foo-elem['bar'] 
(if it were public, that is) - we can assume that we can check for 
property existance in the same 'virtual' way, right? Wrong. If we could, 
the above would output this:

$bar is not set
foobar
$bar is set
Yet it returns:
$bar is not set
foobar
$bar is not set
If we want to check whether or not $bar exists in $foo, we have to add a 
method to the Foo class:

public function isSet ($prop)
{
if (isset($this-elem[$prop])) {
return TRUE;
} else {
return FALSE;
}
}
Which is rather dumb, considering that the intention of isset() is to 
check whether or not a variable exists!

So far there has been two suggestions as to what can be done:
1. Change isset so that it automatically detects
   overloaded properties
	2. Let the user define a custom __isSet() method, similar to the 	 
one above, that is called each time a property of the class
	   is checked with isset()

Maybe there's some other angles/ideas/suggestions?
--
Daniel Schierbeck
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


Re: [PHP] [PHP5] paradox ? Bug ?

2004-09-03 Thread Curt Zirzow
* Thus wrote Daniel Schierbeck:
 I think this basically sums up the problems of the current handling of 
 existence-checking in overloaded objects: We have an object that has 
 user-defined methods for getting and setting object properties (__get() 
 and __set(), respectively). These methods get and set the properties in 
 a private array (private: can only be access from within the object 
 itself). Example (mostly stolen from php.net):

The issue of isset() on __get and __set, will most likely be fixed
with 5.1.



Curt
-- 
The above comments may offend you. flame at will.

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php