php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #32983 Bogus error message when using ArrayAccess / References
Submitted: 2005-05-09 12:38 UTC Modified: 2005-08-16 23:30 UTC
Votes:2
Avg. Score:3.5 ± 1.5
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (100.0%)
From: jason at amp-design dot net Assigned: helly (profile)
Status: Closed Package: SPL related
PHP Version: 5.0.3 OS: *
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: jason at amp-design dot net
New email:
PHP Version: OS:

 

 [2005-05-09 12:38 UTC] jason at amp-design dot net
Description:
------------
I'm not 100% sure this is considered a "bug" as such, anyway, I thought I'd point it out, and let you decide. It's more a case of the error message being a little fuzzy.

When trying to assign an item by reference by using the reference operator, &, to an element inside a class that implements ArrayAccess produces a werid error message.

Admittedly, the code I've provided is probably not valid PHP code, because the nature of the ArrayAccess interface means that data is assigned and returned from offsetSet and offsetGet by value, so using refernces should probably not work.

However, the when you do try this, you get an error about about post/pre increment/decrement. I'm not sure what this refers to, but it doesn't seem to be very descriptive.

Reproduce code:
---------------
<?php

class ArrayAccessImpl implements ArrayAccess {
	private $data = array();

	public function offsetUnset($index) {}

	public function offsetSet($index, $value) {
		$this->data[$index] = $value;
	}

	public function offsetGet($index) {
		return $this->data[$index];
	}

	public function offsetExists($index) {
		return isset($this->data[$index]);
	}
}

$data = new ArrayAccessImpl();
$test = 'some data';
$data['element'] = &$test;

?>

Expected result:
----------------
Unsure, probably an error message relating to the fact ArrayAccess objects can not assign by reference

Actual result:
--------------
Fatal error: Objects used as arrays in post/pre increment/decrement must return values by reference

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-05-09 19:05 UTC] helly@php.net
Actually at the moment this is a known issue which we cannot fix appropriate right away. But we are working on the matter.
 [2005-08-16 07:44 UTC] sslotnick at gmail dot com
I have a similar but different reproduction using two dimensional arrays instead of explicitly setting a reference.

class ArrayAccessImpl implements ArrayAccess {
  private $data = array();

  public function offsetUnset($index) {}

  public function offsetSet($index, $value) {
    $this->data[$index] = $value;
  }

  public function offsetGet($index) {
    return $this->data[$index];
  }

  public function offsetExists($index) {
    return isset($this->data[$index]);
  }
}

$data = new ArrayAccessImpl();
$data['element'] = array();
$data['element']['element2'] = "hi";
 [2005-08-16 23:30 UTC] helly@php.net
Thank you for your bug report. This issue has already been fixed
in the latest released version of PHP, which you can download at 
http://www.php.net/downloads.php

We found out that this is not solvable without blowing up the interface and creating a BC or providing an additional interface to support references and thereby creating an internal nightmare - actually i don't see a way we can make that work ever. Thus we decided to enforce the original design and disallow references completley. Also the error message should have changed with 5.0.4 or is being changed with 5.0.5/5.1 at least
 [2011-12-12 12:41 UTC] charles dot louw at gmail dot com
Excuse me if I'm being obtuse here but this doesn't really solve the problem and renders the ArrayAccess interface useless for anything other than 1-dimensional arrays. So you can't do:
$data = new ArrayAccessImpl(); // using class in example above
$data['level_1'] = array();
$data['level_1']['level_2'] = 'some data';

Suggestion:
1. Change the ArrayAccess interface to support references - so as to fix the problem.
2. Reduce the severity of the error triggered for class declarations that don't implement the ArrayAccess methods with references from "fatal" to "warning" (so that the application does not terminate).
3. If I'm not amiss very little will need to be changed in the SPL to then handle data passed to & from the (ArrayAccess) methods whether passed by reference or not. This will "maintain" BC.
4. Once the old implementation of the ArrayAccess methods have been deprecated you can remove the interface check specific to ArrayAccess which will then revert to a fatal.
* The fatal error I'm talking about would be: "Declaration of ArrayAccessImpl::offsetSet() must be compatible with that of ArrayAccess::offsetSet()"... and for the other methods.
* You could do this as a major revision. I would rather know that I need to update the classes that implement ArrayAccess before upgrading to say PHP.v6 rather than have to live with this limitation. Basically I will now not use ArrayAccess again because of this bug.
 [2012-03-25 08:47 UTC] unkn at i dot ua
why not to add new interface RecursiveArrayIterator, and add return by reference 
in it?
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Nov 27 16:01:29 2024 UTC