Extends : je n'y arrive pas...

Mammouth du PHP | 531 Messages

25 avr. 2009, 14:01

Bonjour,

Je suis un peu perdu, car c'est la première fois que j'ulise extends et je n'y arrive vraiment pas. J'ai pourtant un exemple sous les yeux. Je pense que mon erreur se situe dans le constructeur de ma classe étendue mais je n'en suis pas vraiment sur...

L'idée est en fait d'aller piocher une valeur dans un array défini dans la classe mère depuis la classe étendu, bref du basique :

Voilà ma classe mère :
class moteur{
	private $version;
	//private $racine;
	public $param; // tableau config
	//private $aGet; // tableau $_GET
	
	public function __construct(){
		$this->version = 'dev';
		//$this->aGet = array_keys($_GET);
		$this->param = array();
		foreach(simplexml_load_file('global/config.xml')->item as $item){
			$cle = strval($item->k);
			$valeur = strval($item->v);
			$this->param[$cle] = $valeur;
		}
	}
	public function getParam($cle){
		//echo $this->param['commentaireValidation'];
		return $this->param[$cle];
	}
}
Et dans ma classe étendue :
class commentaire extends moteur{

	private $id;
	private $idArticle;
	private $pseudoAuteur;
	private $emailAuteur;
	private $ipAuteur;
	private $messageAuteur;
	private $date;
	private $etat;
	private $siteAuteur;
	
	public function __construct($id=null){
		$this->id = $id;
	}
// ...suite de la classe

public function setEtat($value){
		echo parent::getParam('commentaireValidation');
		if($value == null){
			$this->etat = parent::getParam('commentaireValidation');
		}
		else{

			$this->etat = $value;
		}
		exit();

	}
Au moment ou je fait $commentaire->setEtat() je devrais normalement voir le résultat du écho, mais rien ne s'affiche, pas d'erreur nomplus.

Voilà, je suis sur que c'est tout bête :?

ViPHP
ViPHP | 928 Messages

25 avr. 2009, 14:04

Salut,

dans le constructeur de ta classe commentaire tu as oublié de faire un :

Code : Tout sélectionner

parent::__construct();
pour appeler le constructeur de ta classe moteur.

Mammouth du PHP | 531 Messages

25 avr. 2009, 14:09

Ah merci :D
Dans l'explication que j'avais ils n'en parlait pas... peut être parce que c'est tellement logique, mais bon quand on ne sait pas ^^

Mammouth du PHP | 531 Messages

29 avr. 2009, 13:52

Je revient sur le sujet

Donc j'ai bien comprit et l'extends marche bien sauf sur un cas particulier :
class rss extends moteur{
private $fichierXml;
private $header;
private $footer;
private $chanelTitre;
private $chanelUrl;
private $chanelDescription;

public function __construct($typeDonnee){
	parent::__construct();
	if($typeDonnee == 'article'){
		$this->fichierXml = 'rss-'.$typeDonnee.'.xml';
		$this->chanelTitre = parent::getParam('blogNom').' - articles ';
		$this->chanelUrl = parent::getParam('blogUrl');
		$this->chanelDescription = parent::getParam('blogDescription'); // ne marche pas on dirait...
		echo parent::getParam('commentaireValidation'); exit();
	}
}
Ce morceau de class rss est une extension d'une classe moteur.
Dans mon constructeur à ce niveau : echo parent::getParam('commentaireValidation'); devrais m'afficher une valeur ce qui n'est pas le cas.
getParam qui est une méthode e la classe moteur est censé retourné une valeur pioché dans un tableau.

Ce qui est étrange c'est dans mes autres classes je n'ai pas de problèmes, ce n'est donc poas un défaut de la classe parent, mais dans celle classe rss en particulier je n'arrive pas à récupérer de valeurs dans ce tableau.

Etant donné que j'utilise autoload pour charger mes classes je me demandais donc dans quel ordre elles étaient charger, et si cela pouvais avoir un rapport ?
Sinon je ne vois pas trop ce qu'il peut bien se passer...

Petit nouveau ! | 2 Messages

29 avr. 2009, 17:14

Essaie d'utiliser

Code : Tout sélectionner

$this->getParm();
plutôt que

Code : Tout sélectionner

parent::getParm();

Mammouth du PHP | 531 Messages

29 avr. 2009, 17:33

Rien à faire
Je n'ai aucune erreur mais toutes mes valeurs sont vides sauf celle qui ne proviennent pas de la classe parent évidement :

object(rss)#3 (9) { ["fichierXml:private"]=> string(15) "rss-article.xml" ["header:private"]=> NULL ["footer:private"]=> NULL ["chanelTitre:private"]=> string(12) " - articles " ["chanelUrl:private"]=> NULL ["chanelDescription:private"]=> NULL ["version:private"]=> NULL ["param:private"]=> NULL ["configFile:private"]=> NULL }


EDIT :

Class moteur :
class moteur{
	private $version;
	private $param; // tableau config
	private $configFile;
	
	public function __construct(){
	}
	public function vroum(){
		$this->version = '1.0.2(a)';
		$this->configFile = 'core/config.xml';
		$this->creerFichierConfig();
		$this->updateFichierConfig();
		global $config;
		$this->param = $config;
		$this->prechauffage();
	}
	public function getParam($cle){
		return $this->param[$cle];
	}
	public function getConfigFile(){
		return $this->configFile;
	}
	public function getVersion(){
		return $this->version;
	}
	
	private function prechauffage(){
		foreach(simplexml_load_file($this->configFile)->item as $item){
			$cle = strval($item->k);
			$valeur = strval($item->v);
			$this->param[$cle] = $valeur;
		}
	}
	private function updateFichierConfig(){
		$config = simplexml_load_file($this->configFile);
		$version = ($config->item[0]->v);
		// Ecrit le fichier si version différente
		if($version != $this->version){
			$this->creerFichierConfig();
		}
	}
	private function creerFichierConfig(){
		// Ecrit le fichier si existe pas
		if(!file_exists($this->configFile)){
			$output = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
			<config>
			<item>
			<l>Version</l>
			<k>version99ko</k>
			<v>".$this->version."</v>
			<i></i>
			</item>
			<item>
			<l>URL du blog</l>
			<k>blogUrl</k>
			<v></v>
			<i>( Pas de slash à la fin. Exemple : http://www.monsite.com )</i>
			</item>
			<item>
			<l>Nom du blog</l>
			<k>blogNom</k>
			<v>Nom du blog</v>
			<i></i>
			</item>
			<item>
			<l>Description du blog</l>
			<k>blogDescription</k>
			<v></v>
			<i></i>
			</item>
			<item>
			<l>Baseline</l>
			<k>blogBaseline</k>
			<v>Un blog motorisé par 99ko.</v>
			<i></i>
			</item>
			<item>
			<l>Balise meta title</l>
			<k>metaTitle</k>
			<v></v>
			<i></i>
			</item>
			<item>
			<l>Balise meta description</l>
			<k>metaDescription</k>
			<v></v>
			<i></i>
			</item>
			<item>
			<l>Validation des commentaire</l>
			<k>commentaireValidation</k>
			<v>1</v>
			<i>( 1 = oui, 0 = non )</i>
			</item>
			<item>
			<l>Nombre d'articles par page</l>
			<k>nbArticleParPage</k>
			<v>10</v>
			<i></i>
			</item>
			<item>
			<l>Flux RSS des articles</l>
			<k>rssArticle</k>
			<v>1</v>
			<i>( 1 = oui, 0 = non )</i>
			</item>
			<item>
			<l>Nombre d'item flux RSS des articles</l>
			<k>nbItemRssArticle</k>
			<v>10</v>
			<i></i>
			</item>
			<item>
			<l>Editeur HTML</l>
			<k>editeurHtml</k>
			<v>1</v>
			<i>( 1 = oui, 0 = non )</i>
			</item>
			<item>
			<l>Thème</l>
			<k>theme</k>
			<v>classic</v>
			<i></i>
			</item>
			</config>";
			$fp = fopen($this->configFile, 'w+');
			fputs($fp, $output);
		}
	}
}
class rss :
class rss extends moteur{
private $fichierXml;
private $header;
private $footer;
private $chanelTitre;
private $chanelUrl;
private $chanelDescription;

public function __construct($typeDonnee){
	parent::__construct();
	if($typeDonnee == 'article'){
		$this->fichierXml = 'rss-'.$typeDonnee.'.xml';
		$this->chanelTitre = parent::getParam('blogNom').' - articles ';
		$this->chanelUrl = parent::getParam('blogUrl');
		$this->chanelDescription = parent::getParam('blogDescription'); // ne marche pas on dirait...
	}
}

public function getFichierXml(){
	return $this->fichierXml;
}
public function getChanelTitre(){
	return $this->chanelTitre;
}

private function setHeader(){
$xml = '<?xml version="1.0" encoding="utf-8"?><rss version="2.0">';
$xml .= '<channel>'; 
$xml .= '<title>'.$this->chanelTitre.'</title>';
$xml .= '<link>'.$this->chanelUrl.'</link>';
$xml .= '<description>'.$this->chanelDescription.'</description>';
$this->header = $xml;
}
private function setFooter(){
$xml = '</channel>';
$xml .= '</rss>';
$this->footer = $xml;
}
public function genererFluxArticle(){
$this->setHeader();
$listeArticle = article::creerListe('all', 0, parent::getParam('nbItemRssArticle'), 1);// var_dump($listeArticle);
$xml = null;
foreach($listeArticle as $article){
	//$date2=date("D, d M Y H:i:s", strtotime($date));
	$xml .= '<item>';
	$xml .= '<title>'.$article->getTitre().'</title>';
	$xml .= '<link>'.parent::getParam('blogUrl').'/index.php?p=article-lire&article='.$article->getTitreForUrl().'&idArticle='.$article->getId().'</link>';
	$xml .= '<pubDate>'.$article->getDate().' GMT</pubDate>'; 
	$xml .= '<description>'.$article->getChapo().'</description>';
	$xml .= '</item>';
}
$this->setFooter();
$output = $this->header.$xml.$this->footer;
// écriture dans le fichier
$fp = fopen($this->fichierXml, 'w+');
fputs($fp, $output);
fclose($fp);
//exit();
}
}
Et dans mon index :
$moteur = new moteur();
$moteur->vroum();
// rss
if($moteur->getParam('rssArticle') == true){
	$rss = new rss('article');
}
var_dump($rss);
Résultat du var_dump :

Code : Tout sélectionner

object(rss)#3 (9) { ["fichierXml:private"]=> string(15) "rss-article.xml" ["header:private"]=> NULL ["footer:private"]=> NULL ["chanelTitre:private"]=> string(12) " - articles " ["chanelUrl:private"]=> NULL ["chanelDescription:private"]=> NULL ["version:private"]=> NULL ["param:private"]=> NULL ["configFile:private"]=> NULL }
Je suis un poil ( enfin un gris poil ) largué...

ViPHP
ViPHP | 928 Messages

30 avr. 2009, 00:08

Il n'y a pas de liens entre ton objet $moteur et ton objet $rss, ce sont deux instances différentes qui ne partagent absolument pas les même propriétés, d'où ta très probable confusion.

Mammouth du PHP | 531 Messages

30 avr. 2009, 00:31

Ben en fait je voyais ma classe moteur comme une classe plutôt générale du script qui ne sert qu'a gérer la configuration ( vérifier si elle existe, faire un tableau des variable, la mettre à jour, etc ). Mes autres classes ont besoin de ces valeurs pour fonctionner, j'avais donc préféré faire un objet plutôt que des variables globales ou des constantes. C'est peut être pas super juste comme méthode mais je voyais pas comment faire autrement... :(

Sinon entre temps j'ai trouvé le problème.
Mon constructeur parent étant vide il était logique que depuis une autre classe je n'arrive pas à accéder aux données du tableau de paramètres puisqu'il n'était pas rempli...
Il aurait fallu que je fasse donc la même chose dans mes classes que dans l'index du script ( new moteur, moteur->vroum() ).
La solution plus simple est donc de faire dans le constructeur ce que fait cette méthode :
public function __construct(){
        $this->version = '1.0.2(a)';
        $this->configFile = 'core/config.xml';
        $this->creerFichierConfig();
        $this->updateFichierConfig();
        global $config;
        $this->param = $config;
        $this->prechauffage();
    } 
Mais si ma méthode est vraiment fausse, comment pourrais-je faire ? peut être avec un singleton ?

Eléphant du PHP | 245 Messages

20 mai 2009, 23:13

et pourquoi , au lie de definir tes proprietes/methodes de la classe mere en 'private', ne les definis tu pas en 'protected' voir en 'public'?

public : utilisable partout
private : utilisable uniquement dans la classe
protected : utilisable dans la classe et les classes descendantes (il me semble).

Eléphant du PHP | 245 Messages

20 mai 2009, 23:14

et pourquoi , au lieu de definir tes proprietes/methodes de la classe mere en 'private', ne les definis tu pas en 'protected' voir en 'public'?

public : utilisable partout
private : utilisable uniquement dans la classe
protected : utilisable dans la classe et les classes descendantes (il me semble).