Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: PDO globaalissa muuttujassa ei toimi

Sivun loppuun

creepy [21.01.2012 14:38:27]

#

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?

Metabolix [21.01.2012 14:57:25]

#

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:

function db() {
  static $pdo;
  if (!$pdo) {
    $pdo = new PDO(...);
  }
  return $pdo;
}

Sitten voi aina käyttää tuota funktiota ilman mitään kikkailuja:

$q = db()->prepare("SELECT * FROM taulu");

creepy [21.01.2012 15:13:17]

#

laitettiinkos se nykyään jotenkin erikseen globaaliksi?

täytyypä kokeilla noita sinun tapoja. Kiitos paljon!

Metabolix [21.01.2012 15:19:54]

#

Ei ole globaaleissa tapahtunut mitään muutosta.

creepy [21.01.2012 16:17:09]

#

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?

Metabolix [21.01.2012 16:18:33]

#

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.

creepy [21.01.2012 17:48:02]

#

Ohops jäi testailu koodi tuohon vahongossa

näin se on
kosjasin kooodiin eli

  public $pdo;

   $haku = $dbh->query($lause);

Metabolix [21.01.2012 17:55:05]

#

No ei se sen paremmaksi muuttunut: edelleenkään rivillä ei ole globalia eikä $dbh:ta. Yritäpä vaikka opetella PHP-oppaasta näitä alkeita.

creepy [21.01.2012 22:02:27]

#

Ei prkl, pastettelee nääitä koodeja niin menee sekasin..

Siis koodin on oikeiasti

global dbh; en tuo pdo tuli jostain esimerkistä ei minun koodista.

Grez [21.01.2012 22:15:31]

#

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ä)

creepy [21.01.2012 22:21:05]

#

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.

Metabolix [21.01.2012 22:24:32]

#

Otetaanpa nyt asia kerrallaan, ettei tarvitse sekoilla. Vaihda nyt ihan ensin jokaisen includen tilalle require_once, niin tiedetään, että tiedostot ovat varmasti mukana.

creepy [21.01.2012 22:30:17]

#

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.. :)

Metabolix [21.01.2012 23:06:49]

#

Sitten laita konffi.php:ssä olevat jutut tuollaiseksi db-funktioksi, jota ehdotin, ja vaihda funktiot.php:ssä oleva kysely muotoon db()->query($lause).

creepy [22.01.2012 13:04:06]

#

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

Metabolix [22.01.2012 13:06:48]

#

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:

ini_set("display_errors", 1);
ini_set("error_reporting", E_ALL | E_STRICT);

Veikkaan, että tulee aika paljon ilmoituksia. Kannattaa kuitenkin korjata ne kaikki.

creepy [22.01.2012 13:29:12]

#

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ä?

Metabolix [22.01.2012 13:43:15]

#

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

creepy [22.01.2012 17:39:33]

#

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

Metabolix [22.01.2012 17:43:04]

#

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öä.

creepy [22.01.2012 17:49:30]

#

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.

Metabolix [22.01.2012 17:51:46]

#

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.

creepy [22.01.2012 17:57:52]

#

Joo, tämä sinun opettamasi tapa vaikuttaa todella hyvältä. Ei tule ylimääräisiä rivejä koodiin. Kiitokset vielä.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta