Multidimensional Array Advice

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
kayers
Forum Newbie
Posts: 14
Joined: Tue Apr 25, 2006 9:38 am

Multidimensional Array Advice

Post by kayers »

Hey all,

I'm working on some code where I'm getting values from a db and comparing them to values I've gotten from a web form. It works correctly, but I don't like the format of my array I'm using because later on, I have to instantiate "custom fields" with the values. The problem is that there are "groups" that may have many "fields", but the "fields" can have one and only one "value". Currently, my array is not grouped that way:

Code: Select all

Array 
( 
	[0] => Array (
	 				[0] => 4 (Edit: Group ID)
	 				[1] => 6 
					[2] => General Facilities 
				 ) 
	[1] => Array (
	 				[0] => 4 (Edit: Group ID)
	 				[1] => 5
	 				[2] => DEC
	 			 ) 
	[2] => Array (
	 				[0] => 5 (Edit: Group ID)
	 				[1] => 7
	 				[2] => test
	 			)
)
I'm trying to figure out a way to either check the next group id and compare it to the current value (through nested for loops) or make an associative array that somehow links the group id and all of its fields and field values.

I'm currently just using a foreach loop to simply loop through all of the values:

Code: Select all

function instantiate_custom_fields($custom_fields)
{
	$field_handler = new cer_CustomFieldGroupHandler();	
	$filename = "test_instantiate.txt";
	$fp = fopen($filename, "a");
		
	foreach($custom_fields as $cf_fields)
	{
		if($cf_fields[0] != "")
		{
			fwrite($fp, "group id: $cf_fields[0]\n");
			fwrite($fp, "field id: $cf_fields[1]\n");
			fwrite($fp, "field value: $cf_fields[2]\n");
					
			//$instance_id = $field_handler->addGroupInstance("T", $this->ticket_id, $val[0]);
			//$field_handler->setFieldInstanceValue($val[1], $instance_id, $val[2]);
		}
	}
		
	fclose($fp);
}
Of course, this loop has no way of knowing that the group ids are the same and so adds a new instance of the group for EACH field. But every time I try a for loop, I get Array[0][1] etc, so I know I'm not reaching the right level.

Does anyone have a suggestion about doing this? I'm going to keep working on it, but I was wondering if anyone here had any ideas. I'd rather modify the instantiate_custom_fields code than my find_custom_fields_in_body, since that logic in more involved in the latter (I've included it at the end of this post, in case you want to look at it - it's kind of long), but I'm open to anything. I've Googled it and looked at the manuals, but nothing I've tried has worked. Sorry to be a bother, but I'm not very good at multidimensional arrays.

Thanks! I really appreciate everyone's help! :)

Code: Select all

function find_custom_field_in_body(&$raw_email)
{	
	$custom_field_values = array();

	$sql = "SELECT g.group_id, g.group_name, f.field_id, f.field_name, f.field_type ".
            "FROM field_group g ".
	    "LEFT JOIN `fields_custom` f ON (f.field_group_id = g.group_id) ".
	    "ORDER BY g.group_name";

	$res = $this->db->query($sql);

	preg_match_all("/\[Group\](.*)/i",$raw_email->body,$groups, PREG_SET_ORDER);
	preg_match_all("/\[Field Name\](.*)/i",$raw_email->body,$field_names, PREG_SET_ORDER);
	preg_match_all("/\[Field Value\](.*)/i",$raw_email->body,$field_values, PREG_SET_ORDER);

	if($this->db->num_rows($res) > 0)
	{
		$counter = 0;

		while($row = $this->db->fetch_row($res))
		{			
			if($row["group_id"] != NULL)
			{				
				foreach($groups as $group_name)
				{
					if(strcmp(rtrim($group_name[1]), stripslashes($row["group_name"])) == 0)
					{
						foreach($field_names as $f_name)
						{
							if(strcmp(rtrim($f_name[1]), stripslashes($row["field_name"])) == 0)
							{
								foreach($field_values as $f_val)
								{
									if(strcmp($row["field_type"], "D") == 0)
									{
										$sql2 = sprintf("SELECT o.field_id, o.option_id, o.option_value ".
	 												"FROM fields_options o ".
													"WHERE o.field_id = %d ".
													"ORDER BY o.option_order, o.option_value ASC",
														$row["field_id"]
											);

										$res2 = $this->db->query($sql2);

										if($this->db->num_rows($res2)) 
										{
											while($row2 = $this->db->fetch_row($res2)) 
											{
												if(strcmp(rtrim($f_val[1]), $row2["option_value"]) == 0)
												{
													$custom_field_values[$counter] = array($row["group_id"], $row["field_id"], $row2["option_value"]);
												}
											}
										}										
									}
									else
									{
										$custom_field_values[$counter] = array($row["group_id"], $row["field_id"], $f_name[1]);
									}
								}
							}
						}
					}
				}

				$counter++;	
			}	
		}
	}

	return $custom_field_values;
}
[/b]
User avatar
infolock
DevNet Resident
Posts: 1708
Joined: Wed Sep 25, 2002 7:47 pm

Post by infolock »

well, one thing i noticed while going through this was there is an error in your sql...

Code: Select all

$sql2 = "SELECT o.field_id, o.option_id, o.option_value FROM fields_options o  WHERE o.field_id = '{$row['field_id']}' ORDER BY o.option_order, o.option_value ASC";

notice the "o" after the fields_options table name in the FROM clause. is this suposed to be AS like this ?

Code: Select all

$sql2 = "SELECT o.field_id, o.option_id, o.option_value FROM fields_options AS o WHERE o.field_id = '{$row['field_id']}' ORDER BY o.option_order, o.option_value ASC";

Next, I'm not exactly what you are wanting to do with your array. All I can tell is you don't like the format it's in, which I have no idea what you would like it to look like? Could you give an example?


Next, I'd try formatting my arrays like this (as they will be a little more descriptive and will help you out later when you have to debug and print out the array like you did above..)

Code: Select all

if(strcmp(rtrim($f_val[1]), $row2["option_value"]) == 0) { 

                          $custom_field_values[] = array('group_id'     => $row["group_id"], 
                                                         'field_id'     => $row["field_id"], 
                                                         'option_value' => $row2["option_value"],
                                                        ); 
                        } 

//....some other stuff you have above this else statement
                  } else { 

                    $custom_field_values[] = array('group_id' => $row["group_id"], 
                                                   'field_id' => $row["field_id"], 
                                                   'f_name'   => $f_name[1],
                                                  ); 

                  }
kayers
Forum Newbie
Posts: 14
Joined: Tue Apr 25, 2006 9:38 am

Post by kayers »

Hmm, well, I didn't write that SQL statement; I found it elsewhere in the code. I'll try it, though. :) Thanks!

I'm trying to store the group id, field id, and field values together, to establish a relationship between them. Then I send it back, and later one, send it to another function in another class, where I parse it and use that data to create instances of these 'custom fields' (which are groups of dropdown list, textareas, etc).

I guess my problem is I can't figure out how to get the foreach loop to check the next group id and compare it to the current one (because I don't want to create a new group each time if the group ids are the same), and I can't get a for loop to work...
User avatar
infolock
DevNet Resident
Posts: 1708
Joined: Wed Sep 25, 2002 7:47 pm

Post by infolock »

you should look up in_array()
kayers
Forum Newbie
Posts: 14
Joined: Tue Apr 25, 2006 9:38 am

Post by kayers »

Yeah, I looked at that, but I don't know the group id value ahead of time... at least, not in that function; the data's all in the array (or am I just not understaning how to use in_array?). I'll play around with it, though. :)
kayers
Forum Newbie
Posts: 14
Joined: Tue Apr 25, 2006 9:38 am

Post by kayers »

Okay, I guess what I'm really wondering is why this

Code: Select all

for($i = 0; $i < count($custom_fields); $i++)
{
	$current = $custom_field[$i];
			
	fwrite($fp, "current_field values:\n");
	fwrite($fp, "group id: $current_field[$i][0]\n");
	fwrite($fp, "field id: $current_field[$i][1]\n");
	fwrite($fp, "field value: $current_field[$i][2]\n\n");

	fwrite($fp, "current values:\n");
	fwrite($fp, "group id: $current[0]\n");
	fwrite($fp, "field id: $current[1]\n");
	fwrite($fp, "field value: $current[2]\n\n");
}
gives me this

Code: Select all

current_field values:
group id: [0]
field id: [1]
field value: [2]

current values:
group id: 
field id: 
field value: 

current_field values:
group id: [0]
field id: [1]
field value: [2]

current values:
group id: 
field id: 
field value: 

current_field values:
group id: [0]
field id: [1]
field value: [2]

current values:
group id: 
field id: 
field value:
User avatar
cj5
Forum Commoner
Posts: 60
Joined: Tue Jan 17, 2006 3:38 pm
Location: Long Island, NY, USA

Post by cj5 »

usort is your friend!
Post Reply