php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #46315 arrayObject count doesn't work correctly a specific instance.
Submitted: 2008-10-16 14:58 UTC Modified: 2008-10-26 01:00 UTC
From: tony dot fraser at gmail dot com Assigned: colder (profile)
Status: No Feedback Package: SPL related
PHP Version: 5.3.0alpha2 OS: MAMP
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: tony dot fraser at gmail dot com
New email:
PHP Version: OS:

 

 [2008-10-16 14:58 UTC] tony dot fraser at gmail dot com
Description:
------------
I have a class that extends ArrayObject. That class is a collection (GenericCollection). Inside this GenericCollection, i have a little wrapper class that wraps around whatever kind of classes I need to store in the collection. 

In that GenericCollection, I have a method that goes into the objects in the array object, searches a a text field in a certain way, is supposed to return another instance of the class with a subset of the collection. (like, all status=active collection objects in another genericcollection)

The problem is with that internal temporary instance of the collection, tempGenericCollection->count doens't work.

Note, in main class of GenericCollection, count works fine, just not in the temporary object that the GenericCollection creates.


Reproduce code:
---------------
The following is working code, but the comment says what doesn't work.
This code comes from within the GenericCollection class.

 $counter=0;
 while ($_iterator->valid()){
	$_tmp = $this->data->offSetGet($_iterator->key());

	$_thisObject =$_tmp->getObject();
	$_thisObjectID = $_tmp->getID();

	if ($_thisObject->getProperty($_field) == $_value){
	  $_returnCollection->addObject($_thisObjectID, $_thisObject);
	  $_counter++;
	 }
	$_iterator->next();
  }
		
  //right here.. $_returnCollection->count() can't be used, always returns zero.
  if ($_counter > 0)  {
  //error_log('returning an object with N items. N=' . $_returnCollection->count());	
  return $_returnCollection;
}

Expected result:
----------------
I expect it to return the number of objects in the array. I have a print method that shows everything, but even though the array is working correctly, it isn't counting


Actual result:
--------------
0

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-10-17 09:03 UTC] colder@php.net
So, $_returnCollection is a GenericCollection which extends ArrayObject, and $_returnCollection->count() doesn't work?

Sounds like an userland mistake, could you please provide the code defining GenericCollection ?
 [2008-10-17 14:18 UTC] tony dot fraser at gmail dot com
No, you would think it was user error. I was certain it was, but when it came down to it, I literally had it down to the $count variable and the ->count() function side by side commenting them back and forth. the ->count variable always returned zero even though the collection was there. Try it yourself, and don't hesitate to email me directly if you want me to zip the entire directory tree for you.

Also, I would have rather had this class be an abstract but I wasn't able to instantiate another instance of itself from within the class itself. That's probably just my own misunderstanding of the language, but it's a notable problem that we had to work around. I have a concrete that just calls parent::construct(), it just wouldn't work from within the class. Some type of circular reference I would imagine.

BTW, it's the kinds of advancements in objects like this that are really pushing forward the acceptance of PHP as a true business language. I was specifically asked if I wanted to take this full blown project out of PHP and push it to Java. I told them no, but they had full funding to do it.

Here are both classes. Note, DBHandle is not used anywhere in anything that you see, so you can just discard it altogether for the purpose of this class.

<?php
class CollectionObject {
	private $id;
	private $object;
	
	function __construct($_id, $_object){
		$this->id = $_id;
		$this->object = $_object;
	}
	function getObject(){
		return $this->object;
	}
	function printObject() {
		print_r($this);
	}
	function getID() {
		return $this->id;
	
	}
}

<?php
require_once 'CollectionObject.php';
require_once 'GenericCollectionInterface.php';

/** 
 * DO NOT EVER TOUCH THIS CLASS. 
 * It's used all over the place and needs to stay exactly the way it is.
 * 
 * This class should be abstract, but it cannot be because we have to use another
 * instance of the class to return subsets of of the collection
 *
 * You should either be extending it, or if extension is not necessary,
 * you should be using the ConcreteCollection extension.
 * 
 * 
*/

class GenericCollection extends ArrayObject implements GenericCollectionInterface {

private $data;  //Will be an object of type array object
				//that holds collectionObjects with two fields
				//the ID(primary key) and the object itself, like
				//a user or some other data object.

	function __construct(){
		$this->data = new ArrayObject();
		//error_log('constructor of GC' . get_class($this->data));
	}
	
	
	function getData() {
		return $this->data;
		
	}
	function count() {
		/*
		 * This is here because of a bug in the datatype. Yes, it's
		 * already a function of the ArrayObject, but please leave this
		 * here perhaps until a few versions of PHP later.
		 */ 
		
		return $this->data->count();
		
	}
	
	/** Add an object of type Collection Object */
	function addObject($_id, $_object){
		//error_log('attempting to add object');
		$_thisItem = new CollectionObject($_id, $_object);
		//print_r($this->data);
		$this->data->offSetSet($_id, $_thisItem);
	}
	function deleteObject($_id){
		$this->data->offsetUnset($_id);
	}
	function objectExists($_id){
		//error_log('GC object exists');
		//error_log('id' . $_id);
		if ($this->data->offsetExists($_id)){
			$_return="true";
		}
		else $_return = "";
		return $_return;
	}
	
	function getObject($_id,$_dbHandle) {
		$_thisObject = $this->data->offSetGet($_id);
		if (isset($_thisObject)) 
			return $_thisObject->getObject(); 
		else 
			return null;
	}
	
	function printCollection() {
		print_r($this->data);
	}
	

	function getObjectType($_id, $_dbHandle) {
		$_thisObject = getObject($_id, $_dbHandle);
		if (isset($_thisObject)) 
			return $_thisObject->getObject(); 
		else 
			return null;			
	}

	function returnObjectsByProperty($_field, $_value){
		//error_log('in here');
		$_returnCollection = new GenericCollection();
		$_iterator = $this->data->getIterator();
		$_counter = 0;  //For some reason, $_returnCollection->count doesn't work here.
		
		while ($_iterator->valid()){
			//error_log($_iterator->key() . " IS KEY <BR>");
			//error_log(get_class($_iterator->current()));
			
			$_tmp = $this->data->offSetGet($_iterator->key());

			$_thisObject =$_tmp->getObject();
			$_thisObjectID = $_tmp->getID();
			//print_r($_thisObject);
			if ($_thisObject->getDataType($_field) == $_value){
				//error_log("MATCH! -> $_field=$_value");
				$_returnCollection->addObject($_thisObjectID, $_thisObject);
				//error_log("Object Exists ? " . $_returnCollection->objectExists($_thisObjectID));
				//error_log($_returnCollection->count());
				$_counter++;
			}
			//error_log($_thisObject->getProperty('status'));
			//error_log(get_class($_thisObject));
			$_iterator->next();
		}
		
		//error_log ("count is:" . $_returnCollection->count());
		
		if ($_counter > 0)  {
			//error_log('returning an object with N items. N=' . $_returnCollection->count());	
			return $_returnCollection;
		}
		else {
			//error_log ("returning nothing");
			return "";
		}
	}
}
?>
 [2008-10-18 15:04 UTC] colder@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.

Can't reproduce here. Could you please reduce your script to a minimal but complete reproduce script, demonstrating your issue.
 [2008-10-26 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 04:01:38 2024 UTC