Jostain syystä kun lähetän html formista dataa PHP-koodille ja tekstikentät sisältää ' -merkkejä syntyy ongelmia. Yhdessä tekstikentässä näitä voi olla vaikka tsiljoona mutta jos toisessa kentässä on yksikin lisää tulee mysql herja. Olen kokeillut kiertää ongelmaa $_post[muttuja], mutta se ei tunnu auttavan kuin sen verran että yhdessä kentässä voi yläpilkkua olla. jotain jää taas vaihteeksi huomaamatta...
Ei huoh taas kerran.
Luehan vaikka Putkan omasta PHP-oppaasta, mitä SQL-injektio tarkoittaa.
Toitsu kirjoitti:
Olen kokeillut kiertää ongelmaa $_post[muttuja], mutta se ei tunnu auttavan kuin sen verran että yhdessä kentässä voi yläpilkkua olla. jotain jää taas vaihteeksi huomaamatta...
O' really? Ensinnäkään se ei ole "$_post" vaan "$_POST". PHP:ssä muuttujat ovat case-sensitive. Toisekseen sinun täytyy kääriä kaikki merkkijonoarvot hipsuihin ($_POST['muttuja']) tai muuten ne tulkitaan esimääritellyiksi vakioiksi.
Kyllä käytin uppercasena tuossa, mutta tähän tuli kirjoitettua pienillä. Annan tyhmyyteni paistaa vielä lisää! :D
En saa mitään formaattia käymään sql insertin kanssa:
$query = " INSERT INTO taulu (a, b, c) VALUES (($_POST['a']), ($_POST['b']), ($_POST['c'])) ":
Eihän tuon pitäisi mikään mahdottomuus olla? :S
Teet asiat väärin.
Jotain menee nyt todella väärin. Tarkastin käyttäjätunnuksen ja salasanan, ne on oikein. Voisikohan olla että webhotelli on blokannut pdo:n? Kuulosta aika kaukaa haetulta...
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[28000] [1045] Access denied for user 'XXXXX'@'10.0.x.xxx' (using password: YES)' in /var/www/fs1/3/public_html/nimi.php:353 Stack trace: #0 /var/www/fs1/3/public_html/nimi.php(353): PDO->__construct('mysql:host=loca...', 'XXXXX', 'XXXXXX') #1 {main} thrown in /var/www/fs1/3/public_html/nimi.php on line 353
Lisäys: Voisikohan tuossa olla kyse siitä, että mysql:n käyttäjä tunnuksessa että salasanassa on _ -merkki?
Miten olet aiemmin yhdistänyt tietokantaan?
Näin:
$server = "localhost"; $user = "XXXXX"; $pass = "XXXXX"; $db = "Kanta"; $link = mysql_connect( $server, $user, $pass ); mysql_select_db ( $db ) or die ( "no go!! $db: ".mysql_error() );
Eikö siis seuraava rivi todellakaan toimi?
$pdo = new PDO("mysql:host={$server};dbname={$db}", $user, $pass);
Eip. Tulee aimmin laittamani herja. Minun "vanhalla tavalla" kantayhteys aukeaa ilman herjoja....
Toitsu kirjoitti:
Näin:
$server = "localhost"; $user = "XXXXX"; $pass = "XXXXX"; $db = "Kanta"; $link = mysql_connect( $server, $user, $pass ); mysql_select_db ( $db ) or die ( "no go!! $db: ".mysql_error() );
Tämä on väärin eikä mysql_-funktioita saa enää käyttää. Lue vaikka PHP:n manuskasta. Nuo vanhat, antiikkiset funkkarit on tarkoitettu muinaiselle MySQL 4:lle eivätkä ne esim. tue vitosversion hienouksia. Sen lisäksi niiden käyttämisen on aivan hullua, koska turvallisen koodin kirjoittaminen on puhdasta helvettiä.
Kyllähän sitä siirtyisi tuohon PDO:n jos se sattuisi jotenkin edes toimimaan mutta kun ei ole oma palvelin kyseessä. Laitoin webhotelliin tiedustelun asiasta... Eipä tuo PDO kovin turvallista koodia ole kun yksi virhe ja heittää selkokielisenä passun ja käyttäjätunnuksen ruudulle.. :S
Et voi syyttää PDO:ta omista ohjelmointivirheistäsi, vaikka PHP:lle uskolliseen tyyliin PDO-luokan konstruktorin dokumentaatio onkin järkyttävän heikkolaatuista. Poikkeukset tulee tarpeen vaatiessa käsitellä try-catch-lohkoilla.
The Alchemist kirjoitti:
Et voi syyttää PDO:ta omista ohjelmointivirheistäsi
Kyllä muiden syyttäminen omista virheistä on ihan mahdollista. Itse asiassa, ei ainoastaan mahdollista, vaan jopa yleistä.
Eri asia sitten onko siinä järkeä.
Toisaalta en itsekään ihan ymmärrä PDO:n suunnittelupäätöstä sisällyttää parametrien arvot (myös salasana) virheilmoitukseen. Vaikka sitä ei näytettäisikään käyttäjälle, niin en tiedä onko sitä järkevää tallettaa lokiinkaan tai esim. lähettää sähköpostilla ylläpitäjälle.
En syytä PDO:ta omista virheistäni vaan PDO:n "ominaisuuksista". Kokeiles googlettaa aiheesta, saman on moni kokenut. Mikäli kanta ei hyväksy syystä tai toisesta kirjautumista tai se vastaa liian hitaasti, tuottaa PDO ruudulle virheilmoituksen, jossa on selkokielisenä käyttäjätunnus ja salasana. Tuosta yllä olevassa virheessä ne myös oli, joskin sensuroin ne siitä. Käsittääkseni PDO:ta voi myös käskeä olemaan tulostamatta virheitään mutta jälleen webhotellissa se ei ole perusasiakkaan ominaisuudessa aina mahdollista.
Toitsu kirjoitti:
tuottaa PDO ruudulle virheilmoituksen
PDO ei kylläkään päätä mihin virheilmoitukset tuotetaan. Eli se tulee ruudulle vain jos kehittäjä ja sivuston ylläpitäjä niin haluaa.
Yleisesti ottaen virheilmoituksia ei ole järkevää näyttää (ainakaan sellaisinaan) loppukäyttäjille. Mutta tietenkin koska PHP-ylläpitäjät keskimäärin on aika pihalla, niin PDO:n kehittäjien olisi kannattanut huomioida, että usein PHP:n virheilmoitukset on typerästi konffattu tulemaan loppukäyttäjän ruudulle.
Toitsu kirjoitti:
Käsittääkseni PDO:ta voi myös käskeä olemaan tulostamatta virheitään mutta jälleen webhotellissa se ei ole perusasiakkaan ominaisuudessa aina mahdollista.
Vaikka web-hotelli ei mahdollistaisikaan virheiden ohjaamsita lokiin (en tiedä onko sellaisia web-hotelleita oikeasti olemassa, itse en tiedä yhtään) niin voit ja sinun tulisikin silti käsitellä virhetilanteet ohjelmassasi, jolloin virheilmoitusta ei tulosteta (mihinkään) ellet niin käske.
Toitsu kirjoitti:
saman on moni kokenut
Moni ei siis ole vaivautunut tekemään minkäänlaista virheenkäsittelyä koodiinsa.
Minulle PDO on uusi juttu ja tuo koodi on täysin kesken joten mitään virheenkäsittelyä siinä ei ole vielä... :) Kunhan saan selville mistä virhe johtuu niin pääsen jatkamaan.
Virheilmoituksen voi helposti piilottaa, jos osaa vähän PHP:tä:
Geneerisemmin virheilmoituksia varten kannattaa määritellä omat virheenkäsittelijät funktioilla set_error_handler ja set_exception_handler.
Itse virheelle on vaikea arpoa mitään syytä, kun ongelma ei ole ennestään tuttu eikä ole tarkkaan tiedossa, millaisia asetuksia palvelimellasi on käytössä. Ideoita voi kuitenkin etsiä netistä. Itse kokeilisin ensin vaihtaa localhostin tilalle IP-osoitteen 127.0.0.1, ja sitten kokeilisin käyttää UNIX-sockettia eli antaa PDO:lle hostin sijaan parametrin unix_socket, jonka oikea arvo selviää tietokannasta kyselyllä SHOW VARIABLES LIKE 'socket'.
The Alchemist kirjoitti:
Et voi syyttää PDO:ta omista ohjelmointivirheistäsi, ...
Mikä ihmeen ongelma nyt iski? Itse en ainakaan näe tässä mitään selvää kysyjän ohjelmointivirhettä, vaan PDO:n alustus tehdään täysin loogisesti ja on hyvä syy odottaa, että se noin toimisikin. Poikkeuksen käsittely olisi varmasti tyylikästä, mutta se ei silti korjaa varsinaista vikaa.
PDO:n dokumentaation sijaan kannattaisi selvittää, onko palveluntarjoajalla mitään tietoa siitä, miten MySQL:ään pitää tuolla palvelimella yhdistää.
Tämäkin alkoi toimimaan hienosti! Kiitos kaikille avustaneille!
Aika päivittää omat tiedot käyttämään PDO:ta. Ongelma oli siinä, että kanta on eri palvelimella ja localhostin sijaan tarvittiin kantapalvelimen nimi. Vielä ei ole tiedossa miksi aikaisemmissa koodeissa toimii ns. vanhalla tavalla myös localhost. Localhost toimii edelleenkin vanhoissa koodeissani... :D Ilmoitan jos webhotelli osaa asiaa vielä valaista.
Ettet vain käyttäisi väärin noita mysql_-funkkareita. Mikäli et esim. anna mysql_query():lle joka kerta kahvaa tiettyyn yhteyteen, niin sovelletaan mustaa magiaa ja käytetty yhteys voi suurin piirtein olla ihan mikä tahansa.
Tällä pohjustan siis väitettäni siitä, että olet yrittänyt avata yhteyden localhostiin, joka on sitten failannut, jonka jälkeen mysql_query():ä kutsuessa PHP on omin lupineen avannut taustalla toisen yhteyden käyttäjällesi.
Et ainakaan tuossa aiemmin quottaamassani koodissa edes tarkista, onnistuiko yhteyden avaaminen.
Toisaalta kyse voi olla jostain uudelleenohjaukseen liittyvästä ongelmasta vaikka PDO:n päässä, kun katsoin jo aiemmin tuota virheilmoitusta, kun se valitti IP:stä 10.0.xxx.xxx vaikka yhdistit localhostiin joka on useimmiten sama kuin 127.0.0.1.
Tässä väitteesi pohja pois, webhotelli vastaa:
"Järjestelmässämme on tehty erikseen pieni ohjaus mysql_connect:lle ja localhost:n käytölle. "
Yhteyden avauksen tarkistusta olen käyttänyt sekä suljen aina yhteyden sen käytön jälkeen, kaikkea "vanhaa" ei vain ole syytä laittaa tänne. Se että käytänkö niitä oikein vai väärin.. Voi hyvin olla että käytän väärin mutta ainakin ne on toimineet moitteetta tähän päivään asti. :)
Nim. PHP:tä harrasteena vuodesta 2001 alkaen, enkä varmasti osaa vielä paljon mitään! :)
Olen minäkin koodannut PHP:llä pääkielenäni vuodesta 2004 asti, mutta rehellinen tunnustukseni on se, etten ole tajunnut siitä yhtään mitään ennen kuin vasta viimeisen vuoden, parin aikana. Pelkkä PHP:n kirjoittaminen ei opeta yhtään mitään, vaan järkevien käytäntöjen oppiminen vaatii muuallekin katselemista. Minua oikeasti harmittaa, että pysyttelin omissa piireissäni niin pitkään ja menetin niin paljon aikaa oppia.
PDO:sta kuuleminen vasta 11 vuoden vuoden jälkeen ei ainakaan minussa herätä luottamusta. (No ok, PDO bundlattiin PHP:n mukaan vasta vuonna 2005...)
Ainakin heittoni mustasta magiasta meni ihan nappiin joskin vähän eri syistä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.