Champ faisant référence à une autre classe.

finalspirit Messages postés 14 Date d'inscription samedi 21 décembre 2002 Statut Membre Dernière intervention 8 juin 2007 - 6 juin 2007 à 17:43
FhX Messages postés 2350 Date d'inscription mercredi 13 octobre 2004 Statut Membre Dernière intervention 18 avril 2015 - 9 juin 2007 à 17:44
Bonjour,

Je suis actuellement en DUT Informatique et on a appris à utiliser le Java. Je connais donc les classes.
Je vois pas comment ça fonctionne sous PHP, je m'explique :
J'ai une classe contenant des champs. Ces champs sont de différents type (string, int etc...) puis j'en ai un de type auteur. Auteur étant un type faisant référence à une autre classe.

Exemple sous Java :
class Auteur {
    private String nom;
    private String prenom;

    public Auteur(nom,prenom) {
        this.nom=nom;
        this.prenom=prenom;
    }
}

class Livre {
    private String titre;
    private Auteur auteur;

    public Livre(titre,auteur) {
        this.titre=tire;
        this.auteur=auteur;
    }
}


J'ai bien ma classe livre qui a un champ qui fait référence à un objet de la classe auteur.
En php, faut faire comme ça ?
class Auteur {

    private $nom;

    private $prenom;


    public __construct($_nom,$_prenom) {

        $this->nom=$_nom;

        $this->prenom=$_prenom;

    }
}


class Livre {

    private $titre;

    private $auteur;


    public Livre($_titre,$_auteur) {

        $this->titre=$_titre;

        $this.auteur=$_auteur;

    }

}


Je pense que c'est ça, mais est ce correct... je ne sais pas donc je vous le demande :)

Par contre, c'est con que la redéfinition et la surcharge ne marche pas sous PHP :(

Merci d'avance !

15 réponses

J_G Messages postés 1406 Date d'inscription mercredi 17 août 2005 Statut Membre Dernière intervention 28 août 2007 9
6 juin 2007 à 18:13
Salut,

oui, c'est ça... Les propriétés (ne dis pas "champ" ou ton prof va te taper...) et les méthodes ne sont pas typées.

Par contre, la surcharge marche très bien !!! C'est l'héritage multiple (dit polyforme) qui n'existe pas.

A lire : http://www.php.net/manual/fr/language.oop5.php

A+
0
J_G Messages postés 1406 Date d'inscription mercredi 17 août 2005 Statut Membre Dernière intervention 28 août 2007 9
6 juin 2007 à 18:14
0
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
6 juin 2007 à 18:27
Hello,

de même, tu peux, dans une moindre mesure, typer certaines choses un peu plus avant :

class Livre {
    private $titre;
    private $auteur;

    public function Livre($_titre, Auteur $_auteur) {
       $this->titre=$_titre;
       $this->auteur=$_auteur;
    }
}
Ici, $this->auteur sera forcément de type Auteur puisque tu lui assigneras $_auteur, qui est forcé en Auteur dans l'appel de la méthode constructeur Livre.
Au passage, en PHP 5 :
class Livre {

    private $titre;

    private $auteur;


    public function __construct ($_titre, Auteur $_auteur) {

       $this->titre=$_titre;

       $this->auteur=$_auteur;

    }

}
Tui peux forcer le type dans l'appel d'une méthode pour les array et les classes. C'est tout.
0
FhX Messages postés 2350 Date d'inscription mercredi 13 octobre 2004 Statut Membre Dernière intervention 18 avril 2015 3
6 juin 2007 à 19:41
Ou alors, dans le cas où les paramètres du constructeur sont optionnels :

class Livre {
 private $id;
 private $titre;
 private $auteur;

 public function __construct($id=null, $titre=null, $auteur=null) {
   if ( isset($id) && $auteur instanceof Auteur ) { // On en déduit que ca provient d'une base de donnée, donc c'est une entrée via constructeur
        $this->id = (int) $id;
        $this->titre = $titre;
        $this->auteur = $auteur;
  } else {
       $this->id = null;
       $this->titre = null;
       $this->auteur = new auteur;
 }
}

// get/set
 public function setAuteur( Auteur $auteur ) {
  $this->auteur = $auteur;
 }

// etc...

}

Cette méthode te permet :
soit d'avoir un objet Livre vide (dans le cas d'un formulaire avec utilisation des sessions par exemple).
soit d'avoir un objet Livre rempli par le constructeur (venant d'une base SQL, d'un fichier XML, flux RSS etc...)

Voila.
Faut que je pense à faire le tuto pour codefalse, j'ai pas oublié, j'ai juste pas beaucoup le temps ces temps ci :p
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
finalspirit Messages postés 14 Date d'inscription samedi 21 décembre 2002 Statut Membre Dernière intervention 8 juin 2007
7 juin 2007 à 10:17
Merci pour ces informations.
En faite ça ressemble beaucoup plus à du Java qu'au premier coup d'oeil :) Y a même le instaceof :)

Ben merci bien pour ces précisions :)

Je vais retourner "zieuter" un peu les classes disponibles sur le site afin de parfaire mes connaissances et améliorer mon codage PHP :)

La vie n'est qu'un jeu que l'on programme au hasard !
0
J_G Messages postés 1406 Date d'inscription mercredi 17 août 2005 Statut Membre Dernière intervention 28 août 2007 9
7 juin 2007 à 11:12
Salut,

A part qques exception (Camel, Math Lab, ... ) tous les langages genre script/algo se ressemblent... T'en connais un t'en connais dix!

Mais en fait, dans son mode de fonctionnement, Java n'a vraiment aucun rapport avec PHP...

PHP est facile à appréhender, tu verras

A+
0
finalspirit Messages postés 14 Date d'inscription samedi 21 décembre 2002 Statut Membre Dernière intervention 8 juin 2007
8 juin 2007 à 12:30
Après deux petits jour sur PHP, en effet, il n'est pas très dur à appréhender. C'est un autre style de développement vu que c'est du web mais c'est vrai que c'est vite abordable.

Par contre, l'intérêt des classes en PHP je ne le vois pas encore. Enfin pour une web agency je suis d'accord, ça permet de développer plus vite mais pour le développement d'un site personnelle autant faire des fonctions que je trouve reviennent au même dans ce cas.

En faite, je crois que je ne vois pas l'intérêt des classes en PHP... une bon fichier PHP contenant les fonctions reviennent au même... ?

La vie n'est qu'un jeu que l'on programme au hasard !
0
J_G Messages postés 1406 Date d'inscription mercredi 17 août 2005 Statut Membre Dernière intervention 28 août 2007 9
8 juin 2007 à 12:58
Salut,

L'intérêt des classes en PHP ...... Ben comparé à Java où là, on ne peut pas se passer des classes - tout est structuré en objets - il est forcément moindre. Mais tout de même, c'est assez important.

Par exemple mysql... un grand classique. Si tu as PHP5, il ne faut plus utiliser mysql, mais mysqli qui est orienté objet. Là, tout d'un coup tu comprendras l'intérêt de l'objet !

De même, si tu utilises DOM... Comment faire sans objet?

Encore un exemple : beaucoup de framework utilisent des objets pour abstraire les tables des bases de données.

Une table Post :
    id
    user_id
    text

Une table Aswer :
    id
    post_id
    title
    text

un exemple d'utilisation vite fait :
    $user; // soit user l'utilisateur courrant, un objet
    $posts = $user->getPosts() // grace au post-id, je chope ces posts dans la table post (un tableau d'objet 'post')
    foreach ( $posts as $post ) {
        echo $post->getTitle() ; // effiche le titre
        $answers = post->getAnswers(); // grace au post_id de la table answer, idem
        foreach( $answers as $answer ) echo $answer->getText(); // Accés directe au champ text
    }

Bon, dans ce cas ou retrouve bien l'idée de POO, et son utilité.

Après, c'est sûr qu'on peut faire sans!!

A+
0
FhX Messages postés 2350 Date d'inscription mercredi 13 octobre 2004 Statut Membre Dernière intervention 18 avril 2015 3
8 juin 2007 à 13:58
"En faite, je crois que je ne vois pas l'intérêt des classes en PHP...
une bon fichier PHP contenant les fonctions reviennent au même... ?"
Comme tu l'as dit, tout dépend de ce que tu veux en faire.

Maintenir une classe est très facile, maintenir 10 fonctions c'est tout autre chose.

Un exemple encore plus simple que J_G :

class news {
 private $auteur;
 private $id;
 private $titre;
 // etc...
}
class auteur {
 private $id;
 private $nom;
 // etc...
}

class NewsFactory {
    static public function getNews($start = 0, $limit 10);
}

// Ca, c'était les classes. C'est long, mais regarde la suite :
 foreach ( NewsFactory::getNews() as $news ) {
       echo $news->getTitre();
       echo $news->auteur->getNom();
 }

Et le modèle est le même si tu veux une gestion de commentaire, de photos etc...
Tu fais un modèle de classe généraliste que tu spécialises par la suite.
Le gain par rapport aux fonctions, c'est le temps de code suivant les modules, le modèle objet n'aura qu'une partie du code à re-écrire alors qu'avec les fonctions, je dois les recoder à la main.

De plus, tu peux uniformiser les méthodes.
Tu prends un gestionnaire de news, et de photos.
Tu veux les 10 ères news, et les 10 ères photos.
Au lieu d'avoir des noms de fonctions à coucher dehords, on uniformise tout ca :

 foreach ( NewsFactory::get(0, 10) as $news ) {
   //
 }
 foreach ( PhotoFactory:get(0, 10) as $photo ) {
  //
 }

Et dans chaque factory, tu peux gérer les inputs/output ( xml, fichiers, sgbd,  ldap, rss etc..) aussi simplement qu'en disant bonjour. Alors qu'avec les fonctions, tu vas devoir faire :
 function getFromXML();
 function getFromFile();
 function getFromldap();

Moi je m'embète plus avec les objets, je passe l'objet d'interfacage entrée/sortie et il se démerde tout seul :)

La puissance de l'objet par rapport au fonction.
C'est aussi une autre facon de voir qui est assez déroutant au début.

Voila pourquoi tu ne comprends pas encore tout à fait à quoi ca sert :) Mais ca viendra !
0
finalspirit Messages postés 14 Date d'inscription samedi 21 décembre 2002 Statut Membre Dernière intervention 8 juin 2007
8 juin 2007 à 14:18
Ok, en effet ça aide. On a une classe mère qui contient les fonctions méthodes et ensuite on a les classes filles qui rajoute leurs méthodes à elles et redéfinissent les méthodes qui changent.
Donc si l'on a par exemple des événements de type culturel, concert et soirée, on définit la classe mère comme étant un événement puis ces classes filles comme étant culturel, concert et soiree.
Dans la mère on définits les propriétés et méthodes communes et dans les filles on redéfinit si besoin et l'on ajoute ce que chaque type à en plus.
Par exemple j'ai pour un concert des groupes mais pour une soirée ou un événement culturel je n'ai pas de groupe. Donc j'ai en plus dans la classe concert une fonction getGroupe(), c'est aussi un bon exemple ? ou j'ai mélangé les pinceaux là ? :D

Par contre le foreach je colle pas... Pourquoi ne pas faire un for ($i=0;$i<NB_NEWS;$i++)... là on dispose en plus d'un repère avec le $i ?
Le terme que je comprend pas très bien aussi, c'est "l'objet d'interfacage" ? c'est quoi ce truc ? :D

La vie n'est qu'un jeu que l'on programme au hasard !
0
J_G Messages postés 1406 Date d'inscription mercredi 17 août 2005 Statut Membre Dernière intervention 28 août 2007 9
8 juin 2007 à 14:55
Ton exemple est bon aussi...

Pour le foreach :

le for($i..) à quelque chose en moins que le foreach : il ne peux pas itérer les tableaux associatifs !

Petit rappel...
array(1,2,3,4); est un tableau indexé
array('a'=>1,'b'=>2,'c'=>3); est un tableau associatif
array('a'=>'A',2,'c'=>'C',4); est un tableau batard, mais ça existe aussi.

Fais des essais avec la fonction print_r ( array('a'=>'A',2,'c'=>'C',4) ); pour comprendre le fonctionnement de l'indexation/association des clefs dans un tableau

Donc si $i est un entier, tu n'atteindra jamais la clef 'a' de ton tableau...

pour ça, foreach te donne l'assurence de parcourir tout ton tableau!

Astuces :
foreach ( $tab as $clef=>$valeur ) echo "$clef => $valeur";
// Là tu récupère les clefs avec

foreach ( $tab as &$valeur ) $valeur ++;
unset($valeur);
// Là tu as directement accèsà la valeur (grâce au principe de reférence, équivalent du pointeur)
// PHP5 uniquement
// dans ce cas, ne surtout pas oublier le unset pour tuer la référence !!!!

reset($tab);while ( list($clef,$valeur) each($tab) ) echo "$clef> $valeur";
// ici, tu itère le tableau au sens propre du terme (d'où le reset avant qui plac le pointeur en début de tableau)
// Interet : foreach créer une copi du tableu, puis l'itère.
// Donc là tu sauve de la mémoire en évitant cette copie
// Note : rarement utile, saf si ton tableau est monstrueusement gros!

Comme tu commences en PHP, je vais aussi te donner l'astuce qui casse tout : www.php.net
La doc officielle, les exemples et commentaires des gens sont vraiement utiles.

A+
0
finalspirit Messages postés 14 Date d'inscription samedi 21 décembre 2002 Statut Membre Dernière intervention 8 juin 2007
8 juin 2007 à 16:00
D'accord, en effet le foreach est un peu plus utile que je l'aurais cru ! :)

Merci pour ces explications en tout cas :)
Et merci pour le site !

Bonne journée et bon week end à tous ! :)

La vie n'est qu'un jeu que l'on programme au hasard !
0
FhX Messages postés 2350 Date d'inscription mercredi 13 octobre 2004 Statut Membre Dernière intervention 18 avril 2015 3
8 juin 2007 à 19:44
"foreach ( $tab as &$valeur ) $valeur ++;"

Dans le cas d'un parcours de tableau :)

Si c'est un parcours d'objet, $valeur n'a pas besoin d'être passé par référence puisque les propriétés qui sont attachés à l'objet passent automatiquement par référence :)

"reset($tab);while ( list($clef,$valeur) each($tab) ) echo "$clef> $valeur";
// ici, tu itère le tableau au sens propre du terme (d'où le reset avant qui plac le pointeur en début de tableau)
// Interet : foreach créer une copi du tableu, puis l'itère.
// Donc là tu sauve de la mémoire en évitant cette copie
// Note : rarement utile, saf si ton tableau est monstrueusement gros!"
Ca, c'était la solution y'a 6 ans :)
Heuresement qu'on a évolué ^^

On peut même faire :
$Itere_moi = new Iterate ( $mon_tableau );
 foreach ( $Itere_moi as $key=>$val ) {
               echo $key.' => '.$val.'
';
 }

Chacun son truc ^^
0
J_G Messages postés 1406 Date d'inscription mercredi 17 août 2005 Statut Membre Dernière intervention 28 août 2007 9
8 juin 2007 à 20:38
Salut FhX,

Si c'est un parcours d'objet, $valeur n'a pas besoin d'être passé par
référence puisque les propriétés qui sont attachés à l'objet passent
automatiquement par référence :)
Intéressant... Je ne savais pas. 
Ca, c'était la solution y'a 6 ans :)
Là par contre, figure toi que j'utilise encore ça défois... Mais dans un cas spécial, pour éviter les récursions. ex :
// trouver tous les sous-éléments d'un arbre :
$ids[] = $parent;
reset($ids); //inutile, mais on ne sait jamais
while ( list(,$parent) = $each($ids) ) {    $sql "select id from branches where parent '$id'";
    $resSQL = $db->query($sql);    while ( $row $resSQL->fetch_row() ) $ids[] $row[0];
}
// et voilà, $ids contient tous les enfants du $parent initial
// ca permet de faire un rapide
$self_and_childs = implode("','",$ids);
$sql = "select * from whatever where id in ('$self_and_childs')";
new Iterate(); ... connais pas non plus, mais j'ai vu qu'il existait un ArrayObjet... Par contre, j'ai pas compris l'intérêt...

A+
0
FhX Messages postés 2350 Date d'inscription mercredi 13 octobre 2004 Statut Membre Dernière intervention 18 avril 2015 3
9 juin 2007 à 17:44
le new Iterate, c'est une classe qui a pour interface Iterator :)

J'aurais pu l'appeler comme je voulais lol ^^
0