Event handler ‚Database::initialize‘ is not callable. (CD-collection s vyuzitim MySQL)
- Endrju
- Člen | 147
Ahoj, s Nette se teprve seznamuji a drive jsem s zanym PHP frameforkem nemel zadnou zkusenost.
Predesilam, ze jsem si precetl serial na „Začínáme s Nette Framework“ na serveru „Zdroják“.
Na foru nebo v ukazkovych aplikacich postradam nejakou kompletni ukazku prace s MySQL databazi pres modely s vyuzitim dibi. Nasel jsem jen utrzky kodu, ze kterych jsem si ale nedokazal poskladat funkcni aplikaci. Predem dekuji za pomoc.
Chci vytvorit rozzsahlejsi aplikaci s vyuzitim Nette a hned na zacatku jsem narazil na problem s vyuzitim MySQL databaze. Snazim se upravit CD-collection z examples, pro pouziti s MySQL db a nedari se mi to. Zkusel jsem pouzit ruzne navrhy reseni tady na foru, ale zda se, ze nekde delam chybu.
Chyba, kteru mi zobrazuje Ladicka:
InvalidStateException
Event handler 'Database::initialize' is not callable.
1. Nette/Object.php (110) source ► ObjectMixin:: call (arguments ►)
2. <PHP inner-code> Object-> __call (arguments ►)
3. Application/Application.php (118) source ► Application-> onStartup (arguments ►)
Line 111: do {
Line 112: try {
Line 113: if (count($this->requests) > self::$maxLoop) {
Line 114: throw new ApplicationException('Too many loops detected in application life cycle.');
Line 115: }
Line 116:
Line 117: if (!$request) {
Line 118: $this->onStartup($this);
Line 119:
Line 120: // default router
Line 121: $router = $this->getRouter();
Line 122: if ($router instanceof MultiRouter && !count($router)) {
Line 123: $router[] = new SimpleRouter(array(
Line 124: 'presenter' => 'Default',
Line 125: 'action' => 'default',
4. app/bootstrap.php (35) source ► Application-> run ()
5. document_root/index.php (19) source ► require (arguments ►)
Adresarova struktura v root directory:
app/
models/
Database.php
presenters/
DefaultPresenter.php
temp/
templates/
@layout.phtml
Default.default.phtml
bootstrap.php
config.ini
document_root/
index.php
libs/
dibi/
Nette/
Ted jak vypada obsah jednotlivych souboru:
document_root/index.php
<?php
define('WWW_DIR', dirname(__FILE__));
define('APP_DIR', WWW_DIR . '/../app');
define('LIBS_DIR', WWW_DIR . '/../libs');
require APP_DIR . '/bootstrap.php';
?>
app/models/Database.php
<?php
class Database extends Object
{
private $connection;
public static function initialize()
{
dibi::connect(Environment::getConfig('database'));
}
public function __construct()
{
$this->connection = dibi::getConnection();
}
}
?>
app/bootstrap.php
Nevim, zda musim nekde nacitat soubor Database.php, kdyz pak tridu Databse
volam v metode onStartup
volam$application->onStartup[] = 'Database::initialize';
. Nevim,
zda Nette samo nacita soubory dusledkem volani Metod a trid, ktere jsou
v techto souborech (a ty jsou umistene ve spravnych adresarich). TOhle jsem se
nikde nedocetl (nebo jsem byl nepozorny).
<?php
require LIBS_DIR . '/Nette/loader.php';
require LIBS_DIR . '/dibi/dibi/dibi.php';
Debug::enable();
Environment::loadConfig();
$application = Environment::getApplication();
$application->onStartup[] = 'Database::initialize';
$router = $application->getRouter();
$router[] = new Route('index.php', array(
'presenter' => 'Default',
'view' => 'default',
), Route::ONE_WAY);
$router[] = new Route('<presenter>/<view>/<id>', array(
'presenter' => 'Default',
'view' => 'default',
'id' => NULL,
));
$application = Environment::getApplication();
$application->run();
?>
app/config.ini
[common]
set.date-timezone = "Europe/Prague"
set.iconv-internal_encoding = "%encoding%"
set.mbstring-internal_encoding = "%encoding%"
database.driver = mysql
database.host = localhost
database.username = root
database.password = pass
database.database = databasename
database.charset = utf8
database.lazy = TRUE
; Production site configuration data
[production < common]
set.include_path = "%appDir%/libs;%modelsDir%/;%presentersDir%/"
; Staging site configuration data inherits from production and
; overrides values as necessary
[development < production]
SW, ktery pouzivam:
- WampServer 2.0
- aktualne pouzivam PHP 5.2.9–2, ale mam k dispozici i PHP 5.3
- apache 2.2.11
- MySQL 5.1.36
- Nette 0.9-PHP-5.2
- dibi-1.2
Nechal jsem take spustit „Requirements-Checker“ z adresare tools, ktery prosel s jedinou vystrahou, a to „ImageMagick library – Disabled (ImageMagick server library is absent. You will not be able to use Nette\ImageMagick.)“
Snad jsem vam dal k dospozici vsechny potrebne informace..
Dekuji za vasi pomoc s resenim problemu.
EDIT:
Zrejme jsem chybu prozatim vyresil. Problem byl v tom, ze trida Database se
nenacitala automaticky. Prisel jsem na to po prostudovani prikladu
Akrabat – https://wiki.nette.org/…ialy/akrabat
Stezejni upravu kodu jsem provedl v souboru bootstrap.php pridanim Robotloaderu, ktery zajisti automaticke nacitani trid (v kodu je to bod 2d):
<?php
// Step 1: Load Nette Framework and Dibi
// 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
Environment::loadConfig();
// 2c) check if directory /app/temp is writable
if (@file_put_contents(Environment::expand('%tempDir%/_check'), '') === FALSE) {
throw new Exception("Make directory '" . Environment::getVariable('tempDir') . "' writable!");
}
// 2d) enable RobotLoader - this allows load all classes automatically
$loader = new RobotLoader();
$loader->addDirectory(APP_DIR);
$loader->addDirectory(LIBS_DIR);
$loader->register();
// Step 3: Configure application
// 3a) get and setup a front controller
$application = Environment::getApplication();
// 3b) establish database connection
$application->onStartup[] = 'Database::initialize';
// Step 4: Setup application router
$router = $application->getRouter();
// mod_rewrite detection
if (function_exists('apache_get_modules') && in_array('mod_rewrite', apache_get_modules())) {
$router[] = new Route('index.php', array(
'presenter' => 'Default',
'action' => 'default',
), Route::ONE_WAY);
$router[] = new Route('<presenter>/<action>/<id>', array(
'presenter' => 'Default',
'action' => 'default',
'id' => NULL,
));
} else {
$router[] = new SimpleRouter('Default:default');
}
// Step 5: Run the application!
$application->run();
?>
Editoval Endrju (2. 11. 2009 2:09)