Avatar billede KFJ1972 Juniormester
29. januar 2011 - 01:37 Der er 11 kommentarer og
1 løsning

Problemer med købt script og ingen reaktion fra programmør efter betaling

Hejsa,

Jeg har købt og betalt for et script som indhenter en bestemt valuta-kurs fra National-banken XML-feed. Da scriptet kørte helt efter hensigten på hverdage, så betalte jeg for arbejdet og opdagede først bagefter at scriptet ikke tager højde for dage i weekenden og andre helligdage hvor Nationalbanken ikke kommer med en ny kurs i deres XML-feed. Programmøren hører jeg selvfølgelig intet til mere, efter han har fået sin betaling - derfor prøver jeg nu herinde.

Jeg har sporet problemet til følgende del af koden:

class updateclass {

    private $db;

    private $xmldoc;

    private $date;

    private $currency = array();

    public function __construct($db, $url) {
        $this->db = $db;
        $this->xmldoc = new SimpleXMLElement($url, NULL, TRUE);

        $date = $this->xmldoc->children()->attributes();

        $this->date = $date["id"];

        foreach($this->xmldoc->dailyrates->currency as $value) {
            $this->currency[(string) $value["code"]] = number_format((float) $this->replaceComma($value["rate"]),2);
        }

        $this->updateDB();
    }

    private function updateDB() {
        $sql = "SELECT id FROM exchangerates WHERE date=?";
        $stmt = $this->db->prepare($sql);

        $stmt->bind_param("s",$this->date);
        $stmt->execute();
        $stmt->store_result();

        if($stmt->num_rows == 0) {
            $stmt->close();
           
            $sql = "INSERT INTO exchangerates(date,rate) VALUES(?,?)";
            $stmt = $this->db->prepare($sql);

            $sql = "SELECT rate,date FROM exchangerates ORDER BY date DESC LIMIT 1";
            $last = $this->db->query($sql);

            if($last->num_rows > 0) {
                $fetched = $last->fetch_row();
                $old_rate = $fetched[0];
                $old_date = new Datetime($fetched[1]);

                if($rate == 0) {
                    $rate = $old_rate;
                }

                $date = new Datetime($this->date);

                $mk_date = mktime(0,0,0,$date->format("m"),$date->format("d"),$date->format("Y"));
                $mk_odate = mktime(0,0,0, $old_date->format("m"), $old_date->format("d"), $old_date->format("Y"));
                $date_diff = $mk_date - $mk_odate;
                $diff_str = floor($date_diff/(60*60*24))-1;

                if($diff_str > 0) {
                    for($i=0;$i<$diff_str;$i++) {
                        $new_date = date("Y-m-d",strtotime(date("Y-m-d", strtotime($old_date->format("Y-m-d"))) . " +" . ($i+1) . " day"));
                        $stmt->bind_param("sd", $new_date, $old_rate);
                        $stmt->execute();
                    }
                }
            }

            $stmt->bind_param("sd", $this->date, $this->currency["THB"]);
            $stmt->execute();
        }
    }

    private function replaceComma($str) {
        return str_replace(",",".",$str);
    }
}

Det jeg ønsker er at scriptet tilføjer dags dato (i weekenden og på helligdage) med den sidst opdateret kurs (det vil almindeligvis sige fredagens kurs).

Linket til Nationalbankens feed er http://www.nationalbanken.dk/dndk/valuta.nsf/valuta.xml hvis det skal bruges.

Håber på at en eller anden skarp hjerne herinde kan hjælpe mig da jeg er helt på herrens mark.

På forhånd tusind tak.
Avatar billede Red0z Nybegynder
29. januar 2011 - 05:04 #1
Nu har jeg ikke rigtig rodet ved PHP, men ! jeg vil da tro der skal indsættes en dato.
Du kan prøve at indsætte en Dato dér og se om den reagere anderledes. :)

private function updateDB() {
        $sql = "SELECT id FROM exchangerates WHERE date=--->>?<<---";
        $stmt = $this->db->prepare($sql);

        $stmt->bind_param("s",$this->date);
        $stmt->execute();
        $stmt->store_result();
Avatar billede Red0z Nybegynder
29. januar 2011 - 05:15 #2
Derudover er der også 2 spørgsmålstegn i nedenstående stykke
$sql = "INSERT INTO exchangerates(date,rate) VALUES(?,?)

Så tror din programmør ikke har vidst hvilken dato og hvilke værdier der skulle indsættes måske . :)

Sidder og benytter Steam's browser lige nu, så kan desværre ikke åbne .xml dokumentet :)

if($stmt->num_rows == 0) {
            $stmt->close();
           
            $sql = "INSERT INTO exchangerates(date,rate) VALUES(?,?)";
            $stmt = $this->db->prepare($sql);

            $sql = "SELECT rate,date FROM exchangerates ORDER BY date DESC LIMIT 1";
            $last = $this->db->query($sql);

            if($last->num_rows > 0) {
                $fetched = $last->fetch_row();
                $old_rate = $fetched[0];
                $old_date = new Datetime($fetched[1]);

                if($rate == 0) {
                    $rate = $old_rate;
                }
Avatar billede michael_stim Ekspert
29. januar 2011 - 08:59 #3
Der er ingen fejl der ;o) Det er prepared statement. Tror nu udvikleren har gjort sit arbejde efter bogen, problemet har nok snarere været en ufuldstændig kravspecifikation (SRS).
Avatar billede KFJ1972 Juniormester
29. januar 2011 - 10:21 #4
XML-feedet f.eks. idag ser sådan her ud:


<?xml version="1.0" encoding="ISO-8859-1"?>

<exchangerates type="Valutakurser" author="Danmarks Nationalbank" refcur="DKK" refamt="1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<dailyrates id="2011-01-28">

<currency code="EUR" desc="Euro" rate="745,40" />

<currency code="USD" desc="Amerikanske dollars" rate="543,69" />

<currency code="GBP" desc="Britiske pund" rate="865,84" />

<currency code="SEK" desc="Svenske kroner" rate="84,20" />

<currency code="NOK" desc="Norske kroner" rate="93,96" />

<currency code="ISK" desc="Islandske kroner" rate="-" />

<currency code="CHF" desc="Schweiziske franc" rate="575,95" />

<currency code="CAD" desc="Canadiske dollars" rate="546,32" />

<currency code="JPY" desc="Japanske yen" rate="6,6105" />

<currency code="AUD" desc="Australske dollars" rate="542,07" />

<currency code="NZD" desc="New Zealandske dollars" rate="422,49" />

<currency code="LVL" desc="Lettiske lats" rate="1.057,45" />

<currency code="LTL" desc="Litauiske litas" rate="215,88" />

<currency code="PLN" desc="Polske zloty" rate="190,34" />

<currency code="CZK" desc="Tjekkiske koruna" rate="30,74" />

<currency code="HUF" desc="Ungarske forint" rate="2,743" />

<currency code="HKD" desc="Hongkong dollars" rate="69,81" />

<currency code="SGD" desc="Singapore dollars" rate="424,92" />

<currency code="ZAR" desc="Sydafrikanske rand" rate="76,54" />

<currency code="BGN" desc="Bulgarske lev" rate="381,12" />

<currency code="RON" desc="Rumænske lei" rate="175,08" />

<currency code="TRY" desc="Tyrkiske lira" rate="341,00" />

<currency code="KRW" desc="Sydkoreanske won" rate="0,4879" />

<currency code="HRK" desc="Kroatiske kuna" rate="100,42" />

<currency code="RUB" desc="Russiske rubel" rate="18,31" />

<currency code="THB" desc="Thailandske baht" rate="17,53" />

<currency code="MYR" desc="Malaysiske ringgit" rate="178,00" />

<currency code="PHP" desc="Filippinske peso" rate="12,33" />

<currency code="IDR" desc="Indonesiske rupiah" rate="0,0602" />

<currency code="CNY" desc="Kinesiske Yuan renminbi" rate="82,43" />

<currency code="BRL" desc="Brasilianske real" rate="324,34" />

<currency code="MXN" desc="Mexikanske peso" rate="45,15" />

<currency code="INR" desc="Indiske rupee" rate="11,88" />

<currency code="ILS" desc="Israelske shekel" rate="148,05" />

<currency code="SDR" desc="Special Drawing Rights" rate="850,23" />

</dailyrates>

</exchangerates>
Avatar billede KFJ1972 Juniormester
29. januar 2011 - 10:49 #5
<dailyrates id="2011-01-28"> og <currency code="THB" desc="Thailandske baht" rate="17,53" /> skulle være de interessante informationer i feedet.

Problemet her i dag den 29. er at datoen i feedet stadigvæk er angivet til den sidste hverdag.

Så tænkte på om man kunne gøre sådan at dags dato i stedet blev taget fra serveren og kursen fra feedet. Umiddelbart ville jeg tro at det så ville kunne til at passe i databasen med en dato og kurs for alle dage året rundt.

Det er desværre ikke muligt i det script som fremviser en graf over kurs-udviklingen at springe dage over da scriptet behøver en information for hver enkelt dag.

Jeg har desværre ikke selv viden nok til at lave en sådan tilretning af koden. Og måske er den hellere ikke ligefrem den smarteste måde at løse problemet på - sandsynligvis er der nogle herinde som har en langt bedre idé til at løse problemet.
Avatar billede webweaver Praktikant
29. januar 2011 - 11:42 #6
Hvad viser den så, når det er weekend? Bare ingenting eller?
Der kunne måske laves noget med at checke for om det er lørdag, og hvis det er, trække 1 fra i dato'en, så vi havner på fredag. Hvis det er søndag, så trække 2 fra ...

Men det vil være et problem med helligdage, da de både kan variere i længden og placering i ugen.
Avatar billede KFJ1972 Juniormester
29. januar 2011 - 11:48 #7
Ja Nationalbanken opdatere ikke i weekenden. Så feedet forbliver bare som det var om fredagen - med fredagens dato.

Ja, jul, nytår, påske osv er nok endnu mere drilske end almindelig lør/søn-dage.
29. januar 2011 - 13:49 #8
Lad mig se om jeg forstaar problemstillingen. 

(1)  Du har et script der tegner graf over kursudviklingen i thailandske bath fra dato og kurs vaerdier der er opslaet i database tabellen 'exchangerates'.

(2)  Vaerdierne i 'exchangerates' bliver indsamlet fra Nationalbankens feed ved hjaelp af den kode du viser i traaden. 

(3)  Problemet er saa at scriptet der tegner graf er skrevet saaledes at der kraeves dato og kurs vaerdier for hver kalenderdag hvorimod koden der in indsamler dataerne er skrevet saaledes at den springer ikke-arbejdsdage over.

(4)  Der er saa i princippet to loesninger, (a) tilpasse graf-scriptet saa der kun tegnes graf for arbejdsdage, og (b) tilpasse koden du viser saa der indfoeres vaerdier i databasen for hver kalenderdag.  Dit indlaeg tyder paa at du vil fastholde en graf for alle kalenderdage (selv om der ikke sker kursudvikling paa weekend/helligdage.)

(5)  I saa fald, givet at du koerer koden hver dag, maa du (som du selv er inde paa) bruge serverens dato hvis den er stoerre (senere) end feed datoen.  Det foelgende forslag har jeg ikke mulighed for at teste, men det burde virke.  (a) Indsaet en ekstra variabel, $today, i class'en, (b) test om denne er stoerre end feed datoen ($date i den niende linie i koden) og i saafald (c) saet this->date = this->today i stedet for this->date = $date["id"].  De foerste linier i koden skal saa erstattes med dette:

class updateclass
{
    private $db;
    private $xmldoc;
    private $today;
    private $date;
    private $currency = array();
    public function __construct($db, $url)
    {
        $this->db = $db;
        $this->xmldoc = new SimpleXMLElement($url, NULL, TRUE);
        $this->today = date("Y-m-d");
        $date = $this->xmldoc->children()->attributes();
        $this->date = (this->today > $date["id"])? this->today : $date["id"];
        foreach($this->xmldoc->dailyrates->currency as $value) $this->currency[(string) $value["code"]] = number_format((float) $this->replaceComma($value["rate"]),2);
        $this->updateDB();
    }

Jeg haaber jeg har forstaaet dig rigtigt og at dette er til nytte.
Avatar billede KFJ1972 Juniormester
29. januar 2011 - 14:16 #9
Hejsa Christian,

Det er helt korrekt forstået af dig :-)

Jeg har lige prøvet og får en fejl i denne linie:
$this->date = (this->today > $date["id"])? this->today : $date["id"];

Fejlen er:
Parse error: syntax error, unexpected T_OBJECT_OPERATOR in /home/sitea/public_html/valutakurser/app/update.class.php on line 26

Har prøvet at kigge på koden i linien, men kan ikke lige gennemskue problemet.
29. januar 2011 - 15:24 #10
Maaske er mit udtryk for kompakt for denne sammenhaeng.  Proev om det gaar bedre paa denne maade:

class updateclass
{
    private $db;
    private $xmldoc;
    private $today;
    private $date;
    private $currency = array();
    public function __construct($db, $url)
    {
    public function __construct($db, $url)
    {
        $this->db = $db;
        $this->xmldoc = new SimpleXMLElement($url, NULL, TRUE);
        $this->today = date("Y-m-d");
        $date = $this->xmldoc->children()->attributes();
        $this->date = $date["id"];
        if($this->today > $this->date) $this->date = $this->today;
        .....
Avatar billede KFJ1972 Juniormester
29. januar 2011 - 15:55 #11
Fik stadigvæk en fejl. Denne gang følgende fejl: Parse error: syntax error, unexpected T_PUBLIC in /home/sitea/public_html/valutakurser/app/update.class.php on line 21

Linie 21/22 er:
    public function __construct($db, $url)
    {

Samme står der i øvrigt i linie 19/20.

Jeg søgte lidt på hvad unexpected T_PUBLIC betød og fandt noget med en uafsluttet { men dem kan jeg ikke se nogle af i koden - de ser lukket ud allesammen. Andre resultater på Google nævnte noget om at man prøvede at afvikle PHP5-kode på PHP4. Min server har PHP Version 5.2.9 - så burde hellere ikke være det.

Jeg prøvede så at fjerne lidt i koden så det ser sådan her ud:

class updateclass
{
    private $db;
    private $xmldoc;
    private $today;
    private $date;
    private $currency = array();
    public function __construct($db, $url)
    {

        $this->db = $db;
        $this->xmldoc = new SimpleXMLElement($url, NULL, TRUE);
        $this->today = date("Y-m-d");
        $date = $this->xmldoc->children()->attributes();
        $this->date = $date["id"];
        if($this->today > $this->date) $this->date = $this->today;
       
        foreach($this->xmldoc->dailyrates->currency as $value) $this->currency[(string) $value["code"]] = number_format((float) $this->replaceComma($value["rate"]),2);
        $this->updateDB();
    }

Efterfølgende kørte jeg koden og det ser ud til at den nu har lagt fredagens kurs ind på idag lørdag både på siden i grafen og i databasen (har checket via phpmyadmin).

Så jeg vil tro at problemet nu er løst :-)

Jeg vil derfor gerne takke jer alle og ønske jer en fortsat rigtig god weekend :-)
Mange tak allesammen. Jeg er meget taknemmelig over den gode hjælp jeg har fået herinde.

Christian, du må meget gerne lige poste et svar.
29. januar 2011 - 16:19 #12
Svar fra mig.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester