php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #36566 offsetUnset after __get with dynamic params fails.
Submitted: 2006-03-01 08:29 UTC Modified: 2006-03-01 12:04 UTC
From: stochnagara at hotmail dot com Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: 5CVS-2006-03-01 (CVS) OS: win xp
Private report: No CVE-ID: None
 [2006-03-01 08:29 UTC] stochnagara at hotmail dot com
Description:
------------
when property and array overloading is used in a combination with a property and array offset taken from variable,
not from constants, PHP fails with 'cannot access empty property message' which is wrong.

Reproduce code:
---------------
<?
class foo_1 implements ArrayAccess {
	function offsetGet($q){}
	function offsetSet($q,$r){}
	function offsetExists($q){}
	function offsetUnset ($q) {
		echo "unset successful";
	}
}
class foo_2 {
	function __get($q) {
		return new foo_1;
	}
}
$f = new foo2;
$m = 'o';
$p = 5;
unset ($f->$m[$p]);

Expected result:
----------------
unset successful

Actual result:
--------------
Cannot access empty property

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-03-01 08:37 UTC] tony2001@php.net
<?php
$m = 'o';
$p = 5;
var_dump($m[$p]);
?>
What do you expect to get in this case?
NOT empty result? Why?

 [2006-03-01 09:25 UTC] stochnagara at hotmail dot com
I've just simplified that test example to match bug reporting requirements for a short example.
I will extend it a little so you can understand what I mean.
I have a function called objectPool which returns an object of class Pool. Class Pool has a method
__get which return an instance of an ORM class. The ORM class itself binds offsetUnset($id) to
DELETE FROM table WHERE id=$id.
I have a function that gets two parametes - $id and $module. I guarantee that this function receives correct
parameters. I intended to use 'unset (objectPool()->$module[$id]);' so i get the ORM class for the module $module
and delete its record with id $id. Unfortunately, PHP echoes the fatal error about the empty property.
Now my workaround is this:
	$q = objectPool()->$module;
	unset ($q[$id]);
which works perfect. I think that 'unset (objectPool()->$module[$id]);' should also work perfect.

P.S. I've tested offsetExists, offsetSet and offsetUnset are also buggy. offsetSet also raises a fatal error,
offsetExists always returns false and offsetGet returns as if it were 'objectPool()->$module' instead of
'objectPool()->$module[$id]'
 [2006-03-01 09:44 UTC] tony2001@php.net
You didn't answer my question.
And I don't get why did you give the code that is not supposed to work at all.
Provide a real reproduce code.
 [2006-03-01 10:20 UTC] stochnagara at hotmail dot com
Here is a more detailed sample:

http://debian.fmi.uni-sofia.bg/~kapitancho/phpbug2.php
 [2006-03-01 10:26 UTC] stochnagara at hotmail dot com
And about
<?php
$m = 'o';
$p = 5;
var_dump($m[$p]);
?>
What do you expect to get in this case?
NOT empty result? Why?

So it seems that [] has a higher priority than -> in this case. It seems that is rather counterintuitive:(
 [2006-03-01 10:29 UTC] tony2001@php.net
Notice the difference between:
1) unset (objectPool()->{$module}[$id]);
and 
2) unset (objectPool()->{$module[$id]});
No bug here.
 [2006-03-01 12:04 UTC] stochnagara at hotmail dot com
Yes, it seems that it is bogus.
Sorry for wasting your time:(
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun May 19 11:01:37 2024 UTC