Model a připojení k DB

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Jirda
Člen | 103
+
0
-

Zdravím,

jsem zde prvně a než vůbec začnu popisovat svůj problém, chtěl bych projevit obdiv nad Nette a taktéž nad Dibi a pochválit tyto úžasná díla.

A teď k problému:
Chtěl bych zajistit přístup k databázi všem modelům prostřednictvím BaseModelu.

Na tomto fóru jsem použil prezentovaný kód uživatelem Jod, který by měl zajistit připojení k db.

Ale mám problém, php vypisuje chybu při volání datasource v modelu, který je potomkem BaseModelu.

>> Fatal error: Call to a member function dataSource() on a non-object.

Kód BaseModel:

<?php

class BaseModel extends Object
{
        protected static $db = null;

        public function __construct()
        {
                if(null === self::$db) {
                    self::$db = new DibiConnection(
                    array(
                    'driver' => 'mysql',
                    'database' => 'test',
                    'username' => 'root',
                    'password' => '',
                    'server' => 'localhost'
                        )
                    );
                }
        }

        function getDb()
        {
                return self::$db;
        }
}
?>

Volání z jiného modelu:

<?php

class Comments extends BaseModel
{
    function __construct()
    {

    }

    function getComments()
    {
      return $this->db->dataSource('SELECT * FROM comments');
    }

}

?>

Volání jsem založil taktéž na základě příspěvku, kde bylo uvedeno, že pak stačí pouze volat $this->db->query, $this->db->dataSource, $this->db->select…..

Předem děkuji za případné podněty, jak se zbavit problému.

Honza Marek
Člen | 1664
+
0
-

V BaseModelu máš model statický (self::$db) a v Comments ho používáš nestaticky ($this->db).

Jirda
Člen | 103
+
0
-

Honza M. napsal(a):

V BaseModelu máš model statický (self::$db) a v Comments ho používáš nestaticky ($this->db).

I když to přepíšu na:

return self::$db->dataSource('SELECT * FROM comments');

Tak vyhodí i tak stejnou chybu.

Honza Marek
Člen | 1664
+
0
-

Jo… taky překryješ konstruktor BaseModelu, čili ten se nezavolá a $db se nenaplní…

Jirda
Člen | 103
+
0
-

Honza M. napsal(a):

Jo… taky překryješ konstruktor BaseModelu, čili ten se nezavolá a $db se nenaplní…

Aha. Napravil jsem to tím, že teď v bootstrapu volám metodu, která $db naplní.

Ale i přesto se bohužel objevil další problém:

MemberAccessException

Call to undefined method DibiConnection::dataSource().

Omlouvám se za to, že pořád řešíme stejný problém, ale snažil jsem se na to včera přijít s kámošem a při té škále řešení, co jsme zkoušeli, se objevil i tenhle problém a taky jsme ho nevyřešili.

Patrik Votoček
Člen | 2221
+
0
-

Czus kde ty se tu beres… :-)

Koukni se nejdriv jestli nemas stavou verzi dibi kde jeste neni datasource… Protoze DibiConnection metodu dataSource ma. Pak by sis mel jak rikal Honza M. tak si prepisujes konstruktor. Pokud v podedene tride doplnujes konstruktor a potrebujes zachovat predchozi logiku tak pouzivej parent::__construct(...).

Btw: posly trochu vic zdrojaku… Ted moc nechapu kde mas presne problem.

PS: Tohle patri spis na dibi forum

Editoval vrtak-cz (2. 5. 2009 19:24)

Honza Marek
Člen | 1664
+
0
-

Vrtáku, Vrtáku… jak to děláš, že máš v každém příspěvku hrubku?

Patrik Votoček
Člen | 2221
+
0
-

Tak že na to mam patent. Ne a ted vazne… Mam na to papir od nejakyho doktora nebo to byl psichous? Uz nevim nikdy se proste ceskej pravopis nenaucim. :-(

PS: Strasne me to se***. ;-(((

Jirda
Člen | 103
+
0
-

vrtak-cz napsal(a):

Czus kde ty se tu beres… :-)

Koukni se nejdriv jestli nemas stavou verzi dibi kde jeste neni datasource… Protoze DibiConnection metodu dataSource ma. Pak by sis mel jak rikal Honza M. tak si prepisujes konstruktor. Pokud v podedene tride doplnujes konstruktor a potrebujes zachovat predchozi logiku tak pouzivej parent::__construct(...).

Btw: posly trochu vic zdrojaku… Ted moc nechapu kde mas presne problem.

PS: Tohle patri spis na dibi forum

Ahoj,
bylo to tou verzi dibi nakonec..myslel jsem, že již verze 1.01 obsahuje dataSource, tak jak jsem ho použil.

Mimochodem, co se s tebou děje? Dlouho jsme se spolu nebavili. Už několikrát jsem ti poslal žádost o autorizaci na icq a nereaguješ.

Honza M.
I tobě ještě jednou díky za snahu o pomoc. Mimo jiné, vrtak a jeho pravopis…bez hrubek by to nebyl on:o)))

kravčo
Člen | 721
+
0
-

Podľa kódu by asi bolo lepšie písať:

abstract class BaseModel extends Object // abstract
{
        protected static $db = null;

        public static function getDb() // lazy access
        {
                if(null === self::$db) {
                	self::$db = new DibiConnection(array(
				// ...
			));
                }
		return self::$db;
        }
}

class Comments extends BaseModel
{
	function getComments()
	{
		return self::getDb()->dataSource('SELECT * FROM comments');
	}
}
PetrP
Člen | 587
+
0
-

Nemyslím si že je správné vytvářet connection přímo v třídě (tedy mít tam hesla a podobně). Volil bych asi nějaký takovýto přístup (když jsme ve fóru nette tak samozřejmě přes Nette\Config\Config)

abstract class BaseModel extends Object
{
        protected $connection;

        public static function __construct(DibiConnection $connection=NULL)
        {
                if(isset($connection))
                	$this->connection = $connection;
                else
                	$this->connection = dibi::getConnection();
        }
}


// bootstrap.php
$config = Environment::loadConfig();
dibi::connect($config->database);
;; config.ini
[common]
database.driver = mysql
database.host = localhost
database.username = ferda_mravenec
database.password = beruska
database.database = brouk_pytlik
database.charset = utf8

PS: proč neexistuje i zvýrazňovaní pro ini?

Editoval PetrP (14. 5. 2009 17:41)

Jod
Člen | 701
+
0
-

kravco miesto toho static getDb by tam bolo krajšie nehať normálnu a volať to cez $this->db. Ja to mám presne tak :)

_Martin_
Generous Backer | 679
+
0
-

PetrP napsal(a):

// bootstrap.php
$config = Environment::loadConfig();
dibi::connect($config->database);

Kvůli ošetření chyb při připojování k DB je lepší řešit připojení tak, aby nezharovala celá aplikace, a měli jsme možnost využít například error presenteru:

// bootstrap.php
$application->onStartup[] = 'Database::initialize';

// Database.php
class Database extends Object
{

	public static function initialize()
	{
		$config = Environment::getConfig()->database;
		dibi::connect($config);
	}

}
PetrP
Člen | 587
+
0
-

_Martin_ napsal(a):

Kvůli ošetření chyb při připojování k DB je lepší řešit připojení tak, aby nezharovala celá aplikace, a měli jsme možnost využít například error presenteru:

jj, v tom máš pravdu, šlo mi hlavně o to aby heslo nebylo natvrdo někde zahrabané.