Appel à une fonction membre sur un non-objet
-
05-07-2019 - |
Question
Je travaille actuellement sur les applications pratiques du Web 2.0 . un peu un barrage routier. J'essaie de faire fonctionner correctement PHP, MySQL, Apache, Smarty et le Framework Zend afin que je puisse commencer à créer l'application. Le fichier de démarrage pour Zend fonctionne, comme indiqué ci-dessous:
<?php
require_once('Zend/Loader.php');
Zend_Loader::registerAutoload();
// load the application configuration
$config = new Zend_Config_Ini('../settings.ini', 'development');
Zend_Registry::set('config', $config);
// create the application logger
$logger = new Zend_Log(new Zend_Log_Writer_Stream($config->logging->file));
Zend_Registry::set('logger', $logger);
// connect to the database
$params = array('host' => $config->database->hostname,
'username' => $config->database->username,
'password' => $config->database->password,
'dbname' => $config->database->database);
$db = Zend_Db::factory($config->database->type, $params);
Zend_Registry::set('db', $db);
// handle the user request
$controller = Zend_Controller_Front::getInstance();
$controller->setControllerDirectory($config->paths->base .
'/include/Controllers');
// setup the view renderer
$vr = new Zend_Controller_Action_Helper_ViewRenderer();
$vr->setView(new Templater());
$vr->setViewSuffix('tpl');
Zend_Controller_Action_HelperBroker::addHelper($vr);
$controller->dispatch();
?>
Ceci appelle IndexController. L’erreur vient de l’utilisation de ce Templater.php pour implémenter Smarty avec Zend:
<?php
class Templater extends Zend_View_Abstract
{
protected $_path;
protected $_engine;
public function __construct()
{
$config = Zend_Registry::get('config');
require_once('Smarty/Smarty.class.php');
$this->_engine = new Smarty();
$this->_engine->template_dir = $config->paths->templates;
$this->_engine->compile_dir = sprintf('%s/tmp/templates_c',
$config->paths->data);
$this->_engine->plugins_dir = array($config->paths->base .
'/include/Templater/plugins',
'plugins');
}
public function getEngine()
{
return $this->_engine;
}
public function __set($key, $val)
{
$this->_engine->assign($key, $val);
}
public function __get($key)
{
return $this->_engine->get_template_vars($key);
}
public function __isset($key)
{
return $this->_engine->get_template_vars($key) !== null;
}
public function __unset($key)
{
$this->_engine->clear_assign($key);
}
public function assign($spec, $value = null)
{
if (is_array($spec)) {
$this->_engine->assign($spec);
return;
}
$this->_engine->assign($spec, $value);
}
public function clearVars()
{
$this->_engine->clear_all_assign();
}
public function render($name)
{
return $this->_engine->fetch(strtolower($name));
}
public function _run()
{ }
}
?>
L'erreur que je reçois lorsque je charge la page est la suivante:
Fatal error: Call to a member function fetch() on a non-object in /var/www/phpweb20/include/Templater.php on line 60
Je comprends que $ name n’apparaît pas comme un objet, mais je ne sais pas comment résoudre ce problème. Le contrôleur n'est-il pas censé se référer au fichier index.tpl? Je n'ai pas été en mesure de découvrir ce que représente la variable $ name et comment y remédier afin que la base fonctionne correctement.
Toute aide que vous avez est très appréciée!
La solution
Le problème ne vient pas de la variable $ name mais plutôt de la variable $ _engine. C'est actuellement vide. Vous devez vérifier que la spécification du chemin d'accès à Smarty.class.php est correcte.
Vous pouvez essayer ceci pour commencer votre débogage:
$this->_engine = new Smarty();
print_r($this->_engine);
S'il s'avère que $ _engine est correct à ce stade, vérifiez qu'il est toujours correctement rempli dans la fonction render ().
Autres conseils
Zend a un exemple de création d'un système de templates qui implémente l'interface Zend_View_Interface ici: http://framework.zend.com/manual/en/zend.view.scripts.html#zend.view.scripts.templates.interface
Cela vous évitera peut-être un peu de temps pour essayer de déboguer une solution personnalisée.
Le retrait de la méthode __construct de la classe a résolu le même problème auquel je faisais face.
Renommer __construct()
en Tempater()
a fonctionné pour moi.