Hiukan outo ongelma on minulla. Olen tekemässä ohjelmaa, jossa tarvitsee listata tietokannasta paljon tietoja.
Rupesin 'yksinkertaistamaan' skriptiä niin se tuli siitä mutkasemmaksi.
Otetaan tähän esimerkki. Tässä loopissa tehdään arrayn rakenne valmiiksi myöhempää silmukkaa varten.
Tämä stringin tulostus tulostaa oikein kaikki 16 riviä:
foreach($query->rows as $order2){ echo 'rivillä 227: ' . $order2['order_id'] . ' : ' . $order2['iso_code_3'];
Kun lisätään toinen testi samaan silmukkaan, ohjelma tulostaa sekä näyttää arrayssa vain neljän rivin tiedot:
echo 'rivillä 246 ' . $order2['order_id'] . ' : ' .$order2['iso_code_3'] . '<br>'; print_r($order2);
Tämä aiheuttaa sen, että myöskään tuossa rivillä 227 ei tulosteta enää kuin neljä riviä.
Jos piilotan tuon print_r funktion kommenttimerkein, listaa taas kaikki 16 riviä. Tosin käytännössä tuossa silmukassa ei tarvitse mitään sen kaltaista tulostaa mutta ihmetyttää aika lailla.
Toinen ongelma.
Kolme riviä alempana aloitetaan uusi silmukka, joka varsinaisesti käsittelee tietokannan tietoja, on vielä omituisempi.
Sen silmukan alussa se löytää tietokannan tulosteesta vain yhden rivin.
Tämä on jo iso ongelma. Mysqli on löytänyt tietokannasta kaikki 16 riviä, mutta jostakin syystä tässä on jarru päällä.
Laitatko vielä esille käyttämäsi SQL-lauseet. Lisäksi kannassa kyselyn kannalta olennaisien taulujen määrittely saattaa olla tarpeen.
Print_r:ssä pitää käyttää toista parametriä, jos se on esim. echossa mukana.
Eli
echo print_r($foo, true);
Itseä myös kiinnostaa nuo sql-lauseet, sillä nyt tämä taas tuntuu siltä, että oletat virheen olevan jossain muualla kuin missä se oikeasti on.
Kyseessä voi olla perinteinen XSS-aukko, eli nyt tulostat tiedot ilman käsittelyä ja jokin html-tagi (tai edes <-merkki) katkaisee html-sivulla näkyvän tulosteen. Eli jälleen kerran: muista käsitellä htmlspecialchars-funktiolla kaikki tulostettava ja tarkasta myös sivun lähdekoodi.
Voit myös lisätä tulostukseen laskurin:
Kyllä tämän SQL lauseet on toiminut ennen tätä kun rupesin muuttelemaan muita skriptin ominaisuukisa.
Muuttuajssa $where on seuraava pitkä rimpsu
o.order_status_id='5' AND o.payment_code = 'my_bank' AND YEAR(o.date_added) = '2020' AND DAYOFYEAR(o.date_added) >= '90' AND DAYOFYEAR(o.date_added) <= '180'
Tuossa olen muuttanut tähän esimerkkiin nimen 'my_bank'. Skripti jatkuu tuosta OR funktion jälkeen samanlaisena, paitsi että etsii myös order status id:n 1 ja 11. Olen tarkistanut, niin kaikki nämä vaihtoehdot löytyy tietokannasta. Ennen sitä on aika lyhyesti:
FROM `oc_order` AS o LEFT JOIN oc_country` AS c ON(o.payment_country_id = c.country_id) WHERE
Epäilen, että jokin muu skripti on minulla siinä joka tökkää, vaikka ei ilmoita virhettä.
Näiden kahden silmukan välissä on tämä:
$pvm = $this->getDay($year); $month = $this->getMonth($month);
Tosin näin äkkiseltään näin tutkimatta en osaa uskoa, että näissä olisi vikaa. Ne nimittäin lisää ainoastaan nollan tarviitaessa eteen, esim. huhtikuuu tulostuu 04 eikä 4.
Yksi vika löytyi. En tiedä vaikuttaako tuohon, miten testitulostus toimisi tuossa silmukan alussa.
Metodissa getEU oli tällainen rivi:
$tulos = $this->request;
En saanut koko aikana tuota julkista muuttujaa toimimaan ja se herjasi kun yritti käyttää array_key_exists funktiota siihen, löytyykö maatunnusta EU-maalistasta.
En ole tehnyt uutta tulostustestiä, mutta nyt toimii ja tallentaa halutut tiedot pdf-tiedostoon.
Minkä OR funktion?
Tämä poju ei taida lukea muiden viestejä ollenkaan, kunhan örveltää ketjussa omia sekavia "tutkimustuloksiaan". Oma arvaukseni on sama kuin Metabolixilla, eli jossain tietokannan kentässä on tallennettuna HTML:ää, ja kun koko tietue tulostetaan print_r-kutsulla, niin tulostettu, mahdollisesti viallinen HTML peittää myöhemmin tulostetut tietueet näkyvistä. Ongelma on helppo todeta katsomalla tuotetun HTML-dokumentin lähdekoodia renderöidyn sivun sijaan.
pistemies kirjoitti:
Yksi vika löytyi. En tiedä vaikuttaako tuohon, miten testitulostus toimisi tuossa silmukan alussa.
Miksi et tiedä? Miten voit edes sanoa tuollaista, kun sinä olet se ohjelmoija, joka koodin tekee. Sinun kuuluu tietää, miten kieli käyttäytyy.
Minusta on moraalisesti arveluttavaa, että täällä foorumilla ratkotaan sinun laiskuudestasi johtuvia alkeellisia ohjelmointivirheitä, jotka ymmärtääkseni liittyvät asiakasprojekteihin, joiden tekemisestä sinulle maksetaan, vaikka olet pihalla kuin lumiukko.
The Alchemist kirjoitti:
Tämä poju ei taida lukea muiden viestejä ollenkaan,
Veikkaampa, että et sinäkään kauhean intensiivisesti minun viestejä ole lukenut ;)
Kuten kirjoitin, homma toimi kuin rasvattu ennen kuin aloin säheltämään ja yritin saada yksinkertaistettua luokan rakennetta.( Tuo request julkinen muuttuja oli yksi siihen liittyvä homma)
The Alchemist kirjoitti:
Ongelma on helppo todeta katsomalla tuotetun HTML-dokumentin lähdekoodia renderöidyn sivun sijaan.
Tietokannan sisältö on selvillä. Siellä ei ole yhtään HTML-koodia.Jos joku yrittää html-koodia, se enkoodataan ennen tallennsuta.
Kerroin myös että echo funktiolla tulostettuna tietokannan tulostamasta arraysta löytyi vain yksi rivi.
The Alchemist kirjoitti:
Miksi et tiedä? Miten voit edes sanoa tuollaista, kun sinä olet se ohjelmoija, joka koodin tekee. Sinun kuuluu tietää, miten kieli käyttäytyy.
En ollut testannut. Nyt testasin sitä jälkimmäistä, joissa tulostetaan order_id, löytyy kaikki rivit.
pistemies kirjoitti:
Veikkaampa, että et sinäkään kauhean intensiivisesti minun viestejä ole lukenut
No eipä niitä kannata kovin intensiivisesti lukea, kun niistä jo suoraan paistaa päälle että todennäköisesti ongelman kannalta olennaisia asioita ei ole kerrottu.
Sinulla on siellä se tietokanta ja koodi, jolla ongelma esiintyy ja on toistettavissa. Koko koodia todellista tietokantaa vasten ajamalla ja debug-työkaluja käyttämällä olisi osaavan tekijän aivan triviaalia selvittää ongelma. Mutta sitten, kun sieltä täältä poimii pari pätkää koodia jotka väitetysti toimivat epäloogisesti, niin parhaankin kristallipallon omistava guru joutuu jossain määrin arvailemaan missä vika voisi olla.
Itse en toistaiseksi annetuilla tiedoilla arvaile muuta, kuin että ongelma ei ole "arrayn toiminnassa".
pistemies kirjoitti:
Kuten kirjoitin, homma toimi kuin rasvattu ennen kuin aloin säheltämään ja yritin saada yksinkertaistettua luokan rakennetta.
Tähän toimisi ehkä sellainen neuvo että kun et kerran osaa, niin älä koske sellaiseen joka toimii.
pistemies kirjoitti:
Tietokannan sisältö on selvillä. Siellä ei ole yhtään HTML-koodia.Jos joku yrittää html-koodia, se enkoodataan ennen tallennsuta.
Antamillasi lähtötiedoilla arvaus oli ihan perusteltu. Eikä sitäkään kukaan olisi voinut arvata, että koodisi tekee enkoodailuita epäloogisessa paikassa.
Yleisellä tasolla tässä voisi ehdottaa myös sellaista toimintatapaa, että koodi olisi versionhallinnassa ja siihen tehtäisiin pieniä muutoksia ja kaikki muutokset testattaisiin, jolloin vika huomattaisiin ajoissa ja olisi helppo palata vanhaan versioon.
Itse ongelmasta nyt tosiaan ei pysty esittämään enempää järkeviä arvauksia. Jos $query->rows on tavallinen taulukko ja sisältää 16 riviä (helppo tarkastaa vaikka countilla), niin ne rivit eivät sieltä itsestään vähene mihinkään, joten vika on jossain ihan muualla kuin nyt esitetyillä koodiriveillä.
Metabolix kirjoitti:
(23.05.2020 18:19:53): Yleisellä tasolla tässä voisi ehdottaa myös...
Kiitos huomioista. Yhden asian tästä ainakin opin. Jos haluaa tehdä suurehkon muutoksen, kannattaa ensin tehdä varmuuskopio tiedostosta.
Mutta tässä ehkä hiukan yllättäen löysin pääasaillisen syyn testailemalla, laittamalla silmukassa olevia skriptejä kommrnttien sisään
Tuolla ekaviestissä mainitaan toisen silmukan alku:
foreach($query->rows as $order){
Silmukan alaosassa olin käyttänyt tämäntapaista riviä
$results['refunded'][$order['order_id']] = $order;
Jostakin syystä tämä rivi alkoi tökkimään. Koska se luetaan silmukassa joka rivillä, homma pysähtyi ekariviin.
Muutin siihen tavallisen arrayn, joka yksilöi tuossa $order muuttujassa olevat tiedot.
Tämä taitaa nyt olla toinen kerta putkeen, kun postaat – – ja myöhemmin kerrot, että se koodi olikin eri koodi kuin missä ongelma oikeasti oli.
Moderoitu!
pistemies kirjoitti:
The Alchemist kirjoitti:
Miksi et tiedä? Miten voit edes sanoa tuollaista, kun sinä olet se ohjelmoija, joka koodin tekee. Sinun kuuluu tietää, miten kieli käyttäytyy.
En ollut testannut. Nyt testasin sitä jälkimmäistä, joissa tulostetaan order_id, löytyy kaikki rivit.
Tarkoitin sitä että tässä puhutaan ohjelmointikielen perusominaisuuksista. Sinun tulee tietää kokeilemattakin, ettei tekstin tulostaminen vaikuta siihen, miten silmukka toimii.
Moderoitu!
The Alchemist kirjoitti:
Moderoitu!
Tämän tyyliset henkilökohtaisuuksiin menevät viestit eivät mielestäni kuulu tälle foorumille! Yritetään pitää keskustelu siistinä, kiitos!
Mod. huom: Yritetäänpä tosiaan pidättäytyä henkilökohtaisista haukuista ja liiasta kiroilusta.
Kysymys on silti aiheellinen: Käsitteleekö tämä koodi tosiaan raha-asioita ja myydäänkö tätä koodia asiakkaille? Kun koodia muokataan ilman varmuuskopioita ja yksinkertaiset silmukat menevät pieleen, vaikuttaa todennäköiseltä, että koodissa on myös vaikeammin havaittavia ja vaarallisempia bugeja. Jos yhtä huolestuttava meno jatkuu, voidaan asiallisesti ja henkilöä haukkumatta kysyä myös, liittyykö koodi erääseen nimeltä ja osoitteelta tunnistettavaan verkkokauppaan. Asiakkailla on oikeus löytää hakukoneella tietoa siitä, mitä ovat ostamassa.
Metabolix kirjoitti:
Jos yhtä huolestuttava meno jatkuu, voidaan asiallisesti ja henkilöä haukkumatta kysyä myös, liittyykö koodi erääseen nimeltä ja osoitteelta tunnistettavaan verkkokauppaan. Asiakkailla on oikeus löytää hakukoneella tietoa siitä, mitä ovat ostamassa.
Keskeneräinen projekti voi tosiaan katsojan silmin näyttää huolestuttavalta ;)
Tällaisena keskeneräisenä se ei liitty mihinkään verkkokauppaan.
Tämä vaan vähän kertoo, miten työlästä näiden ohjelmien teko tässä iässä voi olla ;)
pistemies kirjoitti:
Tämä vaan vähän kertoo, miten työlästä näiden ohjelmien teko tässä iässä voi olla ;)
Minusta se kertoo vaan siitä että ei vaivaudu käyttämään tehokkaita työtapoja. Ei se iästä ole kiinni, jos asioista tekee vaikeita.
Minusta ensimmäinen asia mitä kannattaisi tehdä, olisi opetella käyttämään debug-työaluja. Tällöin ei tarvitse lisäiläl tulostuskoodeja sinne ja tänne, kun voi vaan sanoa esim. että haluaa suorituksen keskeytyvän tietyllä rivillä ja voi tarkistaa muuttujien senhetkiset arvot tai vaikka edetä siitä rivi kerrallaan ja katsoa mitä oikeasti tapahtuu.
Sitten jos ei ongelma selviä tuolla keinolla ja pitää lähteä vaikkapa nyt keskustelufoorumilta kysymään apua, niin kannattaa tehdä tiivis esimerkkikoodi, jolla ongelma toistuu. Eli koodin tulisi olla sellaisenaan ajettavissa ilman esimerkiksi tietokantariippuvuuksia.
Yhdeksässä kymmenestä tapauksesta ongelma selviää jo tuota tiivistettyä koodiesimerkkiä laatiessa. Ja jos ei selviä niin sitten ainakin muut pystyvät selvittävämään ongelmaa.
Aihe on jo aika vanha, joten et voi enää vastata siihen.