Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Brug af curl i php-script

3 views
Skip to first unread message

Kim Ludvigsen

unread,
Sep 13, 2018, 10:15:23 AM9/13/18
to
Jeg plejer at trække en kurs fra den thailandske nationalbank med
file_get_contents, men nu kræver de, at man er registreret, og de viser
et eksempel med curl - jeg kan bare ikke få det til at virke.

De viser nedenstående som eksempel på en kode:

curl --request GET \
--url
'https://apigw1.bot.or.th/bot/public/Stat-ExchangeRate/DAILY_AVG_EXG_RATE_V1/?start_period=20180913&end_period=20180913&currency=DKK
\
--header 'accept: application/json' \
--header 'x-ibm-client-id: REPLACE_THIS_KEY'

REPLACE_THIS_KEY skal selvfølgelig udskiftes med et ID, som jeg har
fået, men som jeg jo af gode grunde ikke kan skrive her.

Hvordan i alverden bruger jeg deres kode i et PHP-script? Jeg har
selvfølgelig prøvet at tjekke PHP-manualen med curl, men det er desværre
sort snak for mig.

--
Mvh. Kim Ludvigsen

Jan Hansen

unread,
Sep 13, 2018, 12:43:24 PM9/13/18
to
Skal det absolut være fra nationalbanken?
Det her giver nok samme resultat,

<?php
$v=file_get_contents('https://www.valutakurser.dk/forex/details.aspx?id=492430');
$p=strpos($v,"\n",strpos($v,'stockPriceUCLastPrice'));
echo "Kursen er ".trim(substr($v,$p,strpos($v,"<",$p)-$p));
?>



--
mvh Jan.
Help Microsoft stamp out piracy. Give
Linux to a friend today!

Kim Ludvigsen

unread,
Sep 13, 2018, 2:27:13 PM9/13/18
to
Den 13-09-2018 kl. 18:43 skrev Jan Hansen:
> Skal det absolut være fra nationalbanken?
> Det her giver nok samme resultat,
>
> <?php
> $v=file_get_contents('https://www.valutakurser.dk/forex/details.aspx?id=492430');
> $p=strpos($v,"\n",strpos($v,'stockPriceUCLastPrice'));
> echo "Kursen er ".trim(substr($v,$p,strpos($v,"<",$p)-$p));
> ?>

Tak, men det er desværre ikke kun THB/DKK, jeg skal bruge.

På min danske hjemmeside, henter jeg den kurs fra den danske
nationalbank. På min engelske udgave af hjemmesiden skal jeg bruge
kurser for 13 forskellige valutaer - og det skal helst ikke være den
aktuelle kurs, men den officielle middelkurs for dagen. Jeg skal også
gerne kunne trække datoen ud.

Kan valutakurser.dk leve op til det? I så fald, hvordan fandt du den
pågældende URL?

--
Mvh. Kim Ludvigsen

Bertel Lund Hansen

unread,
Sep 13, 2018, 3:03:16 PM9/13/18
to
Jan Hansen skrev:

> Skal det absolut være fra nationalbanken?
> Det her giver nok samme resultat,

> <?php
> $v=file_get_contents('https://www.valutakurser.dk/forex/details.aspx?id=492430');
> $p=strpos($v,"\n",strpos($v,'stockPriceUCLastPrice'));
> echo "Kursen er ".trim(substr($v,$p,strpos($v,"<",$p)-$p));
> ?>

Nogle PHP-opsætninger tillader ikke den adgang. CURL er den sikre
måde at gøre det på.

--
/Bertel

Kim Ludvigsen

unread,
Sep 13, 2018, 4:22:44 PM9/13/18
to
Jeg har lige testet, og det virker på mit webhotel, men det er jo ingen
garanti for, at det også vil virke i morgen. Jeg vil helt klart
foretrække at få det til at virke med den thailandske nationalbank, men
jeg vil være tilfreds, hvis bare jeg kan få det til at virke.

Det er drønirriterende, at de forhindrer, at jeg henter via
file_get_contents - jeg var ellers så flink kun at hente én gang i
døgnet i stedet for ved hvert besøg.

--
Mvh. Kim Ludvigsen

Kim Ludvigsen

unread,
Sep 13, 2018, 4:40:40 PM9/13/18
to
Den 13-09-2018 kl. 16:13 skrev Kim Ludvigsen:

Hvor flovt. Jeg havde ikke set, at de havde en menu, hvor man kunne
finde eksempler til forskellige script-sprog. De havde også et eksempel
til PHP.

> De viser nedenstående som eksempel på en kode:
>
> curl --request GET \
>   --url
> 'https://apigw1.bot.or.th/bot/public/Stat-ExchangeRate/DAILY_AVG_EXG_RATE_V1/?start_period=20180913&end_period=20180913&currency=DKK
> \
>   --header 'accept: application/json' \
>   --header 'x-ibm-client-id: REPLACE_THIS_KEY'

PHP-udgaven, hvis andre skulle have brug for opskriften curl => php:

$curl = curl_init();

curl_setopt_array($curl, array(
CURLOPT_URL =>
"https://apigw1.bot.or.th/bot/public/Stat-ExchangeRate/DAILY_AVG_EXG_RATE_V1/?start_period=2018-09-13&end_period=2018-09-13&currency=DKK",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"accept: application/json",
"x-ibm-client-id: REPLACE_THIS_KEY"
),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}

--
Mvh. Kim Ludvigsen

Kim Ludvigsen

unread,
Sep 13, 2018, 4:45:49 PM9/13/18
to
Den 13-09-2018 kl. 22:38 skrev Kim Ludvigsen:
> Den 13-09-2018 kl. 16:13 skrev Kim Ludvigsen:
>
> Hvor flovt. Jeg havde ikke set, at de havde en menu, hvor man kunne
> finde eksempler til forskellige script-sprog. De havde også et eksempel
> til PHP.

Og nu kommer næste problem så, hvordan udtrækker jeg værdien for
"mid_rate" (den sidste værdi i svaret, som ses nedenfor).

{"result":{"success":"true","api":"Daily Weighted-average Interbank
Exchange Rate - THB / USD","timestamp":"2018-09-14
03:36:22","data":{"data_header":{"report_name_eng":"Rates of Exchange of
Commercial Banks in Bangkok Metropolis
(2002-present)","report_name_th":"อัตราแลกเปลี่ยนเฉลี่ยของธนาคารพาณิชย์ในกรุงเทพมหานคร
(2545-ปัจจุบัน)","report_uoq_name_eng":"(Unit : Baht / 1 Unit of Foreign
Currency)","report_uoq_name_th":"(หน่วย : บาท ต่อ 1
หน่วยเงินตราต่างประเทศ)","report_source_of_data":[{"source_of_data_eng":"Bank
of
Thailand","source_of_data_th":"ธนาคารแห่งประเทศไทย"}],"report_remark":[{"report_remark_eng":"Since
Nov 16, 2015 the data regarding Buying Transfer Rate of PKR has been
changed to Buying Rate using Foreign Exchange Rates (THOMSON REUTERS)
with Bangkok Market Crossing.","report_remark_th":"ตั้งแต่วันที่ 16 พ.ย.
2558 ข้อมูลในอัตราซื้อเงินโอนของสกุล PKR
ได้เปลี่ยนเป็นอัตราซื้อที่ใช้อัตราในตลาดต่างประเทศ (ทอมสันรอยเตอร์)
คำนวณผ่านอัตราซื้อขายเงินดอลลาร์ สรอ.
ในตลาดกรุงเทพฯ"}],"last_updated":"2018-09-13"},"data_detail":[{"period":"2018-09-13","currency_id":"DKK","currency_name_th":"เดนมาร์ก
: โครน (DKK)","currency_name_eng":"DENMARK : KRONE (DKK)
","buying_sight":"5.0225000","buying_transfer":"5.0394000","selling":"5.1374000","mid_rate":"5.0884000"}]}}}

--
Mvh. Kim Ludvigsen

Jan Hansen

unread,
Sep 13, 2018, 4:56:22 PM9/13/18
to
Den Thu, 13 Sep 2018 22:20:39 +0200 skrev Kim Ludvigsen <k...@kimsside.dk>:

> Jeg har lige testet, og det virker på mit webhotel, men det er jo ingen
> garanti for, at det også vil virke i morgen.

Det virker åbenbart ganske stabilt, jeg fandt et link til svenske kroner i en logfil fra december 2016, det er stadig samme url.
Det med dagens middelkurs er det nok lidt værre med, er det den, der står ude i højre side under "Kurshistorik"?
Jeg fandt siden ved at gå ind på valutakurser.dk og så klikke på "Thailandsk baht" et stykke nede af forsiden.

Jan Hansen

unread,
Sep 13, 2018, 5:22:07 PM9/13/18
to
Den Thu, 13 Sep 2018 22:43:44 +0200 skrev Kim Ludvigsen <k...@kimsside.dk>:

> > echo $response;

> Og nu kommer næste problem så, hvordan udtrækker jeg værdien for
> "mid_rate" (den sidste værdi i svaret, som ses nedenfor).

Der står jo kun "mid_rate" et sted, så det er bare at tage tallet 11
tegn længere fremme:

<?php
$response='bla bla bla "5.0394000","selling":"5.1374000","mid_rate":"5.0884000"}]}}}';
$kurs=floatval(substr($response,strpos($response,'mid_rate')+11));
echo $kurs;
?>

Kim Ludvigsen

unread,
Sep 13, 2018, 5:32:55 PM9/13/18
to
Den 13-09-2018 kl. 23:22 skrev Jan Hansen:
> Den Thu, 13 Sep 2018 22:43:44 +0200 skrev Kim Ludvigsen <k...@kimsside.dk>:
>
>>> echo $response;
>
>> Og nu kommer næste problem så, hvordan udtrækker jeg værdien for
>> "mid_rate" (den sidste værdi i svaret, som ses nedenfor).
>
> Der står jo kun "mid_rate" et sted, så det er bare at tage tallet 11
> tegn længere fremme:
>
> <?php
> $response='bla bla bla "5.0394000","selling":"5.1374000","mid_rate":"5.0884000"}]}}}';
> $kurs=floatval(substr($response,strpos($response,'mid_rate')+11));
> echo $kurs;
> ?>

Smukt, det virker helt fint! Jeg havde ingen ide om, hvordan jeg trak
det ud. Hidtil har jeg kun prøvet at trække værdier ud af feeds - og det
kun ved at kopiere kode fra andre steder.

Mange tak for hjælpen!

--
Mvh. Kim Ludvigsen

Martin Larsen

unread,
Sep 14, 2018, 7:54:12 AM9/14/18
to
Den 13-09-2018 kl. 23:22 skrev Jan Hansen:

> Der står jo kun "mid_rate" et sted, så det er bare at tage tallet 11
> tegn længere fremme:

Det virker, men det er ikke en robust måde at gøre det på.

Strengen er json-data, så den rigtige løsning er at bruge json_decode:


$json = '{"result":{"success":"true","api":"Daily Weighted-average
Interbank Exchange Rate - THB / USD","timestamp":"2018-09-14
03:36:22","data":{"data_header":{"report_name_eng":"Rates of Exchange of
Commercial Banks in Bangkok Metropolis
(2002-present)","report_name_th":"อัตราแลกเปลี่ยนเฉลี่ยของธนาคารพาณิชย์ในกรุงเทพมหานคร
(2545-ปัจจุบัน)","report_uoq_name_eng":"(Unit : Baht / 1 Unit of Foreign
Currency)","report_uoq_name_th":"(หน่วย : บาท ต่อ 1
หน่วยเงินตราต่างประเทศ)","report_source_of_data":[{"source_of_data_eng":"Bank
of
Thailand","source_of_data_th":"ธนาคารแห่งประเทศไทย"}],"report_remark":[{"report_remark_eng":"Since
Nov 16, 2015 the data regarding Buying Transfer Rate of PKR has been
changed to Buying Rate using Foreign Exchange Rates (THOMSON REUTERS)
with Bangkok Market Crossing.","report_remark_th":"ตั้งแต่วันที่ 16 พ.ย.
2558 ข้อมูลในอัตราซื้อเงินโอนของสกุล PKR
ได้เปลี่ยนเป็นอัตราซื้อที่ใช้อัตราในตลาดต่างประเทศ (ทอมสันรอยเตอร์)
คำนวณผ่านอัตราซื้อขายเงินดอลลาร์ สรอ.
ในตลาดกรุงเทพฯ"}],"last_updated":"2018-09-13"},"data_detail":[{"period":"2018-09-13","currency_id":"DKK","currency_name_th":"เดนมาร์ก
: โครน (DKK)","currency_name_eng":"DENMARK : KRONE (DKK)
","buying_sight":"5.0225000","buying_transfer":"5.0394000","selling":"5.1374000","mid_rate":"5.0884000"}]}}}
';

$obj = json_decode($json);
$midrate = $obj->result->data->data_detail[0]->mid_rate;
echo $midrate;

Martin Larsen

unread,
Sep 14, 2018, 7:55:45 AM9/14/18
to
Den 14-09-2018 kl. 13:54 skrev Martin Larsen:

> Strengen er json-data, så den rigtige løsning er at bruge json_decode:


Tip:

Smid json-data ind fx her http://jsonviewer.stack.hu/ og klik på Format.

Bertel Lund Hansen

unread,
Sep 14, 2018, 8:40:55 AM9/14/18
to
Martin Larsen skrev:

> Tip:
> Smid json-data ind fx her http://jsonviewer.stack.hu/ og klik på Format.

Smart. Bagefter kan man klikke på "Viewer". Så bliver det mere
overskueligt.

--
/Bertel

Jan Hansen

unread,
Sep 14, 2018, 10:19:54 AM9/14/18
to
Den Fri, 14 Sep 2018 13:55:44 +0200 skrev Martin Larsen <martin+spam...@bigfoot.com>:

> Tip:
>
> Smid json-data ind fx her http://jsonviewer.stack.hu/ og klik på Format.

Ja, den side gør det selvfølgelig noget nemmere, ellers kan man vist nemt
bruge timer på at gennemskue det array i arrays array i 5 lag. Når "mid_rate"
ikke forekommer et varierende antal gange i $response, er det meget nemmere
bare at klippe det ud som tekst. Men ok,

<?php
$a=json_decode($response, true);
echo 'Kursen er: '.$a["result"]["data"]["data_detail"][0]["mid_rate"];

Kim Ludvigsen

unread,
Sep 14, 2018, 12:35:16 PM9/14/18
to
Den 14-09-2018 kl. 16:19 skrev Jan Hansen:
> Den Fri, 14 Sep 2018 13:55:44 +0200 skrev Martin Larsen <martin+spam...@bigfoot.com>:
>
>> Tip:
>>
>> Smid json-data ind fx her http://jsonviewer.stack.hu/ og klik på Format.
>
> <?php
> $a=json_decode($response, true);
> echo 'Kursen er: '.$a["result"]["data"]["data_detail"][0]["mid_rate"];
> ?>

Jeg havde lige nået at få lavet det med substr - jeg prøver at bruge
json-decode i stedet.

Tak til jer alle!

--
Mvh. Kim Ludvigsen

Martin Larsen

unread,
Sep 14, 2018, 3:53:18 PM9/14/18
to
Den 14-09-2018 kl. 16:19 skrev Jan Hansen:

> Når "mid_rate" ikke forekommer et varierende antal gange i $response, er det meget nemmere
> bare at klippe det ud som tekst

Det kommer an på hvor vant man er til at arbejde med JSON ;-)

Men problemet er at din metode ikke er robust; du kan ikke vide om der
pludselig kommer en mid_rate_2 et sted. Det vil ikke umiddelbart
ødelægge json-metoden.

Desuden er det nyttigt at kende til JSON, 99% af alle API'er i dag
bruger JSON. Det har nærmest fuldstændig skubbet XML af pinden.

Og heldigvis for det.

Jan Hansen

unread,
Sep 14, 2018, 7:04:11 PM9/14/18
to
Den Fri, 14 Sep 2018 21:53:18 +0200 skrev Martin Larsen <martin+spam...@bigfoot.com>:

> Den 14-09-2018 kl. 16:19 skrev Jan Hansen:
>
> > Når "mid_rate" ikke forekommer et varierende antal gange i $response, er det meget nemmere
> > bare at klippe det ud som tekst
>
> Det kommer an på hvor vant man er til at arbejde med JSON ;-)
>
> Men problemet er at din metode ikke er robust; du kan ikke vide om der
> pludselig kommer en mid_rate_2 et sted.
Ja, det er selvfølgelig rigtig nok. Skulle der være risiko for det, må jeg
medtage gåseøjnene, og rette strpos($response,'mid_rate')+11 til
strpos($response,'"mid_rate"')+12

> Det vil ikke umiddelbart ødelægge json-metoden.
Næ, men så er der til gengæld 5 forskellige led, ændrer de bare et af dem
virker stien ikke mere. F.eks. det [0] midt i det hele giver vel ikke meget
mening, når filen kun indeholder oplysninger om én valuta.
Siden <http://jsonviewer.stack.hu/> gør det selvfølgelig lidt nemmere,
men efter min mening er det ikke så simpelt at bruge var_dump, finde "mid_rate"
i outputtet, og via indrykningerne finde navnene på alle mellemleddene.
Det virker på mig som om det er lavet sådan for at man skal holde fingrene væk,
lidt ligesom de krypterede strenge i Microsofts registreringsdatabase.

Bertel Lund Hansen

unread,
Sep 15, 2018, 3:55:27 AM9/15/18
to
Jan Hansen skrev:

>> Men problemet er at din metode ikke er robust; du kan ikke vide om der
>> pludselig kommer en mid_rate_2 et sted.

> Ja, det er selvfølgelig rigtig nok. Skulle der være risiko for det, må jeg
> medtage gåseøjnene, og rette strpos($response,'mid_rate')+11 til
> strpos($response,'"mid_rate"')+12

Derudover kunne det jo være at Kim var interesseret i nogle af de
andre data.

> Det virker på mig som om det er lavet sådan for at man skal holde fingrene væk,

Det rimer jo ikke med at de selv angiver en metode til at
udtrække data. Det kunne også få mig til at formode at de bevarer
formatet.

--
/Bertel

Kim Ludvigsen

unread,
Sep 15, 2018, 4:03:47 AM9/15/18
to
Den 15-09-2018 kl. 09:55 skrev Bertel Lund Hansen:
> Jan Hansen skrev:
>
>> Ja, det er selvfølgelig rigtig nok. Skulle der være risiko for det, må jeg
>> medtage gåseøjnene, og rette strpos($response,'mid_rate')+11 til
>> strpos($response,'"mid_rate"')+12
>
> Derudover kunne det jo være at Kim var interesseret i nogle af de
> andre data.

Jeg foretrækker også at hente datoen, da den måske er en anden end dags
dato, men det fandt jeg nu også ud af at gøre med substr.

Når jeg nu alligevel skal ændre til json, så et lille spørgsmål:
I øjeblikket gentager jeg den samme kode for samtlige valutaer. Det må
kunne gøres lidt smartere med et array og en løkke, men kan det betale
sig at prøve at få det til at virke, når jeg ikke er skrap til den
slags? Scriptet skal blot køre én gang i døgnet på hverdage, så
optimering er vel ikke så vigtigt?

--
Mvh. Kim Ludvigsen

Bertel Lund Hansen

unread,
Sep 15, 2018, 4:08:11 AM9/15/18
to
Kim Ludvigsen skrev:

> Når jeg nu alligevel skal ændre til json, så et lille spørgsmål:
> I øjeblikket gentager jeg den samme kode for samtlige valutaer. Det må
> kunne gøres lidt smartere med et array og en løkke, men kan det betale
> sig at prøve at få det til at virke, når jeg ikke er skrap til den
> slags? Scriptet skal blot køre én gang i døgnet på hverdage, så
> optimering er vel ikke så vigtigt?

Hvor mange valutaer snakker vi om?

Hvis jeg skal hitte ud af hvordan det kan gøres, skal jeg have
hele scriptet at se.

Jeg ville til enhver tid lave en løkke uanset hvor mange valutaer
det drejer sig om (blot mere end 1).

--
/Bertel

Kim Ludvigsen

unread,
Sep 15, 2018, 5:32:06 AM9/15/18
to
Den 15-09-2018 kl. 10:08 skrev Bertel Lund Hansen:
> Kim Ludvigsen skrev:
>
>> Scriptet skal blot køre én gang i døgnet på hverdage, så
>> optimering er vel ikke så vigtigt?
>
> Hvor mange valutaer snakker vi om?

13

> Hvis jeg skal hitte ud af hvordan det kan gøres, skal jeg have
> hele scriptet at se.

Jeg har endnu ikke fået lavet om til json, her er en forespørgsel med
den nuværende kode:

$idag = date(Y-m-d);

// USD
$url="https://apigw1.bot.or.th/bot/public/Stat-ExchangeRate/DAILY_AVG_EXG_RATE_V1/?currency=USD&start_period=$idag&end_period=$idag";

$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "$url",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"accept: application/json",
"x-ibm-client-id: XXXXX"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);

// Denne if er kun ved den første forespørgsel (USD), så der afbrydes,
hvis nationalbankens server ikke svarer.
if ($err) exit ();

$usdkurs=floatval(substr($response,strpos($response,'mid_rate')+11));
$usddato=substr($response,strpos($response,'last_updated')+15,10);


Det eneste der udskiftes er currency=USD, hvor de 13 værdier er:
USD, GBP, EUR, JPY, INR, AUD, RUB, CNY, HKD, MYR, SGD, TWD, DKK

og $usdkurs og $usddato, der udskiftes med gbpkurs, gbpdato osv.

Efter alle forespørgsler gemmer jeg i en fil:
$kurser =
"$usdkurs,$usddato,$gbpkurs,$gbpdato,$eurkurs,$eurdato,$jpykurs,$jpydato,$inrkurs,$inrdato,$audkurs,$auddato,$rubkurs,$rubdato,$cnykurs,$cnydato,$hkdkurs,$hkddato,$myrkurs,$myrdato,$sgdkurs,$sgddato,$twdkurs,$twddato,$dkkkurs,$dkkdato,$timestamp";

file_put_contents("$filnavn",$kurser, LOCK_EX);

--
Mvh. Kim Ludvigsen

Jan Hansen

unread,
Sep 15, 2018, 7:34:05 AM9/15/18
to
Det må være noget i stil med:

<?php
$lande=explode(', ',"USD, GBP, EUR, JPY, INR, AUD, RUB, CNY, HKD, MYR, SGD, TWD, DKK");
$idag = date("Y-m-d"); $output='';
foreach ($lande as $land) {
$url='https://apigw1.bot.or.th/bot/public/Stat-ExchangeRate/DAILY_AVG_EXG_RATE_V1/?currency='.$land.'&start_period='.$idag.'&end_period='.$idag;
$curl = curl_init();

# og så videre ...

curl_close($curl);
if ($err) exit ();
$output.=floatval(substr($response,strpos($response,'mid_rate')+11)).',';
$output.=substr($response,strpos($response,'last_updated')+15,10).',';
}
# klip sidste komma af:
$output=substr($output,0,strlen($output)-1);
file_put_contents("$filnavn",$output, LOCK_EX);
?>

Jan Hansen

unread,
Sep 15, 2018, 8:39:59 AM9/15/18
to
Den Sat, 15 Sep 2018 09:55:27 +0200 skrev Bertel Lund Hansen <gade...@lundhansen.dk>:

> Jan Hansen skrev:
>
> > Det virker på mig som om det er lavet sådan for at man skal holde fingrene væk,
>
> Det rimer jo ikke med at de selv angiver en metode til at
> udtrække data. Det kunne også få mig til at formode at de bevarer
> formatet.

Hvis de angiver en metode, kan det selvfølgelig godt være, det bliver lidt nemmere.
Men jeg foretrækker nu alligevel en ægte tekst, så jeg i en almindelig teksteditor
kan se, hvad jeg har med at gøre, i stedet for noget virtuel hokuspokus, hvor jeg
kan trække en værdi ud af et 5-dimensionalt array, hvis jeg kan gætte navnene på
de første 4 arraykeys.
Findes der en service på nettet, hvor man kan stoppe json ind i et felt, og skrive
"mid_rate" i et andet felt, og så få serveret:
$obj->result->data->data_detail[0]->mid_rate
["result"]["data"]["data_detail"][0]["mid_rate"]
og - hvis der er flere "mid_rate" (På dansk: hvis det skal give mening med array
i array) - lister de andre forekomster på samme måde?

Bertel Lund Hansen

unread,
Sep 15, 2018, 8:49:22 AM9/15/18
to
Kim Ludvigsen skrev:

>> Hvor mange valutaer snakker vi om?
>
> 13

Okay, her er koden. Jeg har lagt kommentarlinjer ind for at
opdele koden i logiske afsnit. Det gør jeg altid, og det er en
god vane. Jeg har slået linjeopdeling fra i mit mailprogram
så det leverer uendeligt lange linjer.

<?
// ---------------- Constants ----------------

$currencies = array('USD', 'GBP', 'EUR', 'JPY', 'INR', 'AUD', 'RUB', 'CNY', 'HKD', 'MYR', 'SGD', 'TWD', 'DKK');
$url_0 = "https://apigw1.bot.or.th/bot/public/Stat-ExchangeRate/DAILY_AVG_EXG_RATE_V1/?currency=";
$url_1 = "&start_period=$idag&end_period=$idag";
$idag = date(Y-m-d);

// ---------------- Main ----------------

$kurser = "";
foreach ($currencies as $currency) {
$url = $url_0.$currency.$url_1;
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "$url",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"accept: application/json",
"x-ibm-client-id: XXXXX"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);

$kurs = floatval(substr($response,strpos($response,'mid_rate')+11));
$dato = substr($response,strpos($response,'last_updated')+15,10);
$kurser .= "$kurs,$dato,";
}
$kurser = trim($kurser,",");
file_put_contents($filnavn,$kurser, LOCK_EX);
?>

Kommentarer:
Jeg har splittet urlen op i to dele - dog uden koden for valutaen.
Løkken gennemløber alle valutakoderne og giver dem
variabelnavnet $currency. Jeg kan derfor bygge den nødvendige
url ved at sammensætte de tre dele, og dertil bruger PHP
punktum mellem elementerne:

(1) $url = $url_0.$currency.$url_1;

Sidst i løkken samler jeg valuta-elementerne op i en streng.
Det gøres med

(2) $kurser .= "$kurs,$dato,";

hvor jeg har variable indeni anførselstegn fordi de skal blandes
med almindelige tegn (her kommaer). Tegnet ".=" er en kortform
som du skal vænne dig til. (2) kunne også skrives på denne måde:

(2a) $kurser = $kurser."$kurs,$dato,";

Samme kortform kan bruges ved mange andre operatorer. Eksempler:

x+=5; //(x=x+5)
x*=8; // (x=x*8)
osv.

Denne linje:

(3) $kurser = trim($kurser,",");

er kosmetisk. Den fjerner det komma der ellers ville hænge
til sidst i linjen $kurser. trim() alene fjerner
for- og efterhængt whitespace.


Note:
Dine anførselstegn om $filename er uskadelige, men overflødige.
Et 'råt' variabelnavn virker (oversættes) altid alene. Kun hvis
det skal blandes med almindelige tegn bruger man anførselstegn.
Eksempel:

"Info gemmes i filen: $filename"

--
/Bertel

Bertel Lund Hansen

unread,
Sep 15, 2018, 9:00:44 AM9/15/18
to
Bertel Lund Hansen skrev:

Jeg lavede en svipser. $idag skal være kendt før urlerne kan
dannes. Korrekt rækkefølge:

// ---------------- Constants ----------------

> $currencies = array('USD', 'GBP', 'EUR', 'JPY', 'INR', 'AUD', 'RUB', 'CNY', 'HKD', 'MYR', 'SGD', 'TWD', 'DKK');
> $idag = date(Y-m-d);
> $url_0 = "https://apigw1.bot.or.th/bot/public/Stat-ExchangeRate/DAILY_AVG_EXG_RATE_V1/?currency=";
> $url_1 = "&start_period=$idag&end_period=$idag";

--
/Bertel

Jan Hansen

unread,
Sep 15, 2018, 9:33:30 AM9/15/18
to
15 Sep 2018 14:49:22 +0200 skrev Bertel Lund Hansen <gade...@lundhansen.dk>:

> (3) $kurser = trim($kurser,",");

Smart, den må jeg huske.

Martin Larsen

unread,
Sep 15, 2018, 5:54:08 PM9/15/18
to
Den 15-09-2018 kl. 14:39 skrev Jan Hansen:

> Men jeg foretrækker nu alligevel en ægte tekst, så jeg i en almindelig teksteditor
> kan se, hvad jeg har med at gøre

Fint nok til simple ting. Men kan ikke anbefales til mere komplicerede
sager.

Med en træstruktur-visning er det nu let nok at overskue JSON. Når man
er vant til det.

> Findes der en service på nettet, hvor man kan stoppe json ind i et felt, og skrive
> "mid_rate" i et andet felt, og så få serveret:
> $obj->result->data->data_detail[0]->mid_rate

Ikke mig bekendt, men det er sgu en god ide. Måske skulle jeg lave det.

Martin Larsen

unread,
Sep 15, 2018, 6:08:43 PM9/15/18
to
Den 15-09-2018 kl. 23:54 skrev Martin Larsen:

> Ikke mig bekendt, men det er sgu en god ide. Måske skulle jeg lave det.

Jeg fandt lige denne, som kan det næsten: https://jsonformatter.org/

Man kan efter formatering søge på mid_rate og får så dette output:

object ► result ► data ► data_detail ► 0 ► mid_rate

som let kan omsættes til

$obj -> result -> data -> data_detail[0] -> mid_rate



Kim Ludvigsen

unread,
Sep 16, 2018, 5:47:39 AM9/16/18
to
Den 15-09-2018 kl. 14:49 skrev Bertel Lund Hansen:
> Kim Ludvigsen skrev:
>
>>> Hvor mange valutaer snakker vi om?
>>
>> 13
>
> Okay, her er koden. Jeg har lagt kommentarlinjer ind for at
> opdele koden i logiske afsnit. Det gør jeg altid, og det er en
> god vane. Jeg har slået linjeopdeling fra i mit mailprogram
> så det leverer uendeligt lange linjer.

Tak for meget overskuelig kode og fin og forståelig forklaring!

Jeg er ved at prøve at ændre til brug af JSON i stedet for substr(),
hvilket har drillet lidt - Martins link til https://jsonformatter.org
hjalp dog med at få lavet det rigtige udtræk af "last_updated". Nu er
jeg til gengæld røget ind i en begrænsning på daglige forespørgsler på
serveren, så jeg er nødt til at vente til i morgen med at teste videre.

--
Mvh. Kim Ludvigsen

Jan Hansen

unread,
Sep 16, 2018, 9:07:16 AM9/16/18
to
Det hjælper selvfølgelig lidt på det, men det havde nu været smartere
hvis siden formatterede det nøjagtig som det skal stå i en php-fil.
Så havde det kunne bruges, uden forudgående studier af hvorfor
data_detail ► 0 bliver til data_detail[0] og ikke data_detail -> 0
når nu de andre "►" bliver til "->".
Det ideelle ville være en færdig funktion, så man kan skrive
echo 'Kursen er: '.cut_the_crap($response,'mid_rate');

Det ville gøre det lige så simpelt som at klippe den aktuelle kurs ud
af valutakurser.dk

Martin Larsen

unread,
Sep 16, 2018, 11:38:01 AM9/16/18
to
Den 16-09-2018 kl. 11:47 skrev Kim Ludvigsen:

> Nu er jeg til gengæld røget ind i en begrænsning på daglige
> forespørgsler på serveren,

Du skal cache kursen lokalt. Dvs. gem en kopi.

Træk kun friske data hvis kopien er mere end X antal timer gammel.

Martin Larsen

unread,
Sep 16, 2018, 12:11:35 PM9/16/18
to
Den 16-09-2018 kl. 15:07 skrev Jan Hansen:

> Det havde nu været smartere
> hvis siden formatterede det nøjagtig som det skal stå i en php-fil.

Ja, men hvad så med javascript, python, C, ruby osv?

Jeg har lige lavet denne bookmarklet til dig. Opret et bogmærke på
bogmærkelinjen, kald den hvad du vil, og smid denne kode ind i den:


javascript:var t = "$" +
$(".jsoneditor-treepath").text().replace(/►(\d+)/g,"[$1]").replace(/►/g,"->");
$(".jsoneditor-treepath").text(t);void(0);

Du kan også bare paste den ind i adresselinjen uden at lave en
bookmarklet, men vær opmærksom på at i hver fald Chrome fjerner
javascript når du paster.

Kopier derfor "avascript:var t = xxxx", sæt et j i adresselinjen og
indsæt så resten. Det virker!


Håber den er nyttig, det er den i hvert fald for mig selv.

Kim Ludvigsen

unread,
Sep 16, 2018, 12:18:28 PM9/16/18
to
Jeg skal kun hente én gang i døgnet med et cron-job, når det er oppe og
køre; resultatet gemmes i en lokal fil. Problemet med begrænsningen er,
at jeg var nødt til at hente en del gange for at prøve at få det til at
virke med JSON-koden, og så røg jeg over grænsen.

--
Mvh. Kim Ludvigsen

Jan Hansen

unread,
Sep 16, 2018, 2:40:06 PM9/16/18
to
Tak, men jeg kan nu ikke lige få det til at virke. Når jeg prøver at oprette et
bogmærke i firefox 50 bliver det til:
javascript:var%20t%20=%20"$"%20+%20%20$(".jsoneditor-treepath").text().replace(/%E2%96%BA(\d+)/g,"[$1]").replace(/%E2%96%BA/g,"->");%20%20$(".jsoneditor-treepath").text(t);void(0);

Men hvis det er en fast regel, at tal skal i [] og tekst bag ->
skulle det nok være til at finde ud af.

Jan Hansen

unread,
Sep 16, 2018, 3:08:46 PM9/16/18
to
Den Sun, 16 Sep 2018 18:18:25 +0200 skrev Kim Ludvigsen <k...@kimsside.dk>:

> Jeg skal kun hente én gang i døgnet med et cron-job, når det er oppe og
> køre; resultatet gemmes i en lokal fil. Problemet med begrænsningen er,
> at jeg var nødt til at hente en del gange for at prøve at få det til at
> virke med JSON-koden, og så røg jeg over grænsen.

Kom det så til at virke? Når jeg prøver med en lokal kopi af det json du
uploadede, kan jeg få det til at virke ved at udskifte
$kurs = floatval(substr($response,strpos($response,'mid_rate')+11));
$dato = substr($response,strpos($response,'last_updated')+15,10);
med
$obj=json_decode($response);
$kurs = $obj->result->data->data_detail[0]->mid_rate;
$dato = $obj->result->data->data_detail[0]->period;

Kim Ludvigsen

unread,
Sep 16, 2018, 4:09:18 PM9/16/18
to
Den 16-09-2018 kl. 21:08 skrev Jan Hansen:

> Kom det så til at virke? Når jeg prøver med en lokal kopi af det json du
> uploadede, kan jeg få det til at virke ved at udskifte
> $kurs = floatval(substr($response,strpos($response,'mid_rate')+11));
> $dato = substr($response,strpos($response,'last_updated')+15,10);
> med
> $obj=json_decode($response);
> $kurs = $obj->result->data->data_detail[0]->mid_rate;
> $dato = $obj->result->data->data_detail[0]->period;

Jeg endte med :
$obj = json_decode($response);
$kurs = $obj->result->data->data_detail[0]->mid_rate;
$dato = $obj->result->data->data_header->last_updated;

"period" er den dato, jeg forespørger på, så den har jeg allerede.

Jeg er nødt til at bruge last_updated, fordi den er den seneste kursdag.
Resultatet er tomt, hvis der ikke er en kurs for dags dato (fx i
forbindelse med helligdage), så jeg skal have lagt et tjek ind for, om
dags dato er forskellig fra last_updated, så jeg ikke risikerer, at den
seneste kurs overskrives med en tom værdi.

Jeg har endnu ikke fået prøvet det 100 procent af, fordi jeg røg over
grænsen. Jeg fik afprøvet forskellige dele, og de så ud til at virke.

--
Mvh. Kim Ludvigsen

Martin Larsen

unread,
Sep 17, 2018, 3:40:58 AM9/17/18
to
Den 16-09-2018 kl. 20:40 skrev Jan Hansen:

> Tak, men jeg kan nu ikke lige få det til at virke. Når jeg prøver at oprette et
> bogmærke i firefox 50 bliver det til:
> javascript:var%20t%20=%20"$"%20+%20%20$(".jsoneditor-treepath").text().replace(/%E2%96%BA(\d+)/g,"[$1]").replace(/%E2%96%BA/g,"->");%20%20$(".jsoneditor-treepath").text(t);void(0);

Hos mig bliver det i FF til

javascript:var t = "$" +
$(".jsoneditor-treepath").text().replace(/%E2%96%BA(\d+)/g,"[$1]").replace(/%E2%96%BA/g,"->");
$(".jsoneditor-treepath").text(t);void(0);

Men det virker perfekt alligevel. Har du prøvet?

Prøvede lige med din kode fra FF, og det virker også.

Bertel Lund Hansen

unread,
Sep 17, 2018, 3:42:22 AM9/17/18
to
Kim Ludvigsen skrev:

> Jeg har endnu ikke fået prøvet det 100 procent af, fordi jeg røg over
> grænsen. Jeg fik afprøvet forskellige dele, og de så ud til at virke.

Hvis du vil have hjælp til at gemme en lokal kopi som kun
opdateres én gang i døgnet, så sig til. Det vil muliggøre
uendeligt mange testkørsler - og så er det en god vane når man
henter data fra en ekstern server.

--
/Bertel

Jan Hansen

unread,
Sep 17, 2018, 4:54:45 AM9/17/18
to
Jeg fik nok set det forkerte sted i går, det virker perfekt nu. Når jeg
vælger tree og klikker på et element inde i træet, bliver stien på den grå
linie formatteret, når jeg klikker på bogmærket <https://imgur.com/voJpLyR>

Kim Ludvigsen

unread,
Sep 17, 2018, 7:22:48 AM9/17/18
to
Jeg havde ikke skænket det en tanke at gemme en lokal kopi af JSON'en
til test, før Jan nævnte det, og da var det for sent. Jeg vil huske det
til en anden gang.

Nu er jeg færdig med at teste, og alt virker tilsyneladende perfekt med
jeres kode til henholdsvis løkke og JSON.

Skønt, at man stadig kan få hjælp her i gruppen! En stor tak til Jan,
Bertel og Martin!

--
Mvh. Kim Ludvigsen
0 new messages