ID:               35104
 Updated by:       [EMAIL PROTECTED]
 Reported By:      php at tjworld dot net
-Status:           Open
+Status:           Assigned
 Bug Type:         Class/Object related
 Operating System: Windows 2003
 PHP Version:      5.1.0RC5
-Assigned To:      
+Assigned To:      dmitry
 New Comment:

Dmitry, any insight on this?



Previous Comments:
------------------------------------------------------------------------

[2005-11-04 13:27:28] php at tjworld dot net

Further test using DOMDocument/DOMElement...

C:\PHP\5.1.0RC5-dev>php.exe dom.php

Fatal error: extDOMElement::__construct(): Cannot write property in
C:\dom.php on line 14

----------dom.php-------------
<?php
class extDOMDocument extends DOMDocument {
 public function createElement($name, $value=null) {
  $ret = new extDOMElement($name, $value, $this); // create the new
element with this Document as owner
  return $ret;
 }
}

class extDOMElement extends DOMElement {
 function __construct($name, $value='', $owner=null,
$namespaceURI=null) {
  if(!$owner instanceof extDOMDocument)
   throw new DOMException(DOM_NOT_FOUND_ERR); // illegal owner
  parent::__construct($name, $value, $namespaceURI);
  $this->ownerDocument = $owner; //** this line causes a Fatal Error
 }
  //  ... more class definition here
}

$doc = new extDOMDocument('test');
$el = $doc->createElement('tagname');
?>

------------------------------------------------------------------------

[2005-11-04 13:02:41] php at tjworld dot net

C:\PHP\5.1.0RC5-dev>php.exe test.php
testing...
Fatal error: Uncaught exception 'Exception' with message 'Can't
overwrite test' in C:\test.php:12
Stack trace:
#0 C:\test.php(23): ReadOnly::__set('test', 'write to me')
#1 C:\test.php(30): Writeable->__construct('write to me')
#2 {main}
  thrown in C:\test.php on line 12


---------------test.php--------------
<?php
class ReadOnly {
 protected $realProperty;
 private $dynamicProperty = array();
 function __construct() {
  $realProperty = 12;
  $this->dynamicProperty['test'] = 'read-only';
 }
 public function __set($name, $value) {
  if($name=='test') {
   if(isset($this->dynamicProperty[$name]))
    throw new Exception("Can't overwrite $name");

   $dynamicProperty[$name] = $value;
  }
 }
 public function __get($name) { return $this->dynamicProperty[$name];
}
}
class Writeable extends ReadOnly {
 function __construct($value) {
  parent::__construct();
  $this->realProperty = 25; // ok
  $this->test = $value; // causes Fatal Error
 }
 public function getReal() {return $this->realProperty; }
 public function getDynamic() {return $this->test; }
}

echo "testing...\r\n";
$test = new Writeable('write to me');
echo 'real: '.$test->getReal()."\r\n";
echo 'dynamic: '.$test->getDynamic()."\r\n";
?>

------------------------------------------------------------------------

[2005-11-04 12:38:17] [EMAIL PROTECTED]

Please try using this CVS snapshot:

  http://snaps.php.net/php5-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5-win32-latest.zip



------------------------------------------------------------------------

[2005-11-04 11:49:33] php at tjworld dot net

Description:
------------
When extending a class that has a visible (public or protected)
read-only dynamic property by virtue of __set(), the sub-class is
prevented from modifying (or "overloading") the property as if it were
merely a public consumer of an instance-object of super, rather than an
extension of the class definition itself.

This shows up in particular in the DOM classes DOMNode and DOMDocument,
where it causes:

Fatal error: extDOMElement::__construct() [function.--construct]:
Cannot write property in...

If you extend both classes, and try to create a new derived extDOMNode
object using a custom  extDOMDocument->createElement(), it is
impossible to set any of the new extDOMNode's dynamic properties from
within extDOMNode's constructor (especially ownerDocument) because
DOMNodes without an owner are forced to be read-only.

The extDOMNode class definition should be able to modify the publically
visible ownerDocument property.

Since real properties accessible from a sub-class can't be private (if
they're to be accessible from other objects), it follows that the same
rule should apply to dynamic properties. If this were so the dynamic
properties made visible by __set() would be inherited as protected or
public  and this issue wouldn't arise.

Reproduce code:
---------------
class ReadOnly {
 protected $realProperty;
 private $dynamicProperty = array();
 function __construct() {
  $realProperty = 12;
  $this->members['test'] = 'read-only';
 }
 public function __set($name, $value) {
  if($name=='test') {
   if(isset($this->dynamicProperty[$name]))
    throw new Exception("Can't overwrite $name");  

   $props[$name] = $value;
  }
 }
}
class Writeable extends ReadOnly {
 function __construct($value) {
  parent::__construct();
  $this->realProperty = 25; // ok
  $this->test = $value; // causes Fatal Error
 }
}

$test = new Writeable('write to me');

Expected result:
----------------
The extended class should be able to inherit and modify protected or
public properties of the super class.

Actual result:
--------------
For built-in classes causes a Fatal Error. For user defined classes
causes a user-defined read-only result. In the example causes an
Exception.


------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=35104&edit=1

Reply via email to