0
    public function filter($index, $value) {
        if($this->tasks) {
            foreach ($this->tasks as $id => $t) {
                if($t->$index != $value) {
                    unset($this->tasks[$id]);
                }
            }
        } else {
            echo "Tasks are empty";
        }
    }

So I am having a problem with the function above searching multidimensional objects. What I mean by that is like these:

$task->form->id
$task->form->type
$task->author->id
$task->fields->[FIELDNAME]->value
$task->form->template->id
$task->id

etc. These are the kinds of fields that need to be accessed. I thought that I could just, in $index, put "form->id" but that didn't work. For my application, I literally can spell it out. I just don't want to have to write a function for each to the last, because some of them (as you can see) only need to be on the first level and some need to be all the way down four objects.

Just tell me what more data you need and I will give it. I know every keystroke intimately so it sometimes means I forget to share something.

If you help, thank you so much.

WHAT I DID


Okay so I got it to work but I did something different.

Within the Form class

public function search($value, $type = NULL) {
    if(is_object($this->fields)) {
        foreach($this->fields as $page) {
            foreach($page as $name=>$field) {
                if($name != "pdata") {
                    if ($type != NULL && $field->type == $type && $field->value == $value || $type == NULL && isset($field->value) && $field->value == $value) {
                        return true;
                    }
                } 
            }
            return false;
        }
    } else {
        //Probably corrupted
        return false;
    }
    return false;
}

Outside of it I can just call this function and delete or add based on whether it returns true or false.

Luke James Emery
  • 489
  • 4
  • 20

2 Answers2

2
function array_searchRecursive( $needle, $haystack, $strict=false, $path=array() )
{
    if( !is_array($haystack) ) {
        return false;
    }

    foreach( $haystack as $key => $val ) {
        if( is_array($val) && $subPath = array_searchRecursive($needle, $val, $strict, $path) ) {
            $path = array_merge($path, array($key), $subPath);
            return $path;
        } elseif( (!$strict && $val == $needle) || ($strict && $val === $needle) ) {
            $path[] = $key;
            return $path;
        }
    }
    return false;
}

OR

I know you don't want to write it all out, but I have to say I love the way this is done in the Symfony framework. In symfony you have an Entity class that defines functions to retrieve each piece of information (variable) from a given object.

One way you could mimic this is to create a base class for tasks that has functions to retrieve each variable you need...such as getTaskId.

Then you could extend this base class with the one you are working with now. This would give you access to the functions you created to parse your object. Retrieving $task->form->template->id could be as simple as calling the getTemplateId function.

I know this would probably take longer than what you were looking for, but I hope it helps.

Shattuck
  • 2,744
  • 4
  • 21
  • 26
  • Also, it seems there are multiple variables inside the $task->form level. In this case, instead of writing a function to retrieve each one you could simply write a function to retrieve the 'form' object as a whole. – Shattuck Nov 18 '11 at 08:22
  • Yeah that seems like it will take a very long time, and time isn't something I have. I was hoping it would look something like one of the plain array recursive searches. I just didn't know how to implement a recursive, do you think that would work or am I totally mistaken. – Luke James Emery Nov 18 '11 at 08:24
  • Oh yeah there are many many many variables that can be searched. It ends up being a fairly large amount of data. – Luke James Emery Nov 18 '11 at 08:25
  • Check this question out. It might help a little http://stackoverflow.com/questions/1019076/how-to-search-by-key-value-in-a-multidimensional-array-in-php – Shattuck Nov 18 '11 at 08:27
  • I like you idea of a recursive search. I just edited my answer with something that might help – Shattuck Nov 18 '11 at 08:29
  • Sorry for being a newb, but I am assuming I used it the exact same way I am using the current one. – Luke James Emery Nov 18 '11 at 08:38
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/5123/discussion-between-luke-james-emery-and-mike) – Luke James Emery Nov 18 '11 at 08:41
  • Okay so I decided to do something else which works better anyways. I am going to amend my top post to show you what I did and you can choose to look at it if you are interested. Thank you for your help though, it helped to take a step back and look at something else and look at it afterwards. – Luke James Emery Nov 19 '11 at 23:21
1

You can use get_object_vars() to process all public variables of an object and proceed recursively to reach all variables named id. Here is a simple template:

class Task {
    public $author, $form, $id;
}
class Author {
    public $id;
}
class Form {
    public $id, $type, $template;
}
class Template {
    public $id;
}

$tasks = Array();

$task = new Task();
$tasks[] = $task;
$task->id = "id1";
$task->author = new Author();
$task->author->id = "id1";
$task->form = new Form();
$task->form->template = new Template();
$task->form->template->id = "id1";

function filter($parent, $object, $id_value) {
    $vars = get_object_vars($object);
    foreach ($vars as $var => $value) {
        if ($var == "id") {
            if ($value == $id_value) {
                echo "$parent -> $var == $value <br />";
            }
        }
        else if (is_object($value) && isset($value)) {
            filter("$parent -> $var", $value, $id_value);
        }
    }
}

foreach ($tasks as $index => $task) {
    filter("Task[$index]", $task, "id1");
}

The output is:

Task[0] -> author -> id == id1 
Task[0] -> form -> template -> id == id1 
Task[0] -> id == id1 
Jiri Kriz
  • 9,192
  • 3
  • 29
  • 36