Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

In PHP, I know there is no official way to delete items once they have been put into an array. But there must be a "best-method" solution to my problem. I believe this may lie in the array_filter function.

Essentially, I have a shopping cart object that stores items in a hashtable. Imagine you can only ever buy one of any item at a time.

I do

add_item(1);
add_item(2);
remove_item(1);

get_count() still returns 2.

var $items;


function add_item($id) {
	$this->items[$id] = new myitem($id);
}

function remove_item($id) {
	if ($this->items[$id]) {
		$this->items[$id] = false;
		return true;
	} else {	
		return false;
	}
}


function get_count() {
	return count($this->items);
}

What do people think is the best method to use in get_count? I can't figure out the best way to use array_filter that simply doesn't return false values (without writing a seperate callback).

Thanks :)

share|improve this question
    
php.net/unset ? –  SilentGhost Apr 28 '09 at 21:27
add comment

3 Answers

up vote 5 down vote accepted

No official way? Sure there is! Unset!

<?php

class foo
{
    var $items = array();


    function add_item($id) {
            $this->items[$id] = new myitem($id);
    }

    function remove_item($id)
    {
        unset( $this->items[$id] );

    }


    function get_count() {
            return count($this->items);
    }
}

class myitem
{
    function myitem( $id )
    {
    	// nothing
    }
}

$f = new foo();

$f->add_item( 1 );
$f->add_item( 2 );

$f->remove_item( 1 );

echo $f->get_count();

Also, is this PHP4? Because if not, you should look into some of the SPL stuff like ArrayObject or at least the the Countable and ArrayAccess interfaces.

EDIT

Here's a version using the interfaces directly

<?php

class foo implements ArrayAccess, Countable
{
    protected $items = array();

    public function offsetExists( $offset )
    {
    	return isset( $this->items );
    }

    public function offsetGet( $offset )
    {
    	return $this->items[$offset];
    }

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

    public function offsetUnset( $offset )
    {
    	unset( $this->items[$offset] );
    }

    public function count()
    {
    	return count( $this->items );
    }

    public function addItem( $id )
    {
    	$this[$id] = new myitem( $id );
    }
}

class myitem
{
    public function __construct( $id )
    {
    	// nothing
    }
}

$f = new foo();

$f->addItem( 1 );
$f->addItem( 2 );
unset( $f[1] );

echo count( $f );

And here's a version as an implementation of ArrayObject

<?php

class foo extends ArrayObject
{
    public function addItem( $id )
    {
    	$this[$id] = new myitem( $id );
    }
}

class myitem
{
    public function __construct( $id )
    {
    	// nothing
    }
}

$f = new foo();

$f->addItem( 1 );
$f->addItem( 2 );
unset( $f[1] );

echo count( $f );
share|improve this answer
    
Get rid of the isset condition ;) –  Mario Apr 28 '09 at 21:39
    
Oh, I guess it's not needed. I didn't test the code, but I guess it doesn't throw a warning with unset() after all. –  Peter Bailey Apr 28 '09 at 21:44
add comment
if ($this->items[$id]) {

May return a warning, should use array_key_exists or isset.

unset() seems cleaner than assigning false when removing an item (will also get rid of your count problem).

share|improve this answer
add comment

+1 to both Peter's and Mario's answers: using unset() is the correct way to remove items from an array.

I just wanted to leave a note to explain why your method wasn't working. Using count() will count the number of values in an array. false, though you could imagine it as meaning "nothing", is still actually a value. Typically if you want to actually specify "no value" then use null.

You can also unset an array element by setting it to null, though look at the code below to see the difference.

$x = array("a", "b", "c");

var_dump(isset($x[0]));   // bool(true)
var_dump(isset($x[1]));   // bool(true)
var_dump(isset($x[2]));   // bool(true)
echo count($x);           // 3

$x[2] = null;
var_dump(isset($x[2]));   // bool(false) -- the value is not set any longer
echo count($x);           // 3  -- but it doesn't remove it from the array

unset($x[1]);
var_dump(isset($x[1]));   // bool(false)
echo count($x);           // 2
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.