Php : Element uit multi-array krijgen

Alles over programmeren en development binnen de IT-wereld
Plaats reactie
helmuteke
Premium Member
Premium Member
Berichten: 568
Lid geworden op: 08 feb 2010, 15:36
Uitgedeelde bedankjes: 3 keer
Bedankt: 27 keer

ik krijg het array verhaal van php maar niet onder de knie.

ik heb volgende array gecreeerd via een Api

Code: Selecteer alles

Array ( [0] => Array ( [responseCode] => 200 [error] => [response] => [{"id":5341,"attributes":{"batteryLevel":56.0,"distance":0.0,"totalDistance":0.0,"motion":false},"deviceId":1,"type":null,"protocol":"osmand","serverTime":null,"deviceTime":"2017-09-03T18:29:41.000+0000","fixTime":"2017-09-03T18:29:41.000+0000","outdated":false,"valid":true,"latitude":51.177466,"longitude":2.941456,"altitude":-3.06641,"speed":0.0,"course":63.9844,"address":null,"accuracy":0.0,"network":null}] ) )
ik zou er de waarden van de attributen batterylevel , totalDistance , motion moeten uitkrijgen
de array zit in een $geg[] .

kan me iemand op weg helpen want geraak er niet wijs uit.
Gebruikersavatar
Splitter
Elite Poster
Elite Poster
Berichten: 5230
Lid geworden op: 10 maa 2010, 12:30
Uitgedeelde bedankjes: 64 keer
Bedankt: 520 keer
Recent bedankt: 9 keer

dat lijkt me json?
ff uit mijn hoofd denk ik aan zoiets:

$datajson = $geg['0']['response'];
$datarray = json_decode($datajson,true);
$batterylevel = $datarray['attributes']['batteryLevel'];
echo $batterylevel;

maarehm.... lijkt me niet de meest efficiente manier om je data te krijgen?
(of er ontbreekt iets aan je uitleg, mss)

edit: 'true' toegevoegd om de json data in een array om te zetten ipv string.
hoe je precies de 56PUNT0 kan krijgen geen idee... denk dat het slechte json is want geloof niet dat een punt is toegelaten zonder die te quoten in " of ' ...
helmuteke
Premium Member
Premium Member
Berichten: 568
Lid geworden op: 08 feb 2010, 15:36
Uitgedeelde bedankjes: 3 keer
Bedankt: 27 keer

doe ik het volgende

Code: Selecteer alles

$json_string = json_encode($geg, JSON_PRETTY_PRINT);
dan krijg ik dit

Code: Selecteer alles

{ "responseCode": 200, "error": "", "response": "[{\"id\":5481,\"attributes\":{\"batteryLevel\":55.0,\"distance\":0.0,\"totalDistance\":0.0,\"motion\":false},\"deviceId\":1,\"type\":null,\"protocol\":\"osmand\",\"serverTime\":null,\"deviceTime\":\"2017-09-03T18:54:09.000+0000\",\"fixTime\":\"2017-09-03T18:54:09.000+0000\",\"outdated\":false,\"valid\":true,\"latitude\":51.177466,\"longitude\":2.941456,\"altitude\":-0.270142,\"speed\":0.0,\"course\":63.9844,\"address\":null,\"accuracy\":0.0,\"network\":null}]" }
ik genereer natuurlijk uit de api een JSON

doe ik jouw voorstel dan krijg ik volgende fout

Code: Selecteer alles

Fatal error: Cannot use object of type stdClass as array in
dit op de lijn

Code: Selecteer alles

$datajson = $geg['0']['response'];
Gebruikersavatar
Splitter
Elite Poster
Elite Poster
Berichten: 5230
Lid geworden op: 10 maa 2010, 12:30
Uitgedeelde bedankjes: 64 keer
Bedankt: 520 keer
Recent bedankt: 9 keer

ja, heb het in mijn edit hierboven al aangepast :)

wil je werken met de data als string dan doe je dit:

$datajson = $geg['0']['response'];
$datarray = json_decode($datajson);
$batterylevel = $datarray->attributes->batteryLevel;
echo "$batterylevel";

blijft nog steeds zo dat je de 56.0 niet gaat krijgen omdat het niet "56.0" is in de aangereikte data.

edit: dit is trouwens enkel zo voor wat op .0 eindigt (php stript dat eruit) - kan je niet dadelijk zeggen of je dat kan uitschakelen,
maar het lijkt me dat een .0 niet zo belangrijk is (en anders check je achteraf of je iets achter de . hebt en dan voeg je gewoon .0 toe achteraf)
helmuteke
Premium Member
Premium Member
Berichten: 568
Lid geworden op: 08 feb 2010, 15:36
Uitgedeelde bedankjes: 3 keer
Bedankt: 27 keer

de stukjes code geven geen fout , maar ook geen output

nu heb ik effe scratch gedaan en volgende aangepast

Code: Selecteer alles

echo json_encode($geg);
dus gewoon de json encoderen , dan krijg ik als output

Code: Selecteer alles

{"responseCode":200,"error":"","response":"[{\"id\":5572,\"attributes\":{\"batteryLevel\":54.0,\"distance\":0.0,\"totalDistance\":0.0,\"motion\":false},\"deviceId\":1,\"type\":null,\"protocol\":\"osmand\",\"serverTime\":null,\"deviceTime\":\"2017-09-03T19:10:16.000+0000\",\"fixTime\":\"2017-09-03T19:10:16.000+0000\",\"outdated\":false,\"valid\":true,\"latitude\":51.177466,\"longitude\":2.941456,\"altitude\":1.3147,\"speed\":0.0,\"course\":63.9844,\"address\":null,\"accuracy\":0.0,\"network\":null}]"}
mss handiger ?
Gebruikersavatar
Splitter
Elite Poster
Elite Poster
Berichten: 5230
Lid geworden op: 10 maa 2010, 12:30
Uitgedeelde bedankjes: 64 keer
Bedankt: 520 keer
Recent bedankt: 9 keer

kan je een keer tonen wat de data is die je binnenkrijgt van de api, letterlijk?
dus zonder iets te encoden of te bewerken gewoon de letterlijke output van de api (waarmee jij dus begint)
helmuteke
Premium Member
Premium Member
Berichten: 568
Lid geworden op: 08 feb 2010, 15:36
Uitgedeelde bedankjes: 3 keer
Bedankt: 27 keer

via de browser krijg ik deze output

Code: Selecteer alles

[{"id":5695,"attributes":{"batteryLevel":53.0,"distance":0.0,"totalDistance":5.09,"motion":false},"deviceId":1,"type":null,"protocol":"osmand","serverTime":null,"deviceTime":"2017-09-03T19:31:52.000+0000","fixTime":"2017-09-03T19:31:52.000+0000","outdated":false,"valid":true,"latitude":51.177434,"longitude":2.941404,"altitude":-1.92926,"speed":0.0,"course":63.9844,"address":null,"accuracy":0.0,"network":null}]
de functie welke de gegevens vanuit de api haal in php is deze

de aanroep voor $geg

Code: Selecteer alles

$geg = traccar::positions2($traccarCookie); 
de functie positions2

Code: Selecteer alles

public static function positions2($cookie) {

     

        return self::curl('/api/positions?','GET',$cookie ,'',array());
    }
en de functie curl

Code: Selecteer alles

public static function curl($task,$method,$cookie,$data,$header) {

        $res=new stdClass();

        $res->responseCode='';

        $res->error='';

       // $header[]="Cookie: ".$cookie;
		
		$header = array(
    'Cookie: '.$cookie,
    'Accept: application/json',
);

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, self::$host.$task);

        curl_setopt($ch, CURLOPT_TIMEOUT, 30);

        curl_setopt($ch, CURLOPT_HEADER, 1);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);

        if($method=='POST' || $method=='PUT' || $method=='DELETE') {

            curl_setopt($ch, CURLOPT_POST, 1);

            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        }

        curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
				
        $data=curl_exec($ch);
		        $size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);

        if (preg_match('/^Set-Cookie:\s*([^;]*)/mi', substr($data, 0, $size), $c) == 1) self::$cookie = $c[1];

        $res->response = substr($data, $size);

        if(!curl_errno($ch)) {

            $res->responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        }
        else {

            $res->responseCode=400;

            $res->error= curl_error($ch);
        }

        curl_close($ch);

        return $res;
    }
}
Gebruikersavatar
Splitter
Elite Poster
Elite Poster
Berichten: 5230
Lid geworden op: 10 maa 2010, 12:30
Uitgedeelde bedankjes: 64 keer
Bedankt: 520 keer
Recent bedankt: 9 keer

dus eigenlijk krijg je gewoon json binnen (en lijkt me logischer als een array)

$geg = traccar::positions2($traccarCookie);
$datarray = json_decode($geg);
$batterylevel = $datarray->attributes->batteryLevel;
echo $batterylevel;

dat zou het moeten doen
(met andere woorden: je werkt niet echt met een array maar json data )
helmuteke
Premium Member
Premium Member
Berichten: 568
Lid geworden op: 08 feb 2010, 15:36
Uitgedeelde bedankjes: 3 keer
Bedankt: 27 keer

geen output

wel een waarschuwing

Code: Selecteer alles

Warning: json_decode() expects parameter 1 to be string, object given 
nu zou $geg geen string zijn ofzo maar een class

Code: Selecteer alles

new stdClass()
edit : heb alles uit de class gesmeten en enkel de json geretourneerd.

nu krijg ik de pure json

Code: Selecteer alles

[{"id":5933,"attributes":{"batteryLevel":49.0,"distance":0.0,"totalDistance":5.09,"motion":false},"deviceId":1,"type":null,"protocol":"osmand","serverTime":null,"deviceTime":"2017-09-03T20:13:46.000+0000","fixTime":"2017-09-03T20:13:46.000+0000","outdated":false,"valid":true,"latitude":51.177434,"longitude":2.941404,"altitude":-1.2312,"speed":0.0,"course":63.9844,"address":null,"accuracy":0.0,"network":null}]
de gegeven code retourneert echter niets
Gebruikersavatar
Splitter
Elite Poster
Elite Poster
Berichten: 5230
Lid geworden op: 10 maa 2010, 12:30
Uitgedeelde bedankjes: 64 keer
Bedankt: 520 keer
Recent bedankt: 9 keer

als je het ziet zitten, stuur me dan ff het script zelf... dat debugt mss wat eenvoudiger :)

normaal krijg je van een api iets terug in json formaat, dan moet je json decode kunnen doen, en dan zou je ofwel een object (stdclass) ofwel een array terugkrijgen.
ik heb beide opties hier al aangehaald, en beide zouden perfect moeten werken...

zonder het script zelf lijkt het me niet echt realistisch meer om je nog te kunnen helpen.
helmuteke
Premium Member
Premium Member
Berichten: 568
Lid geworden op: 08 feb 2010, 15:36
Uitgedeelde bedankjes: 3 keer
Bedankt: 27 keer

pb gestuurd
Gebruikersavatar
Splitter
Elite Poster
Elite Poster
Berichten: 5230
Lid geworden op: 10 maa 2010, 12:30
Uitgedeelde bedankjes: 64 keer
Bedankt: 520 keer
Recent bedankt: 9 keer

probeer eens:


public static function curl($task,$method,$cookie,$data,$header) {
//$res=new stdClass();

.....


curl_close($ch);
$res = json_encode($res);
return $res;
Gebruikersavatar
Splitter
Elite Poster
Elite Poster
Berichten: 5230
Lid geworden op: 10 maa 2010, 12:30
Uitgedeelde bedankjes: 64 keer
Bedankt: 520 keer
Recent bedankt: 9 keer

goed, heb even de tijd gehad om er eens tegoei naar te kijken.

gewoon origineel script nemen, en op deze manier het aanroepen:

Code: Selecteer alles

$t=traccar::login($email,$password);

if($t->responseCode=='200') {

$geg = traccar::positions2($traccarCookie);
$response = $geg->response;
$datarray = json_decode($response,true);
$attributes = $datarray['0']['attributes'];
$batterylevel = $attributes['batteryLevel'];
echo "battery is at $batterylevel";
    /*

    .....

     */
}
Plaats reactie

Terug naar “Development”