[RESOLU] Obtenir une instance de la classe parent

Modérateur PHPfrance
Modérateur PHPfrance | 10409 Messages

22 mai 2016, 13:15

Bonjour,

Mes cours de poo remontent à loin du coup je galère un peu à m'y remettre et espère que vos lumières ou suggestions pourront m'aider à y voir plus clair :)

En résumé : j'ai une classe B qui hérite d'une classe A et je dispose d'une instance ($b) de B.

Y a-t-il une solution en php (5) pour "cloner", copier, transformer... cette instance afin d'obtenir une instance $a de A, avec uniquement les valeurs des attributs qui vont bien ? Je voudrais en fait récupérer juste une partie de l'instance $b correspondant à la classe parente, sans devoir me taper la copie des attributs un à un -_-
(est-ce seulement possible en php ?)

En gros je voudrais insérer les attributs du parent dans une table et ceux propres à l'enfant dans une autre à partir de la classe enfant, mais je ne parviens pas à trouver de solution simple ou propre permettant de profiter de l'héritage, ce qui m’arrangerait bien vu le nombre de classes enfants et d'attributs à gérer...

Je me bats avec des clones (je mériterais d'être au conseil des jedis !), des selfs, etc. mais j'arrive à rien... alors à vot' bon coeur :(
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Mammouth du PHP | 506 Messages

23 mai 2016, 12:17

Bonjour Ryle, je n'ai pas la solution mais c'est le principe du Class Table Inheritence de Doctrine.
http://docs.doctrine-project.org/projec ... nheritance

Le parent et l'enfant sont enregistrés dans des tables différentes et liés par la clé primaire qui est la même. J'ai pas regardé sous le moteur mais tu peux peut être y trouver des éléments de réponse.

EDIT : sinon, après avoir cherché un peu, je pense que tu peux t'orienter sur la Reflection API ou utiliser la fonction get_object_vars. Tu devrais pouvoir assez simplement créer une instance de la class parente, boucler sur ses propriétés et y injecter dynamiquement les valeurs de l'enfant.
http://fr.php.net/manual/en/book.reflection.php
http://fr.php.net/manual/en/function.ge ... t-vars.php

Modérateur PHPfrance
Modérateur PHPfrance | 10409 Messages

23 mai 2016, 17:50

Hello !

Merci pour ton retour, je vais jeter un coup d'oeil à doctrine et voir si effectivement je peux m'en inspirer.
A défaut je pense effectivement utiliser get_object_vars pour alimenter simplement une instance de ma classe parent, mais ça m'étonne quand même qu'on ne puisse pas aisément distinguer la partie "parent" de la classe enfant".
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Modérateur PHPfrance
Modérateur PHPfrance | 10409 Messages

24 mai 2016, 12:16

Bon ben visiblement php ne permet pas l'upcasting, je me suis donc pour le moment rabattu sur une initialisation membre à membre de mon instance parente.
class Father {

	public function upcast() {
		$f = new Father;
		foreach (get_object_vars($this) as $property => $value) {
			if (isSet($f->$property)) {
				if (!is_object($value))
					$f->$property = $value;
				else
					$f->$property = clone $value;
			}
		}
		return $f;
	}

}
La méthode upcast() hérité par les classes filles me permettra ainsi d'obtenir une instance du parent en attendant de trouver mieux. Je peux ainsi accéder aux méthodes du parent applicable au parent et non à la classe fille et faire un insert du parent dans la table parent et un insert des filles dans les tables correspondantes... y a surement mieux, mais en attendant ça fera l'affaire :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Mammouth du PHP | 506 Messages

25 mai 2016, 18:04

Salut Ryle, je savais pas que ça s'appelait l'upcasting. ^^
A priori moi je l'aurais pris dans l'autre sens (boucle sur les propriétés de $f) et j'aurais utilisé un ternaire (^^) mais en tout cas ça m'a l'air très bien. :)

Modérateur PHPfrance
Modérateur PHPfrance | 10409 Messages

25 mai 2016, 19:29

Bien vu ! Une boucle sur $f est effectivement plus logique (forcément moins d'attributs à parcourir) et du coup évite le isSet :)

Pour le ternaire, on peut effectivement l'utiliser ici, mais en ce qui me concerne j'essaie d'en limiter l'usage. D'une part parce que de nombreux développeurs ne connaissent pas cette syntaxe et d'autre part parce qu'elle est plus complexe à lire qu'un if/else (surtout quand tu commences à les imbriquer :)).
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Mammouth du PHP | 506 Messages

26 mai 2016, 00:16

C'est clair que l'imbrication de ternaires est plutôt à éviter pour la lisibilité mais dans des cas simples comme l'affectation d'une valeur à une variable selon une condition simple elle aussi [ if (condition) a = b; else a = c; ], je trouve qu'il prend tout son sens et est au contraire très lisible [ a = condition ? b : c; ]. Je trouve ça plutôt élégant. :)

Typiquement aussi sur un return (ou un echo) je préfère nettement un [ return condition ? a : b; ] qu'un [ if (condition) return a; else return b; ], la première syntaxe est pour moi plus lisible et élégante. Et je pense que tout développeur avec un minimum d'expérience le connait (il est utilisait par nombre de développeurs, on le retrouve dans beaucoup de librairies, frameworks et autres solutions open source). Mais après c'est sur que ça reste une préférence assez personnelle. ;)

Saian, membre de la LDT (Ligue de Défense du Ternaire). Faisons connaître le ternaire ! :mrgreen: