Mul on tietokanta luokka, mutta nyt pitäisi lehti luokassa tehdä tietokanta kyselyit. Miten siirrän tietokanta yhteyden sinne? Olen siis jo avannut yhteyden tietokantaan sivun alus muita kyselyit varten.
Ilmeisesti näin
$db = new Tietokanta('MySQL');
....
$lehti = new Lehti($db);
Sitten Lehti luokas constructorissa $this->db = $db
Jolloin luokas voi käyttää $this->db->query($sql);
Ilmeisesti näin
$db = new Tietokanta('MySQL');
....
$lehti = new Lehti($db);
Sitten Lehti luokas constructorissa $this->db = $db
Jolloin luokas voi käyttää $this->db->query($sql);
Vastaukset 13
Vanhimmat
tuolla katsomassa:
http://www.intranetjournal.com/php-cms/
Käy läpi ainakin part 2, se selittää miten tuo pitää tehdä.
Kiitoksia linkistä, mut voitkos kertoa tarkemmin missä kohtaa se selviää? En meinaan huomannut siel.
Ellet sit meinannut tuota SystemComponent(asetusten haku) juttua, mielestäni se ei käy tietokantayhteyteen?
Selvyyden vuoksi pieni esimerkki mitä haluan pohjautuen tuohon linkkisi esimerkkiin.
Ongelma on miten tietokanta yhteyttä voi käyttää Lehti luokas?
Tietokantaluokan perintä ei liene hyvä ratkaisu, koska näin joutuu avaa toisen yhteyden kantaan?
"Tietokantaluokan perintä ei liene hyvä ratkaisu, koska näin joutuu avaa toisen yhteyden kantaan?"
on oikea ratkaisu, siksihän luokkia käytetään. SystemComponen luokkaa ei ole pakko käyttää mutta se helpottaa jonkin verran.
Mistä niin päättelit, että kantaan avataan kaksi yhteyttä ?
DbConnector.php
class DbConnector {
/*
Täällä muodostetaan tietokanta yhteys ja suoritetaan kyselyt
*/
}
lehti.class.php
class lehti extends DbConnector{
function hae(){
}
}
käyttö tähän tapaan. Käytetään dbconnectorin query metodia, tulokset voi sitten antaa lehtiluokan hae metodille.
Huomattavasti käyttökelpoisempi ja yksinkertaisempi.
*Mistä niin päättelit, että kantaan avataan kaksi yhteyttä ?*
$connector = new DbConnector(); avaa ekan yhteyden tietokantaan, ja sitten jos periytän DbConnector lehti luokkaan niin silloinhan constructori avaa toisen yhteyden? Vai olenko ymmärtänyt jotain väärin?
Ja jos myöhemmin tartten tietokanta yhteyttä muissa luokissa niin silloin yhteyksiä on enempi?
Lisättäköön vielä, että käytän PHP 5 jolloin constructori määritellään __construct eikä PHP 4 tapaan saman nimiseksi kuin itse luokka.
*käyttö tähän tapaan. Käytetään dbconnectorin query metodia, tulokset voi sitten antaa lehtiluokan hae metodille.
Huomattavasti käyttökelpoisempi ja yksinkertaisempi.*
Hmmm.... eikös tuo juuri olio-ohjelmoinnin perusteiden vastaista?
Eikö idea ole se että kapseloidaan toiminnallisuuden omiksi luokiksi jolloin itse pääkoodi pysyy helppolukuisena jne...
*$result = $lehti -> query('SELECT firstname FROM customers');
$row = $lehti -> fetchArray($result);*
Eikö paljon käteväpi ole ilmoittaa itse pääkoodissa
$lehti->hae(4565);
joka sitten tekee tarvittavat kyselyt jne... ja palauttaa vain tarvittavan tiedon.
"...avaa ekan yhteyden tietokantaan, ja sitten jos periytän DbConnector lehti luokkaan niin silloinhan constructori avaa toisen yhteyden?"
Ei, teet ensin lehti-olion ja avaat sitten vasta tietokantayhteyden. Sama juttu muiden luokkien kanssa, jos halutaan luoda yhteys tietokantaan. Ja jos tietokantayhteyttä ei käytetä, sitä ei myöskään tarvitse periyttää.
Jeps, PHP 5:ssa tehdään juuri mainitsemallasi tavalla eli konstruktori on __construct jne..
-----------
"...eikös tuo juuri olio-ohjelmoinnin perusteiden vastaista ....idea ole se että kapseloidaan toiminnallisuuden omiksi luokiksi "
Ei ole. Sehän on juuri kapselointia. Query-metodi on siinä DbConnector-luokassa. Mutta kun mainitsit, että "hae metodi hakee tietokannasta ... ja suorittaa erinäisiä juttuja" ei ole järkevää tehdä sille omaa metodia DbConnector-luokkaan, eikä toisaalta lisätä uutta query-metodia lehti-luokkaan. Tietokantahaku tehdään samalla tavalla (hakulauseke tietenkin vaihtuu) huolimatta tulosten käsittelystä. Tulosten jatkokäsittely on sen sijaan riippuvainen asiayhteydestä eli uutiset näytetään tietyllä tavalla muotoiltuna ja sisältösivut toisella tavalla.
-----------
"Eikö paljon käteväpi ole ilmoittaa itse pääkoodissa $lehti->hae(4565);"
Tuo kai on makuasia, missä tietokantayhteyksien muodostus ja hakujen tekeminen tehdään.
*Ei, teet ensin lehti-olion ja avaat sitten vasta tietokantayhteyden. Sama juttu muiden luokkien kanssa, jos halutaan luoda yhteys tietokantaan. Ja jos tietokantayhteyttä ei käytetä, sitä ei myöskään tarvitse periyttää.*
Mutta lehti olion luontihan avaa tietokanta yhteyden. Saman tekee muutkin mihkä olen periyttänyt tuon DbConnector luokan nämä tarvitsevat myös tietokanta juttuja, eikö tällöin ole useita yhteyksiä auki?
Eihän yhteyttä kannata sulkea ja sit taas avata?
*Ei ole. Sehän on juuri kapselointia. Query-metodi on siinä DbConnector-luokassa. Mutta kun mainitsit, että "hae metodi hakee tietokannasta ... ja suorittaa erinäisiä juttuja" ei ole järkevää tehdä sille omaa metodia DbConnector-luokkaan, eikä toisaalta lisätä uutta query-metodia lehti-luokkaan.*
Hmmmm... tämähän aiheuttaa ongelmia ennemmin tai myöhemmin jos SQL-lauseet kirjoitetaan itse pääohjelmaan. Mielestäni on helpompa muokata lehti luokkaa kuin muutamalta sivulta samaa kyselyä.
Sekä nyt suunnittelen käyttäjän tunnistus juttua, ajattelin tehdä sille oman luokan jossa on myös tietokanta kyselyit. Tällöinhän luokkaa on helppo käyttää muuissakin jutuissa kun tarvittavat kyselyt on luokassa valmiina. Meneekö tämäkin taas pieleen?
Aloittelija kun olen oliomailmas.
Tarkennuksena sanon ettei tarkoitukseni ole tehdä uutta query-metodia vaan käyttää DbConnector-luokassa olevaa esim lehti luokasta käsin. Ilmeisesti näin ei saa tehdä?
Löysin Googlel tämmösen
static $install = null;
static function getInstance()
{
if (self::$instance)
return self::$instance;
else
return self::$instance = new self;
}
Ja sitten $this->db = DB::getInstance();
Jolloin avataan uus yhteys tietokantaan jos ei ole, jos yhteys on niin käytetään sitä. Mut onko tämä huono keino?
$install = $instance
Vastauksia kaivataan vielkin.
Vain Ruussi vaivautui vastaamaan muutaman kerran ei sit enää lisäkysymyksiin :(
Löysit jo ratkaisun, minkä mainitsit tuossa yhdessä viestissä. Ei, ei se löytämäsi ratkaisu ole huono keino, sillä se on yleismaailmallinen ratkaisumalli suunnittelu ongelmaasi, riippumatta ohjelmointi kielestä. Kyseistä suunnittelu mallia sovelletaan siis kun halutaan, ettei luokasta voi luoda useampaa ilmentymää (eli oliota). Katso lisää vaikka: http://en.wikipedia.org/wiki/Singleton_pattern
Jos ohjelmasi ei tarvitse kuin yhtä tietokanta yhteyttä, niin tuo on ongelmasi ratkaisu. Varsinaista tietokanta oliota ei kannata siirtää muihin luokkiin suoraan, vaan "ottaa" olio vain silloin kun sitä tarvitaan, näin tietokanta yhteyttä ei avata jos hakuja ei tehdä. Alla pieni esimerkki:
--- ESIMERKKI ALKAA ---
Lehti1 -luokan suorita funktion sisällä piti alun perin lukea Lehti2 eikä Lehti1, ja ehkä olisi pitänyt nimetä Tietokanta luokan suorita -funktio queryksi, ettei jokaisen funktion nimi olisi ollut suorita. :)
"..lukea Lehti2 eikä Lehti1.." => "..lukea Lehti1 eikä Lehti2.." =>