Forum Moderators: coopster

Message Too Old, No Replies

PHP Multidimensional Array Problems

Creating Multiple Lists & Sub-Lists with Multidimensional Arrays

         

Sherif

3:53 pm on Oct 28, 2010 (gmt 0)

10+ Year Member



Hey Guys,

This is my first time in dealing with complicated arrays especially multidimensional ones.

I found this page which discusses something similar to what i want to do.
[stackoverflow.com ]


I have a database that contains 3 tables.

1 having all of the users
1 having all of the contracts connected to the users through the user id
1 having apartments connected to contracts and users through the relative id as mentioned above.

I want to create a table at the end with something like the following for each user


Contract Number 1
-----Building Number 1
-----------Apartment Number 1
-----------Apartment Number 2

-----Building Number 2
-----------Apartment Number 1
-----------Apartment Number 2


Contract Number 2
-----Building Number 4
-----------Apartment Number 1
-----------Apartment Number 2

-----Building Number 5
-----------Apartment Number 1
-----------Apartment Number 2

etc.....



and so on and so forth depending on the number of contracts, and then the number of the building, and finally the number of the apartment.

It must be noted that the number of contract for each user varies depending on the user itself.


I tried creating the following code for the multidimensional array:-


<?php

$contractlist = array();

foreach($row_apartments as $apartments)
{

if(!in_array($apartments['contract_id'], $contractlist))
{

$contractlist[$apartments['contract_id']] = $apartments['contract_id'];

}


if(!in_array($apartments['contract_id'][$apartments['building_no']], $contractlist))
{

$contractlist[$apartments['contract_id']][$apartments['building_no']] = $apartments['building_no'];

}

$contractlist[$apartments['contract_id']][$apartments['building_no']][$apartments['apartment_no']] = $apartments['apartment_no'];
}


?>


After testing the code, i got the following error:-
Fatal error: Cannot use string offset as an array in dir on line 199


although all of the the values i'm using are numbers.


Can you please help me in developing the correct code for the multidimensional array?


Your help will be much appreciated, and thank you for your cooperation in advance.


Sincerely,
Sherif

enigma1

4:36 pm on Oct 28, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The first problem I believe happens with the in_array. The in_array function checks the arrays values for the input not the keys. But you are setting up the keys for the $contractlist array and that's what you should be checking. It should be:


if( !isset($contractlist[$apartments['contract_id']]) {
$contractlist[$apartments['contract_id']] = $apartments['contract_id'];
}
// etc

Sherif

9:50 pm on Oct 28, 2010 (gmt 0)

10+ Year Member



But the thing that confuses me, is that even if what you are saying is correct, i assign the key the same value,

if(!in_array($apartments['contract_id'], $contractlist))
{

$contractlist[$apartments['contract_id']] = $apartments['contract_id'];

}

so the condition should return true, and have no problems.

Does it have to do with defining the arrays within the primary array, or should it detect that automatically?

Thanks for the support.


Sincerely,
Sherif

enigma1

8:09 am on Oct 29, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You have a foreach loop and multiple in_array checks. So the second one,

if(!in_array($apartments['contract_id'][$apartments['building_no']], $contractlist))

you assume this

$apartments['contract_id']

Is an array, but it isn't. You cannot have an integer and an array at the same time assigned. Use the keys, check with isset.

Sherif

8:57 am on Oct 31, 2010 (gmt 0)

10+ Year Member



Thanks a lot for all of the support of until this moment.

It is true, the
$apartments['contract_id']
Should be an array, and even the
$apartments['building_no']
should be another array in the contract id array.

and as a result, we should end up with a multidimensional array.
$contractlist[$apartments['contract_id']][$apartments['building_no']]


with the building number being an array that carries all of the apartment numbers.

As i said earlier, i am an amateur when it comes to array, so could you please help me with some coding that i can get started with?


Thanks a lot for your support.


Sincerely,
Sherif

enigma1

9:31 am on Oct 31, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Just do few changes to the original code.


$row_apartments = array(
array('contract_id' => 3, 'building_no' => 123, 'apartment_no' => 7),
array('contract_id' => 4, 'building_no' => 124, 'apartment_no' => 2),
array('contract_id' => 5, 'building_no' => 125, 'apartment_no' => 6),
array('contract_id' => 8, 'building_no' => 126, 'apartment_no' => 9),
array('contract_id' => 3, 'building_no' => 126, 'apartment_no' => 1),
array('contract_id' => 3, 'building_no' => 126, 'apartment_no' => 5),
);

$contractlist = array();

foreach($row_apartments as $apartments) {

if( !isset($contractlist[$apartments['contract_id']]) ) {
$contractlist[$apartments['contract_id']] = array();
}

if( !isset($contractlist[$apartments['contract_id']][$apartments['building_no']]) ) {
$contractlist[$apartments['contract_id']][$apartments['building_no']] = array();

}
$contractlist[$apartments['contract_id']][$apartments['building_no']][$apartments['apartment_no']] = array();
}

echo '<pre>';
print_r($contractlist);
echo '</pre>';
exit();


I added a sample array so you can see the output. The various fields are keys not values. Values are arrays because of the hierarchy.

Sherif

9:49 am on Oct 31, 2010 (gmt 0)

10+ Year Member



Thanks enigma1 for the quick reply,

when i do the for each loop, and check the !isset function,

if( !isset($contractlist[$apartments['contract_id']]) ) {
$contractlist[$apartments['contract_id']] = array();
}


here i define that this is an array, but how do i store in it the data relative to it, here as far as what i understood is that we check if the array exists or not, and if not we define an array but not store any data in it. Am i right?

Thanks a lor for all of your support and patience.


Sincerely,
Sherif Malek

enigma1

11:35 am on Oct 31, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



In the code the only place you could add some information is the very last assignment.

$contractlist[$apartments['contract_id']][$apartments['building_no']][$apartments['apartment_no']] = array();

Instead of an array you could store some details for the apartment/resident. In every other place because it is an associative array you use the key as a reference. Besides if you added some information to the parent array elements it could get duplicated. So in effect, the keys hold the information. And the last array child could be used for specifics/details.

Sherif

12:52 pm on Oct 31, 2010 (gmt 0)

10+ Year Member



I think I can grasp the concept now...

but if i want to output the a table with each contract having a row span of the total number of apartments, and each building number having a total row span for the relative apartments similar to what i had mentioned in the first post... how can i output the array in a way so that i know the total number of contracts and the contract numbers, followed by the total number of buildings and their numbers, and finally the same for the apartments?

I know it has something to do with a php pseudo code with a loop, i would be extremely thankful if you were able to help me in this.


Thanks in advance.

Sincerely,
Sherif

enigma1

1:33 pm on Oct 31, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You use the another loop to format and output the keys and its values. So after the first loop the $contractlist holds everything grouped the way you want. Then you parse it.


foreach($contractlist as $contract_id => $building) {
echo '<div><b>Contract-' . $contract_id . '</b></div>';
foreach($building as $building_no => $appartment) {
echo '<div style="padding-left: 20px;">Building-' . $building_no . '</div>';
foreach($appartment as $appartment_no => $details) {
echo '<div style="padding-left: 40px;">Appartment-' . $appartment_no . ': ' . $details . '</div>';
}
}
}

Sherif

1:48 pm on Oct 31, 2010 (gmt 0)

10+ Year Member



Sorry for the stupid question, but what if i want the building number to be the last array that will store the apartment number. Will i in this case use array_push? if so, then when i enter the array, should it be
array_push($contractlist[$apartments['contract_id']][$apartments['building_no']],$apartments['apartment_no']);


I tested the code you place above and i noticed that each apartment number is an array, and as a result, we have a redundant empty array for each apartment.

Can you also please further explain the output pseudo code in a simpler format since i don't get the concept.

Thanks.

Sincerely,
Sherif

enigma1

2:12 pm on Oct 31, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I mentioned earlier about the last array. It can be set to hold details

$contractlist[$apartments['contract_id']][$apartments['building_no']][$apartments['apartment_no']] = $apartments['apartment_no'];

But I don't know what details. It's up to you set it up to another string or format the code so it doesn't display an empty array there.

array_push will only mess the keys and break the code. If you don't want to display a separate line for building/apartment, then comment out the building echo statement and append it with the last echo statement.

echo '<div style="padding-left: 40px;">Building-' . $building_no . ' Appartment-' . $appartment_no . ': ' . $details . '</div>';

In the original code you have building/apartment in separate lines.

There isn't any special formating the echo statement prints the text within the foreach loops

Sherif

2:51 pm on Oct 31, 2010 (gmt 0)

10+ Year Member



I tried the array_push and this was what i got

Array
(
[3] => Array
(
[123] => Array
(
[0] => 7
)

[126] => Array
(
[0] => 1
[1] => 5
)

)

[4] => Array
(
[124] => Array
(
[0] => 2
)

)

[5] => Array
(
[125] => Array
(
[0] => 6
)

)

[8] => Array
(
[126] => Array
(
[0] => 9
)

)

)


which is pretty close to what i want, i don't really care on the index of the apartment number as they are the last item we want to display. But you are right in the case that we would like to display more details related to the apartment.

But how can i retrieve the value of the total number for all apartments in a contract, then the total number of apartments in each building so that we can generate a table with cell merges using rowspan in html to create a fancy looking table [example below].

<table border="1">
<tr><th>Contract No</th>
<th>Building Number</th>
<th>Apartment Number</th>
</tr>
<tr>
<td rowspan="5">123</td>
<td rowspan="3">10</td>
<td>101</td>
</tr>
<tr>
<td>102</td></tr>
<tr><td>103</td></tr>
<tr><td rowspan="2">11</td>
<td>201</td>
</tr>
<tr><td>202</td></tr>
</table>



This is a sample of what i want to output from the array. Ofcourse, the structure of the table would vary based on the information in the contract (number of buildings and apartments associated with each building.)


Please check it out and tell me what you think..


Thanks.

Sincerely,
Sherif

enigma1

5:17 pm on Oct 31, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Once you have the contractlist array populated just put few functions get the info out of it. Here is one that returns the number of apartments for a specific contract


function total_apartments($contract_id, $contractlist) {
$result = 0;
foreach( $contractlist[$contract_id] as $key => $value) {
$result += count($value);
}
return $result;
}


Just pass the contract_id and the contractlist array

echo total_apartments(3, $contractlist);

Sherif

9:27 am on Nov 1, 2010 (gmt 0)

10+ Year Member



Enigma1!

You are a MASTER!

I'll start testing out what you have explained earlier, and see how everything goes.

Seriously, Thanks for all of the support, and your patience.


Sincerely,
Sherif

Sherif

6:58 pm on Nov 1, 2010 (gmt 0)

10+ Year Member



Hey Guys (Enigma1),

Everything is working close to perfect with a very small problem.

I made a MySQL query to obtain specific results which we want to print out the contract information. After the query, i made a mysql_fetch_assoc.

$row_apartments = mysql_fetch_assoc($apartments);


then i made a do while look to input the results in the array that we had created.


$contractlist = array();


do {

if( !isset($contractlist[$row_apartments['contract_id']]) ) {
$contractlist[$apartment['contract_id']] = array();
}

if( !isset($contractlist[$row_apartments['contract_id']][$row_apartments['building_no']]) ) {
$contractlist[$row_apartments['contract_id']][$row_apartments['building_no']] = array();

}
$contractlist[$row_apartments['contract_id']][$row_apartments['building_no']][$row_apartments['apartment_no']] = array();


} while($row_apartments = mysql_fetch_assoc($apartments));


when i output the array, an empty array is generated within the array.

Array
(
[] => Array
(
)

[1] => Array
(
[1] => Array
(
[2] => Array
(
)

)

)

[2] => Array
(
[1] => Array
(
[101] => Array
(
)

[102] => Array
(
)

)

)

)


The code is working perfect except that an empty array is created at the very beginning. The weird thing is that the array doesn't even have a key.... is there any know valid specific reason why this happened?


Thank you for your cooperation guys for helping me reach this step.

The problem with this now is that the output then comes out as:
Contract Number:-
Contract Number:- 1
---Building Number:- 1
------Apartment Number:- 2
Contract Number:- 2
---Building Number:- 1
------Apartment Number:- 101
------Apartment Number:- 102


The first Contract Number:- should not print since nothing exists within it..


Any suggestions?

Thank you for your support.


Sincerely,
Sherif

Sherif

6:59 pm on Nov 1, 2010 (gmt 0)

10+ Year Member



Hey Guys (Enigma1),

Everything is working close to perfect with a very small problem.

I made a MySQL query to obtain specific results which we want to print out the contract information. After the query, i made a mysql_fetch_assoc.

$row_apartments = mysql_fetch_assoc($apartments);


then i made a do while look to input the results in the array that we had created.


$contractlist = array();


do {

if( !isset($contractlist[$row_apartments['contract_id']]) ) {
$contractlist[$apartment['contract_id']] = array();
}

if( !isset($contractlist[$row_apartments['contract_id']][$row_apartments['building_no']]) ) {
$contractlist[$row_apartments['contract_id']][$row_apartments['building_no']] = array();

}
$contractlist[$row_apartments['contract_id']][$row_apartments['building_no']][$row_apartments['apartment_no']] = array();


} while($row_apartments = mysql_fetch_assoc($apartments));


when i output the array, an empty array is generated within the array.

Array
(
[] => Array
(
)

[1] => Array
(
[1] => Array
(
[2] => Array
(
)

)

)

[2] => Array
(
[1] => Array
(
[101] => Array
(
)

[102] => Array
(
)

)

)

)


The code is working perfect except that an empty array is created at the very beginning. The weird thing is that the array doesn't even have a key.... is there any know valid specific reason why this happened?


Thank you for your cooperation guys for helping me reach this step.

The problem with this now is that the output then comes out as:
Contract Number:-
Contract Number:- 1
---Building Number:- 1
------Apartment Number:- 2
Contract Number:- 2
---Building Number:- 1
------Apartment Number:- 101
------Apartment Number:- 102


The first Contract Number:- should not print since nothing exists within it..


Any suggestions?

Thank you for your support.


Sincerely,
Sherif

Sherif

7:31 pm on Nov 1, 2010 (gmt 0)

10+ Year Member



Hey Guys, i found the solution to the problem.... :)


The problem was at the first if statement in the loop...
if( !isset($contractlist[$row_apartments['contract_id']]) ) {
$contractlist[$apartment['contract_id']] = array();
}


the $apartment['contract_id'] should have been $row_apartments['contract_id']

once i fixed that, everything went PERFECT!


Thanks guys...


Sincerely,
Sherif

Sherif

1:05 pm on Nov 4, 2010 (gmt 0)

10+ Year Member



Now I have a really small problem.

As i mentioned earlier, i wanted to generate a table with multiple cell merges.

As a result, i created a counter loop as shown below, to calculate the number of rows required for each component.

<?php

foreach($contractlist as $contract_id => $building){
$total=0;
foreach($building as $building_no => $apartment){
echo 'Total Height Required for ' . $building_no . ' is = ' . $row = count($apartment,1) . "<br/>";
$total += count($apartment,1);
}
echo 'Total height required for contract segment = ' . $total . '<br/><br/>';
}

?>


how can i save these values in their appropriate array?

Example in the $contractlist array(), we have the following :-

Array
(
[3] => Array
(
[123] => Array
(
[7] => Array()
)

[126] => Array
(
[1] => Array()
[5] => Array()
)

)

[4] => Array
(
[124] => Array
(
[2] => Array()
)

)

[5] => Array
(
[125] => Array
(
[6] => Array()
)

)

[8] => Array
(
[126] => Array
(
[9] => Array()
)

)

)


How can i store the row height for each component, so that i can retrieve it when i need it, as a property?

I.e. i want to store a row height for the contract number, and the row height for the building number so that i can use it in the rowspan command in the table syntax.

Example:
I want to have something like $contractlist(
contract1(building1(apartment1, apartment2, buildingproperty), building2, building3, contractproperty),

contract2(building1(apartment1,buildingproperty), contractproperty)... etc....)

Where buildingproperty and contractproperty contains information such as the required rowspan, color, etc....


So the array should end with something like this:-


Array
(
[3] => Array
(
[123] => Array
(
[7] => Array()
[buildingproperty] => Array
(
Height=2, color=2,etc...
)
)
[contractproperty] => Array
(
Height=2, color=2,etc...
)
)

etc...


)

Thanks for your cooperation.

Sincerely,
Sherif

Sherif

8:35 pm on Nov 4, 2010 (gmt 0)

10+ Year Member



HEEEELLLLLPPPP!

I Cannot find a solution to my problem....

Regards what i said earlier, i made a code, but something appears to be wrong.

1) I created a code to count the various components, and placed it in an array as follows:-
foreach($contractlist as $contract_id => $building){
$totalcontractrows=0;
foreach($building as $building_no => $apartment){
$row = count($apartment,1);
$contractlist[$contract_id][$building_no]["property"] = array("height" => $row);

$totalcontractrows += count($apartment,1);
}


$contractlist[$contract_id]["property"] = array("height" => $totalcontractrows);

}



2) The Array structure is now as follows:-
Array
(
[1] => Array
(
[1] => Array
(
[1] => Array
(
)

[2] => Array
(
)

[property] => Array
(
[height] => 2
)

)

[property] => Array
(
[height] => 2
)

)

[2] => Array
(
[2] => Array
(
[101] => Array
(
)

[102] => Array
(
)

[property] => Array
(
[height] => 2
)

)

[property] => Array
(
[height] => 2
)

)

)



3) Then I created the code for the table to perform the cell merges and loops as follows:-

<table border="1">
<tr>
<th>Contract Number</th>
<th>Building Number</th>
<th>Apartment Number(s)</th>
</tr>
<?php

foreach($contractlist as $contract_id => $building){
echo '<tr>' . '<td rowspan="' . $contractlist[$contract_id]["property"]["height"] . '">' . $contract_id . '</td>';

$i=0;

foreach($building as $building_no => $apartment){
if($i == 0){

echo '<td rowspan="' . $contractlist[$contract_id][$building_no]["property"]["height"] . '">' . $building_no. '</td>';

}

elseif($i!=0){
echo '<tr><td rowspan="' . $contractlist[$contract_id][$building_no]["property"]["height"] . '">' . $building_no. '</td>';

}

$i++;

$i2=0;

foreach($apartment as $apartment_detail => $details){

if($i2 == 0){

echo '<td>' . $apartment_detail . '</td></tr>';

}
elseif($i2!=0){

echo '<tr><td>' . $apartment_detail . '</td></tr>';

}
$i2++;
}
}
}

?>
</table>



4) I revised the code 1,000,000 times, and i cannot find where the problem is...

The output comes out as
<table border="1">
<tr>
<th>Contract Number</th>
<th>Building Number</th>
<th>Apartment Number(s)</th>
</tr>
<tr><td rowspan="2">1</td><td rowspan="2">1</td><td>1</td></tr><tr><td>2</td></tr><tr><td>property</td></tr><tr><td rowspan="">property</td><td>height</td></tr><tr><td rowspan="2">2</td><td rowspan="2">2</td><td>101</td></tr><tr><td>102</td></tr><tr><td>property</td></tr><tr><td rowspan="">property</td><td>height</td></tr> </table>


As you can see, the rowspan="", and the property, and height text appears even when i do not call it as i have shown above...


Any ideas?


I really hope that someone here can help me.


Thanks in advance.


Sincerely,
Sherif