Pripojeni k databazi MySQL
- tomasnikl
- Člen | 137
Dobry vecer, uz pres 3 hodiny se marne snazim pripojit k databazi (i kdyz to se mi uz mozna podarilo) MySQL a vypsat vsechny clanky z tabulky „test“. Prohledal jsem kompletne forum na ruzne fraze, prosel si priklad s deskami v slozce examples ale stale se mi nedari dosahnout vysledku.
Obracim se na Vas tedy s prosbou, zda nekdo nemate nejaky velmi jednoduchy priklad na:
- pripojeni k db MySQL
- vypis vsech dat z dane tabulky
jsem z toho uz opravdu zoufaly, snazim se nette pochopit ale zatim mi dela vice starosti nez uzitku :)
dekuji za ochotu a nebo nasmerovani na nejaky sikovny clanek (zde na foru to uz asi nema cenu, mam to projite snad vse).
s pozdravem Tom Nikl
- _Martin_
- Generous Backer | 679
Ahoj, nejprve otázka: jak pracuješ v PHP s DB? Používáš nějaké ORM? Nebo nějaký layer (třeba dibi)?
Pokud ti něco říká pojem MVC, tak MySQL spadá do části, které se říká model. Psaní modelů v Nette je ponecháno čistě na tvůrci aplikace. Většinou se k tomu využívají výše zmíněná ORM. Jsou-li modely jednodušší, lze si napsat vlastní modely bez použití cizích ORM (třeba s využitím již uvedeného dibi layeru).
- tomasnikl
- Člen | 137
k praci s db pouzivam dibi, jiz se mi podarilo dokonce pripojit k db coz jse necekal… vsude ovsem bylo psano ze nejlepsi je davat udaje do config.ini, ovsem to mi jaksi nefungovalo, tak jsem to vyresil jinym zpusobem.. pripojuju se takto v bootstrap.php (asi to neni vhodne ale to pozdeji vychytam, teprve se ucim a zkousim si co vse nette umi)..
dibi::connect(array(
'driver' => 'mysql',
'host' => 'localhost',
'username' => 'root',
'password' => '',
'database' => 'nette',
'charset' => 'utf8',
));
dale kdyz do DefaultPresenter.php vlozim nasledujici kod:
$text = "I'm fine";
dibi::query('UPDATE `pavel` SET `text`=%s WHERE id=1', $text);
tak mi to v databazi aktualizje tak jak ma.. z cehoz jsem nadseny ze mi to funguje :).. ovsem nedokazu vypsat veskery obsah teto tabulky (ma pouze sloupce ID a TEXT).. takze nyni potrebuji poradit pouze s timto jak tak koukam…
kdybych si to psal po svem bez nejakeho frameworku tak je to pro mne otazka 3minut, ale vsude ctu ze frameworky usnadnuji praci tak si rikam, proc to nezkusit :o) a zjistuju ze misto 3minut je pro me vypis obsahu tabulky otazkou 3hodin :o))) snad to jednohodo dne pochopim :)
Editoval tomasnikl (23. 11. 2009 17:41)
- Ondřej Mirtes
- Člen | 1536
Udělej si BaseModel:
abstract class BaseModel extends Object {
private static $db;
public function getDb() {
if (self::$db == NULL) {
self::$db = new DibiConnection(Environment::getConfig('database'));
}
return self::$db;
}
}
Díky tomuto modelu pak ve všech jeho potomcích budeš mocí přistupovat
k instanci dibi přes $this->db
.
Tento model počítá s takovýmto nastavením v config.ini (pokud se ti nedaří rozběhat config, napiš důvod, pomůžeme):
[common]
database.driver = mysqli
database.lazy = TRUE
database.charset = utf8
; dalsi nastaveni tvoji aplikace...
[development < common] ; vývojová mašina
database.host = localhost
database.database = db
database.username = user
database.password = ***
[production < common] ; produkční server
database.host = localhost
database.database = db
database.username = user
database.password = ***
Samotný model (třída pracující s databází) by mohla vypadat takto:
class TestModel extends BaseModel {
public function getTest() {
return $this->db->fetchAll('SELECT id, test FROM [table]');
}
}
V Presenteru data předáš do šablony:
class DefaultPresenter extends BasePresenter {
public function renderDefault() {
$model = new TestModel;
$this->template->data = $model->getTest();
}
}
A v šabloně je vypíšeš:
<table>
<tr><th>ID</th><th>Test</th></tr>
{foreach $data as $row}
<tr>
<td>{$row->id}</td>
<td>{$row->test}</td>
</tr>
{/foreach}
</table>
- tomasnikl
- Člen | 137
Dekuju za radu, uz to pomalu zacinam chapat..ale vyhazuje mi to chybu
Class ‚BaseModel‘ not found
File: C:\xampp\htdocs\test\nette\app\presenters\DefaultPresenter.php Line: 6
Line 6: $model = new TestModel;
DefaultPresenter.php mam nasledujici:
<?php
class DefaultPresenter extends /*Nette\Application\*/Presenter {
public function renderDefault() {
$model = new TestModel;
$this->template->data = $model->getTest();
}
}
?>
BaseModel.php (ve slozce models):
<?php
abstract class BaseModel extends Object {
private static $db;
public function getDb() {
if (self::$db == NULL) {
self::$db = new DibiConnection(Environment::getConfig('database'));
}
return self::$db;
}
}
?>
TestModel.php (ve slozce models):
<?php
class TestModel extends BaseModel {
public function getTest() {
return $this->db->fetchAll('SELECT id, test FROM [nette]');
}
}
?>
nevite kde by mohla byt chybka? nejspis jeste neco nekde musim definovat…
Diky za rady.
Tom Nikl
Editoval tomasnikl (23. 11. 2009 18:21)
- Ondřej Brejla
- Člen | 746
Promazal si temp
adresář? Používáš
RobotLoader
?
Editoval Ondřej Brejla (23. 11. 2009 18:28)
- tomasnikl
- Člen | 137
Ondřej Brejla napsal(a):
Promazal si
temp
adresář? PoužívášRobotLoader
?
temp je kupodivu prazdny.. RobotLoader? predpokladam ze nepouzivam, k nette jsem se dostal teprve vcera a poradne ani nevim co RobotLoader je a nikde jsem nic nenastavoval.. ale co jsem tak prohlizel forum a rady, tak tusim ze robotLoader se zminoval v config.ini… prikladam tedy i config.ini zda v nem nenajdete nejakou chybku:
[common]
; PHP configuration
php.date.timezone = "Europe/Prague"
php.iconv.internal_encoding = "%encoding%"
php.mbstring.internal_encoding = "%encoding%"
; services
;service.Nette-Security-IAuthenticator = Model\Users
service.Nette-Loaders-RobotLoader.option.directory[] = %appDir%
service.Nette-Loaders-RobotLoader.option.directory[] = %libsDir%
service.Nette-Loaders-RobotLoader.run = TRUE
[common]
database.driver = mysqli
database.lazy = TRUE
database.charset = utf8
; vývojová mašina
[development < common]
database.host = localhost
database.database = nette
database.username = root
database.password =
; produkční server
[production < common]
database.host = localhost
database.database = nette
database.username = root
database.password =
- tomasnikl
- Člen | 137
Ondřej Brejla napsal(a):
Nahráváš
config.ini
v bootstrapu?
ano ano, zde je kod bootstrap.php
<?php
// Step 1: Load Nette Framework
// this allows Nette to load classes automatically so that
// you don't have to litter your code with 'require' statements
require_once LIBS_DIR . '/Nette/loader.php';
// načte konfiguraci (nezadám-le jméno souboru, výchozí je '%appDir%/config.ini')
Environment::loadConfig(APP_DIR . '/config.ini');
// Step 2: Enable Nette\Debug
// for better exception and error visualisation
Debug::enable();
// Step 3: Get the front controller
$application = Environment::getApplication();
// Step 4: Run the application!
$application->run();
?>
Editoval tomasnikl (23. 11. 2009 18:46)
- tomasnikl
- Člen | 137
aha, tak jsem to zksuil postavit na „skeleton“ prikaldu ktery je v archivu kdyz se to stahne… a vypada to ze jsem pokrocil o krok dal. nyni se mi to cele seklo na:
Notice: Undefined index: test in C:\xampp\htdocs\test2\app\temp\c-Nette.Template\_9e45da1783f500c64b85498978987100.default.phtml.php on line 26
zkousel jsem temp i promazat ale nepomohlo… zkusim se v tom jeste pohrabat, treba z toho neco vyleze :)
//edit:
tak uz to funguje jak ma :)… v posledni chybe byl nejaky problem se sloupcem
v tabulce.. „Ondřej Mirtes“ si asi spatne precetl muj dotaz a misto
sloupce „text“ psal „test“ :)
Editoval tomasnikl (23. 11. 2009 19:29)
- Endrju
- Člen | 147
Ondřej Mirtes napsal(a):
Udělej si BaseModel:
abstract class BaseModel extends Object { private static $db; public function getDb() { if (self::$db == NULL) { self::$db = new DibiConnection(Environment::getConfig('database')); } return self::$db; } }
Díky tomuto modelu pak ve všech jeho potomcích budeš mocí přistupovat k instanci dibi přes
$this->db
.Tento model počítá s takovýmto nastavením v config.ini (pokud se ti nedaří rozběhat config, napiš důvod, pomůžeme):
[common] database.driver = mysqli database.lazy = TRUE database.charset = utf8 ; dalsi nastaveni tvoji aplikace... [development < common] ; vývojová mašina database.host = localhost database.database = db database.username = user database.password = *** [production < common] ; produkční server database.host = localhost database.database = db database.username = user database.password = ***
Samotný model (třída pracující s databází) by mohla vypadat takto:
class TestModel extends BaseModel { public function getTest() { return $this->db->fetchAll('SELECT id, test FROM [table]'); } }
V Presenteru data předáš do šablony:
class DefaultPresenter extends BasePresenter { public function renderDefault() { $model = new TestModel; $this->template->data = $model->getTest(); } }
A v šabloně je vypíšeš:
<table> <tr><th>ID</th><th>Test</th></tr> {foreach $data as $row} <tr> <td>{$row->id}</td> <td>{$row->test}</td> </tr> {/foreach} </table>
Ondro, prosim te, co zapricini, ze se vola metoda getDb() ve tride BaseModel? Nikde jsem si nevsiml, ze by se nekde volala a presto to bez teto funkce nemuze fungovat. vsude pak v dedenych Modelech pristupuji k promenne $this->db, ale kde jsem tuto promennou naplnil? Je dost mozne, ze mi unika neco zakladniho, ale vrta mi to hlavou a byl bych rad, kdyby se mi to nekdo pokusil objasnit. Dekuji moc!
- mkoubik
- Člen | 728
Ondro, prosim te, co zapricini, ze se vola metoda getDb() ve tride BaseModel? Nikde jsem si nevsiml, ze by se nekde volala a presto to bez teto funkce nemuze fungovat. vsude pak v dedenych Modelech pristupuji k promenne $this->db, ale kde jsem tuto promennou naplnil? Je dost mozne, ze mi unika neco zakladniho, ale vrta mi to hlavou a byl bych rad, kdyby se mi to nekdo pokusil objasnit. Dekuji moc!
To zařídí třída Object
, kterou dědí
BaseModel
. Je to takovej pomocník, kterej dělá z php
použitelnej objektovej jazyk. Pokud přistupuješ k private proměnné, pak se
použije getter (pro čtení – getPromenna()
) nebo setter (pro
zápis – setPromenna($hodnota)
). Je dobrý třídu, která by
jinak nic nedědila podědit z Object
, ulehčí ti to spoustu
práce. Víc tady.
- Endrju
- Člen | 147
mkoubik napsal(a):
Ondro, prosim te, co zapricini, ze se vola metoda getDb() ve tride BaseModel? Nikde jsem si nevsiml, ze by se nekde volala a presto to bez teto funkce nemuze fungovat. vsude pak v dedenych Modelech pristupuji k promenne $this->db, ale kde jsem tuto promennou naplnil? Je dost mozne, ze mi unika neco zakladniho, ale vrta mi to hlavou a byl bych rad, kdyby se mi to nekdo pokusil objasnit. Dekuji moc!
To zařídí třída
Object
, kterou dědíBaseModel
. Je to takovej pomocník, kterej dělá z php použitelnej objektovej jazyk. Pokud přistupuješ k private proměnné, pak se použije getter (pro čtení –getPromenna()
) nebo setter (pro zápis –setPromenna($hodnota)
). Je dobrý třídu, která by jinak nic nedědila podědit zObject
, ulehčí ti to spoustu práce. Víc tady.
Ahaaaa, tak ted je mi to mnohem jasnejsi! Netusil jsem, ze to funguje jako getter a setter :).
Takze kdyz bych mel metodu getPromenna()
a
setPromenna()
, ktera by nastavovala nejakou private promennou
$xyz
,
tak tuto promennou nastavuji tak za zavolam treba
$this->promenna = neco
(v tomto pripade se vola metoda
setPromenna()) a naopak $neco = $this->promenna;
(zde se zase
vola metoda getPrommena()).
Je to presne tak nebo se mylim? (Znam to takto z .NET c#).
Jenom mi taky pak trochu nesedi, ze promenna $db
je static a
metoda, ve ktere k teto promenne pristupuji (tedy getDb()
) static
neni. Nevim jak to ma byt, ale tusim, ze tak jak jsem zvykly z .NET bych
v non-static metode nemohl pristupovat ke static promennym. Kdyz tak me pls
opravte pokud je to jinak, diky :)!
- mkoubik
- Člen | 728
Ahaaaa, tak ted je mi to mnohem jasnejsi! Netusil jsem, ze to funguje jako getter a setter :).
Takze kdyz bych mel metodu
getPromenna()
asetPromenna()
, ktera by nastavovala nejakou private promennou$xyz
,tak tuto promennou nastavuji tak za zavolam treba
$this->promenna = neco
(v tomto pripade se vola metoda setPromenna()) a naopak$neco = $this->promenna;
(zde se zase vola metoda getPrommena()).Je to presne tak nebo se mylim? (Znam to takto z .NET c#).
Je to přesně tak.
Jenom mi taky pak trochu nesedi, ze promenna
$db
je static a metoda, ve ktere k teto promenne pristupuji (tedygetDb()
) static neni. Nevim jak to ma byt, ale tusim, ze tak jak jsem zvykly z .NET bych v non-static metode nemohl pristupovat ke static promennym. Kdyz tak me pls opravte pokud je to jinak, diky :)!
To je pokud vím obráceně. Ze statické metody nemůžeš přistupovat k nestatické proměnné, ale z nestatické metody můžeš přistupovat ke statické proměnné (která je pro všechny instance třídy společná).
- SyXcz
- Člen | 75
hm teď mi zas hlásí „Configuration must be array, string or ArrayObject.“. File: C:\xampp\htdocs\syx_new\libs\dibi\libs\DibiConnection.php Line: 68
zřejmě mi nenačítádatabázi z config.ini
ale přitom ho načítam
<?php
// Step 1: Load Nette Framework
// this allows load Nette Framework classes automatically so that
// you don't have to litter your code with 'require' statements
require LIBS_DIR . '/Nette/loader.php';
require LIBS_DIR . '/dibi/dibi.php';
// Step 2: Configure environment
// 2a) enable Nette\Debug for better exception and error visualisation
Debug::enable();
// 2b) load configuration from config.ini file
new DibiConnection(Environment::getConfig('database'));
Environment::loadConfig();
// Step 3: Configure application
// 3a) get and setup a front controller
$application = Environment::getApplication();
$application->errorPresenter = 'Error';
//$application->catchExceptions = TRUE;
?>
atd.. atd…
neni tu někde funkční tutoriál k používání mysql? quick-start pořát neni a na fóru to každej používá jinak, a ať zkoušim jak zkoušim, nejede :(
Editoval SyXcz (7. 3. 2010 12:02)
- chemikus
- Člen | 49
Tak a teď jsem suveréně v koncích. Mám
bootstrap.php
<?php
// Step 1: Load Nette Framework
// this allows load Nette Framework classes automatically so that
// you don't have to litter your code with 'require' statements
require LIBS_DIR . '/Nette/loader.php';
require LIBS_DIR . '/dibi/dibi.php';
// Step 2: Configure environment
// 2a) enable NDebug for better exception and error visualisation
NDebug::enable();
// 2b) load configuration from config.ini file
NEnvironment::loadConfig();
dibi::connect(NEnvironment::getConfig('database'));
// Step 3: Configure application
// 3a) get and setup a front controller
$application = NEnvironment::getApplication();
$application->errorPresenter = 'Error';
//$application->catchExceptions = TRUE;
// Step 4: Setup application router
$router = $application->getRouter();
$router[] = new NRoute('index.php', array(
'presenter' => 'Homepage',
'action' => 'default',
), NRoute::ONE_WAY);
$router[] = new NRoute('<presenter>/<action>/<id>', array(
'presenter' => 'Homepage',
'action' => 'default',
'id' => NULL,
));
// Step 5: Run the application!
$application->run();
?>
Pak mám config
[production < common]
; common database connection
database.driver = mysql
database.database = hodnoti_cz
database.charset = utf8
database.lazy = TRUE
database.host = localhost
database.username = *******
database.password = *******
[development < common]
; database options in development mode
database.profiler = TRUE
database.host = localhost
database.username = root
database.password = newpwd
A jediný co mi to vypíše je
InvalidArgumentException
Configuration must be array, string or ArrayObject.
A když se podívám na argumenty, které se předávají
dibi/dibi.php (191) source ► DibiConnection-> __construct (arguments ▼)
$config
NConfig(4) ▼ {
"profiler" => "1"
"host" => "localhost" (9)
"username" => "root" (4)
"password" => "newpwd" (6)
}
Můžete mi někdo prosím sdělit, co a kde mám špatně?
EDIT
Problém vyřešen změnou jednoho řádku
<?php
dibi::connect(NEnvironment::getConfig('database')->toArray());
?>
btw. Určitě byste to měli změnit i v tutoriálu, protože se to vůbec neshoduje ;-) A hlavně, v nové verzi se používají už N… zatímco v tutoriálu je to bez N ;-)
Editoval chemikus (16. 9. 2010 13:04)