Moro onko jotain muttunut nyt parissa vuodessa?
En saa toimimaan enään samallalailla kuin ennen.
Eli nettisivujen rakenne
konffi.php, jossa tietokannan avaukset ja tiedot sekä include functiot.php.
functiot.php on erillinen php tiedosto jossa yleisimmät functiot joita käytetään monella sivulla
sisältösivulla siis pelkästää include konffi.php
ja tietokanta yhteydet toimivat, mutta jos käytän sisältö sivulta jotain functiota(erilliseltä functiot.php:ltä) jossa on tietokanta kysely niin se ei toimikkaan vaan tulee
Call to a member function query() on a non-object in
mistäs tämä johtuu? minusta tälleen on ennen toiminut?
Mitä minun täytyy functiossa esitellä? pälkkä global dbh; ei auta
ei viitsisi tuota kannanyhteyden avausta tehä monessa paikkaa.
ymmärsiköhän kukaan?
Kyllä global auttaa, jos se tietokantamuuttujasi on globaali. Eli ilmeisesti se ei ole globaali tai olet mokaillut jotain muuta.
Joka tapauksessa globaalia muuttujaa tyylikkäämpi ratkaisu on avata yhteys jossain funktiossa näin:
Sitten voi aina käyttää tuota funktiota ilman mitään kikkailuja:
$q = db()->prepare("SELECT * FROM taulu");
laitettiinkos se nykyään jotenkin erikseen globaaliksi?
täytyypä kokeilla noita sinun tapoja. Kiitos paljon!
Ei ole globaaleissa tapahtunut mitään muutosta.
Ei tämä nyt onnistu.
konffi.php
include('koodi/funktiot.php'); $palvelin = 'localhost'; $tietokanta='tkanta'; $tunnus='tunnus'; $salasana='ssana'; $dbh = new PDO("mysql:host=$palvelin;dbname=$tietokanta", $tunnus, $salasana,array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
Sisältö.php
include('konffi.php'); $versio=haerivi('SELECT versio FROM versio ORDER BY id DESC LIMIT 1;')
functiot.php
function haerivi($lause){ public $dbh; $haku = $dbh->query($lause); $kanta = $haku->fetch(PDO::FETCH_ASSOC); return $kanta; }
virhe:
PHP Fatal error: Call to a member function query() on a non-object in funktiot.php on line 9
Olenko minä ihan alunperinki väärin tämän tehnyt.. Näin se aikaisemmin on toiminut..
Pitäisikö uudistaa kokonaan tämä kannan käsittely. Tavoitteena on kuitenkin tuo sisältö sivu pitää mahdollisimman "siistinä"
Näin tämä ennen on toiminu.. Voisitko vääntää vähän rautalankaa mitä tuonne function sisään pitää laittaa?
creepy kirjoitti:
static $pdo; $haku = $dbh->query($lause);
Ota nyt silmä käteen ja katso tuota ensimmäistä riviä. Onko sillä mitään tekemistä globaalin $dbh-muuttujan kanssa? Ei varmasti ole koskaan toiminut noin.
Ehdottamani db-funktio kuuluisi laittaa tuonne konffi.php:hen ja sen jälkeen db() jokaisen $dbh:n tilalle.
Kannattaa yleensä laittaa includen tilalle require_once.
Ohops jäi testailu koodi tuohon vahongossa
näin se on
kosjasin kooodiin eli
public $pdo; $haku = $dbh->query($lause);
No ei se sen paremmaksi muuttunut: edelleenkään rivillä ei ole globalia eikä $dbh:ta. Yritäpä vaikka opetella PHP-oppaasta näitä alkeita.
Ei prkl, pastettelee nääitä koodeja niin menee sekasin..
Siis koodin on oikeiasti
global dbh; en tuo pdo tuli jostain esimerkistä ei minun koodista.
Kannattaa lukea mitä on laittanut ennen kuin painaa "Lähetä" nappia. Jotenkin ei hirveästi ihmetytä, että ohjelman kanssa on ongelmia, kun katsoo tuota sekoilun määrää.
Saitko sen jo toimimaan vai vieläkö on ongelmaa jonkin asian kanssa? (kun en oikein pysy kärryillä)
heh, en saanut toimimaan.. ja nyt on korjattu koodi tuola esimerkissä..
Meni hieman sekaisin kun kokeilin tuossa noita metabolixin koodeja oman sekaan..
tosiaan aikoinaan tehnyt aina noin ja nyt sitten herjaa kun pitkästä aikaa alkoi koodailemaan.
Otetaanpa nyt asia kerrallaan, ettei tarvitse sekoilla. Vaihda nyt ihan ensin jokaisen includen tilalle require_once, niin tiedetään, että tiedostot ovat varmasti mukana.
ne on vaihdettu ja tiedostot on olemassa. eihä se muuten herjaisi tuonne functiot.php:n jos sisältösivu ei olisi ladannut ensin konffia ja konffi sitten functioita
ehkä tässä on jo koodaillu vähä liikaa ja pitäisi käydä välillä ulkona.. :)
Sitten laita konffi.php:ssä olevat jutut tuollaiseksi db-funktioksi, jota ehdotin, ja vaihda funktiot.php:ssä oleva kysely muotoon db()->query($lause).
Noni, jatketaampa. Nyt on näin. Kokeilen kahdella tiestolla ensin.
index.php
<?php require_once'konffi.php'; $q = db()->prepare("SELECT * FROM versio"); foreach ($dbh->query($q) as $kanta){ echo $kanta['versio'].' - '.$kanta['otsikko'].'<br />'.$kanta['teksti'].'<br /><br />'; } ?>
konffi.php
<?php // ***** TIETOKANTA ***** $palvelin = 'localhost'; $tietokanta='kanta'; $tunnus='tunnus'; $salasana='ssala'; function db() { static $dbh; if (!$dbh) { $dbh= new PDO("mysql:host=$palvelin;dbname=$tietokanta", $tunnus,$salasana,array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); } return $dbh; } ?>
Pukkaa aika erikoista virhettä
Stack trace: #0 /home/public_html/test/konffi.php(13): PDO->__construct('mysql:host=;dbn...', NULL, NULL, Array) #1 /home/public_html/test/index.php(5): db() #2 {main} thrown in /home/public_html/test/konffi.php on line 13
No nuo loputkin muuttujat pitäisi tietenkin laittaa funktion sisään. Siitähän tässä koko keskustelussa on alusta asti ollut kysymys: globaaleista muuttujista vs. funktion sisäisistä muuttujista. (Muutenkin on aika vaarallista pitää tietokantatunnuksia globaaleissa muuttujissa. Joskus vielä tulostaisit ne vahingossa sivulle.)
Laitapa virheilmoitukset ja varoitukset käyttöön:
Veikkaan, että tulee aika paljon ilmoituksia. Kannattaa kuitenkin korjata ne kaikki.
Taidan luovuttaa nämä omat vanhat viritykset ja napata jostain joku oikea toimiva systeemi. Esim tuolla oppaissa näytti olevan.
Sekin on tosin toteutettu eritavalla kuin sinun metabolix?
vai olisiko jotain huippuja valmiita systeemejä joilla kannan käyttö olisi varsinaisilla sisältö sivuilla lastenleikkiä?
Antin PHP-oppaassa on monta puutetta, koska Antin mielestä huono koodi on aloittelijalle helpompaa ymmärtää. Olen tästä aivan toista mieltä: jos kaikki oppaiden koodi olisi hyvää, tilanne olisi juuri päinvastoin ja aloittelijoille tulisi vähemmän ongelmia.
Luovutat? Oikeasti, ei voi olla niin vaikeaa siirtää neljä riviä funktion ulkopuolelta funktion sisään? :D
Kokeilin tässä vielä vääntää, siirryin yhden tiedoston malliin, jos opettelis ensin tämän oikean pdo:n käytön.
Miten tuolla db():llä sitten käytetään tuota kantaa? esim foreeach?
<?php function db() { static $pdo; $palvelin = ''; $tietokanta=''; $tunnus=''; $salasana=''; if (!$pdo) { $pdo = new PDO("mysql:host=$palvelin;dbname=$tietokanta", $tunnus, $salasana,array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); } return $pdo; } $q = db()->prepare("SELECT * FROM versio"); foreach (db()->query($q) as $kanta){ echo $kanta['versio'].' - '.$kanta['otsikko'].'<br />'.$kanta['teksti'].'<br /><br />'; } ?>
Ei ainakaan noin toiminut
kirjoittaja kirjoitti:
[22-Jan-2012 17:36:17] PHP Warning: PDO::query() expects parameter 1 to be string, object given in /home/public_html/test/index.php on line 16
[22-Jan-2012 17:36:17] PHP Warning: Invalid argument supplied for foreach() in /home/public_html/test/index.php on line 16
Ihan samalla tavalla käytetään kuin vanhalla $dbh:llakin – eli ei todellakaan noin, vaan tuosta $q-oliosta pitäisi nyt kutsua $q->execute() ja foreachin alussa $q->fetchAll(). (Tai vaihtoehtosesti suoraan db()->query("SELECT * FROM taulu")->fetchAll() ilman mitään $q:ta.)
Tämä db-funktio ei vaadi muualla koodissa mitään muita muutoksia kuin jokaisen $dbh:n vaihtamisen db():ksi, eikä tästä seuraa yhtäkään ylimääräistä virheilmoitusta, vaan kaikki ongelmat ovat jo ennestään olleet koodissasi.
Jos et osaa edes PDO:n alkeita, ei ole mikään ihme, ettei homma suju. Suosittelen oppaiden perusteellista lukemista. Esimerkiksi MySQL-oppaan toinen osa voisi olla hyödyllinen, siinä esitellään PDO:n käyttöä.
Noni, nyt toimii! Kiitos. On sitä aikoinaan tullu koodailtua enempiki, mutta siloin ei ollut pdo:ta olemassakaan, muutenki php tais olla vähän alkeellisempi.. 2000 alkupuolella?
Jotenki tämä on nyt niin hankala käsittää kun en ole noiden luokkien kanssa pelannut. erillisillä functioilla vain.
Toivottavasti tämä nyt alkaa sujumaan, kuin tämän kanta asian saa kuntoon.
Joo, kyllä PHP on onneksi 10 vuodessa vähän kehittynyt. :) Toki vanhat MySQL-funktiot ovat olemassa, mutta kunhan opit PDO:ta käyttämään, varmaan huomaat, että näin on parempi.
Joo, tämä sinun opettamasi tapa vaikuttaa todella hyvältä. Ei tule ylimääräisiä rivejä koodiin. Kiitokset vielä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.