Jump to content

json encode a multidimensional array


jimfog

Recommended Posts

This topic is related to this one http://w3schools.invisionzone.com/index.php?showtopic=51266&hl=

 

I need to json_encode a multidimensional array....this is an example array-var_dump:

array(7) { ["name"]=> string(7) "Kostas " ["apID"]=> string(2) "16" ["start"]=> string(19) "2014-08-27 12:30:00" ["end"]=> string(19) "2014-08-27 15:00:00" ["staffID"]=> string(1) "5" ["origin"]=> string(7) "backend" ["service"]=> array(2) { [0]=> string(1) "1" [1]=> string(1) "2" }}

As you see....the above is a multidimensional array.

The function that creates the above is this:

function get_appointments($connection,$email)//να μάθω για το μηνυμα που σχετίζεται με το κιτρινο τριγωνακι  {        $connection->set_charset("utf8");        $result=$connection->query('select appointments.name,appointments.apID,staffID,appointments.app        s_origin,FROM_UNIXTIME( startDate ) as startDate ,FROM_UNIXTIME( endDate ) as endDate             from appointments,users            where users.email="'.$email.'"            and appointments.bookedfor=users.user_ID');                 if(!$result)        {printf("Errormessage for result: %sn", $connection->error);         return false;}         elseif($result->num_rows>0)                  {   while ($appdetails = $result->fetch_object()){          $appdata=['name'=>$appdetails->name,'apID'=>$appdetails->apID,          'start'=>$appdetails->startDate,'end'=>$appdetails->endDate,'staffID'=>$appdetails->staffID                  ,'origin'=>$appdetails->apps_origin];           }               }          $result1 = $connection->query('select serviceID from services_list,appoint_servi_chosen               where services_list.serviceID=appoint_servi_chosen.service_ID               and appoint_servi_chosen.app_ID="'. $appdata['apID'].'"');        if(!$result1)        {printf("Errormessage for result1: %sn", $connection->error);         return false;        }         elseif($result1->num_rows>0)        {          while($service = $result1->fetch_object())           {            $appdata['service'][] = $service->serviceID;           }}           return  $appdata;              }

So,in the first query,data are loaded in the $appdata array,with each key of the array being another array which corresponds to a different database row-let us forget for now the second query(with $service related info being passed to the $appdata array)

 

I can access the $appdata array with this for loop:

    for($i=0;$i < count($appdata);++$i)            {            $event[$i] = array('id'=>$appdata[$i]["apID"],                 'title' => $appdata[$i]["name"],                 'staff_ID'=>$appdata[$i]['staffID'],                 'start' =>$appdata[$i]['start'],                 'end'=>$appdata[$i]['end'],                 'color'=>$backend,'allDay'=>false);//$backend and allday are not contained in the                   array...do not be confused with these two            }            echo json_encode($event);

The problem arises when we add to the array the service(the result off the second query....it is what you see in the beginning of the topic )...how am I going to access the service key and its data?

 

 

So,in essence(and tell me if I am wrong) we are dealing here with a 3-dimensional array(after service has been added).

 

Thanks and sorry for the length of the topic.

Link to comment
Share on other sites

Would this be suitable?

 

 

$event[$i] = array('id'=>$appdata[$i]["apID"],'title' => $appdata[$i]["name"],'staff_ID'=>$appdata[$i]['staffID'],'start' =>$appdata[$i]['start'],'end'=>$appdata[$i]['end'],'color'=>$backend,'allDay'=>false,'services' => $appdata[$i]['service']); // <------
Link to comment
Share on other sites

No,it will not do it.I get a bunch of undefined offset errors.

I could isolate the services with this but it must be added somehow to the JSON related to the $event array:

 for($k=0;$k<count($appdata['service']);++$k)   {        $service[$k]=array($appdata['service'][$k]);    }    echo json_encode($service);

The above works but the downside is that I am sending a separate JSON stream while it needs to be a single one.

 

I do not if a for loop within a for loop will do the job.

Link to comment
Share on other sites

here is the result of print_r

Array( [name] => Kostas [apID] => 16 [start] => 2014-08-27 12:30:00 [end] => 2014-08-27 15:00:00 [staffID] => 5 [origin] => backend [service] => Array ( [0] => 1 [1] => 2 ))
Link to comment
Share on other sites

Well inside the get_appointments() function I can understand $appdata being a 1 dimensional array and (2 dimensional array for services key), but outside that function isn't $appdata supposed to be 2 dimensional (and 3 dimensional for services key)?

Because you have $appdata[$i]["apID"] instead of $appdata["apID"].

 

Outside the get_appointments() function, shouldn't the $appdata array look like this:

 

Array( [0] => Array( [name] => Kostas [apID] => 16 [start] => 2014-08-27 12:30:00 [end] => 2014-08-27 15:00:00 [staffID] => 5 [origin] => backend [service] => Array ( [0] => 1 [1] => 2 )))
Link to comment
Share on other sites

I do not understand what are you trying to say.

Outside the function $appdata DOES look like your example-here is the result of var_dump:

array(7) { ["name"]=> string(7) "Kostas " ["apID"]=> string(2) "16" ["start"]=> string(19) "2014-08-27 12:30:00" ["end"]=> string(19) "2014-08-27 15:00:00" ["staffID"]=> string(1) "5" ["origin"]=> string(7) "backend" ["service"]=> array(2) { [0]=> string(1) "1" [1]=> string(1) "2" }}
Link to comment
Share on other sites

Your var_dump is a 2 dimensional array, my example is a 3 dimensional array.

 

But if you are using a 2 dimensional array, this should work:

 

 

 $event[$i] = array('id'=>$appdata["apID"],'title' => $appdata["name"],'staff_ID'=>$appdata['staffID'],'start' =>$appdata['start'],'end'=>$appdata['end'],'color'=>$backend,'allDay'=>false,'services' => $appdata['service']);
Link to comment
Share on other sites

why are you json_encoding before you are done creating the final data output?

I think the for loop does exactly that...unless you mean something else.

Link to comment
Share on other sites

 

Your var_dump is a 2 dimensional array, my example is a 3 dimensional array.

 

But if you are using a 2 dimensional array, this should work:

 $event[$i] = array('id'=>$appdata["apID"],'title' => $appdata["name"],'staff_ID'=>$appdata['staffID'],'start' =>$appdata['start'],'end'=>$appdata['end'],'color'=>$backend,'allDay'=>false,'services' => $appdata['service']);

Yes var_dump produces a 2 dimensional array and the way the for loop is now the offset error is justified.

Nonetheless by looking at your answer here again http://w3schools.invisionzone.com/index.php?showtopic=51266&hl= and by doing some testing I have reached to some conclusions.

 

First of all,the function must return a 3 dimensional array-something that does not happen now-and the reason lies in the answer you gave me in the above topic.

You gave me this code-I remind you that I was asking you how to add the service in an array-:

$details; while ($appdetails = $result->fetch_object()){  $details = array(    'name' => $appdetails->name,    'apID'=>$appdetails->apID,    'start'=>$appdetails->startDate,    'end'=>$appdetails->endDate,    'staffID'=>$appdetails->staffID,    'origin'=>$appdetails->apps_origin  );} while($service = $result1->fetch_object()){  $details['service'] = $service->serviceID;} $names[] = $detail;

The above creates a 2 dimensional array-which is undesirable-let me explain.

The problem lies in the first while loop,if the result of the query is more than one row,only the last will be passed to the $details array.

That is the mistake....service does get added successfully but the problem is directly above.

 

With the code below I solve this issue but the service addition code must be reconsidered cause it no longer works.

           {   while ($appdetails = $result->fetch_object()){          $appdata[]=['name'=>$appdetails->name,'apID'=>$appdetails->apID,                  'start'=>$appdetails->startDate,'end'=>$appdetails->endDate,'staffID'=>$appdetails->staffID                  ,'origin'=>$appdetails->apps_origin];           }               } 

I hope i was clear.Take a look now at var_dump($appdata):

array(2) { [0]=> array(6) { ["name"]=> string(7) "Kostas " ["apID"]=> string(2) "16" ["start"]=> string(19) "2014-08-27 12:30:00" ["end"]=> string(19) "2014-08-27 15:00:00" ["staffID"]=> string(1) "5" ["origin"]=> string(7) "backend" } [1]=> array(6) { ["name"]=> string(3) "nik" ["apID"]=> string(2) "17" ["start"]=> string(19) "2014-08-27 09:00:00" ["end"]=> string(19) "2014-08-27 11:00:00" ["staffID"]=> string(1) "5" ["origin"]=> string(7) "backend" }} 

For each of the above services must be added,and since this may contain more than one value,this must be another array(hence the 3 dimensional array).

I must take a look at the code in the function first before json_encode.

Link to comment
Share on other sites

How does the services query data relate to the first query data?

Is there a field in both of the 2 queries that retrieves the same value?

Each query retrieves data from a different db table-the tables are related though in the following manner:

The one table holds columns/data regarding appointments(APid,names,start,end etc)...the first query targets this table-APid is the primary key.

 

The other query targets a table where it holds the services chosen for a specific appointment.

For example we might have 2 rows there that correspond to the same appointments(same APid) but each row deals with a different service(service "1",service "2")

 

So I have to take these 2 values(related to two different service) from this second table and add them as an array to the array produced by the first query.

In essence the first query creates an array where each element is another array holding appointment data.

 

I hope I was clear.

Link to comment
Share on other sites

If apID is fetched in both queries then the arrays can be linked on this value.

 

 

while ($appdetails = $result->fetch_object()){$details = array('name' => $appdetails->name,'apID'=>$appdetails->apID,'start'=>$appdetails->startDate,'end'=>$appdetails->endDate,'staffID'=>$appdetails->staffID,'origin'=>$appdetails->apps_origin);$appdata[$appdetails->apID] = $details;}while($service = $result1->fetch_object()){ // make sure to fetch 'apID' field in this query$appdata[$service->apID]['service'][] = $service->serviceID;}
Link to comment
Share on other sites

 

If apID is fetched in both queries then the arrays can be linked on this value.

while ($appdetails = $result->fetch_object()){$details = array('name' => $appdetails->name,'apID'=>$appdetails->apID,'start'=>$appdetails->startDate,'end'=>$appdetails->endDate,'staffID'=>$appdetails->staffID,'origin'=>$appdetails->apps_origin);$appdata[$appdetails->apID] = $details;}while($service = $result1->fetch_object()){ // make sure to fetch 'apID' field in this query$appdata[$service->apID]['service'][] = $service->serviceID;}

Before doing what you propose I have to say this....

In the first while loop the code must be like this

while ($appdetails = $result->fetch_object()){$details []= array('name' => $appdetails->name,'apID'=>$appdetails->apID,'start'=>$appdetails->startDate,'end'=>$appdetails->endDate,'staffID'=>$appdetails->staffID,'origin'=>$appdetails->apps_origin);$appdata[$appdetails->apID] = $details;}

Cause your version will overwrite the previous array element....and we have 3 rows for example,only one will end up in the details array.

Link to comment
Share on other sites

In the following line of your code I get error "trying to get property" of a non-object.

$appdata[$appdetails->apID] = $details;
Link to comment
Share on other sites

You can see the code below,as already stated is not correct,I have incorporated your suggestions-only the first while loop is OK:

function get_appointments($connection,$email)//να μάθω για το μηνυμα που σχετίζεται με το κιτρινο τριγωνακι  {        $connection->set_charset("utf8");        $result=$connection->query('select appointments.name,appointments.apID,staffID,appointments.apps_origin,FROM_UNIXTIME( startDate ) as startDate ,FROM_UNIXTIME( endDate ) as endDate             from appointments,users            where users.email="'.$email.'"            and appointments.bookedfor=users.user_ID');                 if(!$result)        {printf("Errormessage for result: %sn", $connection->error);         return false;}         elseif($result->num_rows>0)                  {          while ($appdetails = $result->fetch_object()){          $appdata[]=['name'=>$appdetails->name,'apID'=>$appdetails->apID,                  'start'=>$appdetails->startDate,'end'=>$appdetails->endDate,'staffID'=>$appdetails->staffID                  ,'origin'=>$appdetails->apps_origin];           }        }                for($i=0;$i < count($appdata);++$i)        {           $result1 = $connection->query('select serviceID from services_list,appoint_servi_chosen               where services_list.serviceID=appoint_servi_chosen.service_ID               and appoint_servi_chosen.app_ID="'. $appdata[0]['apID'].'"');        }             if(!$result1)        {printf("Errormessage for result1: %sn", $connection->error);         return false;        }         elseif($result1->num_rows>0)        {          while($service = $result1->fetch_object())           {            $appdata[0]['service'][] = $service->serviceID;           }        }           return  $appdata;              }

here is the call:

$appdetails=get_appointments($conn,$email);
Link to comment
Share on other sites

I think the for loop does exactly that...unless you mean something else.

that's what I'm trying to say. the last thing at all is json_encode the whole thing. not items you are pushing. the very last thing I would expect, since you are encoding as JSON presumably for a web service, is

 

 

echo json_encode($myData);
Link to comment
Share on other sites

 

that's what I'm trying to say. the last thing at all is json_encode the whole thing. not items you are pushing. the very last thing I would expect, since you are encoding as JSON presumably for a web service, is

echo json_encode($myData);

I got what you said,nonetheless we are dealing here with a different aspect of the problem-long before using json_encode

Link to comment
Share on other sites

 

<?phpfunction get_appointments($connection,$email){$connection->set_charset("utf8");$result=$connection->query('select appointments.name,appointments.apID,staffID,appointments.apps_origin,FROM_UNIXTIME( startDate ) as startDate ,FROM_UNIXTIME( endDate ) as endDatefrom appointments,userswhere users.email="'.$email.'"and appointments.bookedfor=users.user_ID');if(!$result){printf("Errormessage for result: %sn", $connection->error);return false;}elseif($result->num_rows>0){$mapApIDToRowIndex = []; // int apID => row indexwhile ($appdetails = $result->fetch_object()){$mapApIDToRowIndex[$appdetails->apID] = count($appdata);$appdata[]=['name'=>$appdetails->name,'apID'=>$appdetails->apID,'start'=>$appdetails->startDate,'end'=>$appdetails->endDate,'staffID'=>$appdetails->staffID,'origin'=>$appdetails->apps_origin];}}for($i=0;$i < count($appdata);++$i){$result1 = $connection->query('select serviceID from services_list,appoint_servi_chosenwhere services_list.serviceID=appoint_servi_chosen.service_IDand appoint_servi_chosen.app_ID="'. $appdata[$i]['apID'].'"');if(!$result1){printf("Errormessage for result1: %sn", $connection->error);return false;}elseif($result1->num_rows>0){while($service = $result1->fetch_object()){$rowIndex = $mapApIDToRowIndex[$appdata[$i]['apID']];$appdata[$rowIndex]['service'][] = $service->serviceID;}}}return $appdata; // should be 3 dimensional}

 

sorry for the indentation, it gets unindented automatically for me :/

Link to comment
Share on other sites

First of all many thanks for the code,it works(3 dimensional array ARE produced)....but with a very small problem.

I get the following error regarding this code $mapApIDToRowIndex[$appdetails->apID] = count($appdata);//this is at line 35

 

Notice: Undefined variable: appdata in C:Apache24htdocsAppointmentsAdministratoradmin_db_code.php on line 35

 

So despite the notice,the job gets done but it would be nice if that was missing of course.

Link to comment
Share on other sites

I have already tried placing $mapApIDToRowIndex[$appdetails->apID] = count($appdata)

below the $appdata array creation and that produced other unwanted results.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...