[RESOLU] Transformer objet en un autre objet d'une certaine classe

Eléphant du PHP | 53 Messages

29 sept. 2016, 09:35

Bonjour,

Je travaille actuellement sous un site web / application.

Je récupère une liste de type array (qui contient les variables voulues), ensuite je la transforme en un objet grâce au cast (object).

Cet objet contient des noms de machines voulues, et il doit remplacer un array d'objet contenant les listes de TOUTES les machines, or on ne les veut pas toutes. J'ai donc essayé de remplacer cet objet par celui que je viens de créer.

Mais je tombe sur un problème:

J'utilise une fonction pour transformer l'objet en objet de la classe voulue (Machine). La fonction :
function objectToObject($instance, $className) {
    					return unserialize(sprintf('O:%d:"%s"%s', strlen($className), $className, strstr(strstr(serialize($instance), '"'), ':')));
					}
A la sortie, j'obtiens un objet de ce type :

object(Machine)[59]
private 'id' => null
private 'nom' =>
array (size=2)
'nom' => string 'Cat D250' (length=8)
0 => string 'Cat D250' (length=8)
private 'dernierCompteur' => null
public '0' =>
array (size=2)
'nom' => string 'Volvo L120E' (length=11)
0 => string 'Volvo L120E' (length=11)
public '1' =>
array (size=2)
'nom' => string 'Volvo A25D' (length=10)
0 => string 'Volvo A25D' (length=10)
public '2' =>
array (size=2)
'nom' => string 'Cat D250' (length=8)
0 => string 'Cat D250' (length=8)

Or je devrai obtenir un array d'objets de ce type (la liste pleine des machines) :

array (size=9)
11 =>
object(Machine)[40]
private 'id' => string '11' (length=2)
private 'nom' => string 'Cat 966 Resc' (length=12)
private 'dernierCompteur' => string '0' (length=1)
7 =>
object(Machine)[42]
private 'id' => string '7' (length=1)
private 'nom' => string 'Cat D250' (length=8)
private 'dernierCompteur' => string '19941' (length=5)
9 =>
object(Machine)[43]
private 'id' => string '9' (length=1)
private 'nom' => string 'Concasseur Pegson' (length=17)
private 'dernierCompteur' => string '13662' (length=5)
1 =>
object(Machine)[44]
private 'id' => string '1' (length=1)
private 'nom' => string 'Liebherr L566' (length=13)
private 'dernierCompteur' => string '9320' (length=4)
5 =>
object(Machine)[45]
private 'id' => string '5' (length=1)
private 'nom' => string 'Liebherr L566 Jegun' (length=19)
private 'dernierCompteur' => string '15145' (length=5)
6 =>
object(Machine)[46]
private 'id' => string '6' (length=1)
private 'nom' => string 'Liebherr R924' (length=13)
private 'dernierCompteur' => string '20129' (length=5)
3 =>
object(Machine)[47]
private 'id' => string '3' (length=1)
private 'nom' => string 'Volvo A25D' (length=10)
private 'dernierCompteur' => string '11021' (length=5)
4 =>
object(Machine)[48]
private 'id' => string '4' (length=1)
private 'nom' => string 'Volvo EC25' (length=10)
private 'dernierCompteur' => string '2465' (length=4)
2 =>
object(Machine)[49]
private 'id' => string '2' (length=1)
private 'nom' => string 'Volvo L120E' (length=11)
private 'dernierCompteur' => string '13707' (length=5)

Si quelqu'un a une idée de comment faire, j'ai cherché et tenté des choses mais sans résultat !

Avatar de l’utilisateur
Modérateur PHPfrance
Modérateur PHPfrance | 8728 Messages

29 sept. 2016, 13:50

salut,

c'est pas clair ton affaire et relativement complexe, je ne pense pas qu'utiliser la sérialisation pour passer d'un objet à un autre soit une bonne idée.

tu peux très bein parcourir ta liste d'objet pour un créer une autre
<?php
$tab1 = [];
$tabFinal = [];
foreach($tab1 as $current) {
$m = new Machine();
$m->setId($current->getId());
$->setNom($current->getNom());
// etc.
$tabFinal [] = $m;
}
si tu veux simplifier la chose tu peux créer une méthode statique dans ton objet machine qui retourne un objet machine a partir de l'autre type d'objet.

par exemple
<?php
class AutreChose
{
}
class Machine
{
    public static function fromAutreAhose(AutreChose $autreChose)
    {
        $retour = new Machine();
        $retour->setId($autrechose->getId());
        // etc..
        return $retour;
    }
}
du coup le premier code devient
<?php
$tab1 = [];
$tabFinal = [];
foreach($tab1 as $current) {
    $tabFinal[]= Machine.fromAutreChose($current);
// etc.
}
@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 53 Messages

29 sept. 2016, 14:13

Aucun souci, je suis ton conseil, si tu penses cela complexe je vais tenter d'appliquer ta méthode qui est bien souvent (voir tout le temps) la meilleure :) !

Merci pour le coup de pouce !

Avatar de l’utilisateur
Modérateur PHPfrance
Modérateur PHPfrance | 8728 Messages

29 sept. 2016, 14:59

ce n'est p'tet pas la meilleur, mais la c'est un peu capillotracté ;)

reserve la sérialisation pour son utilisation primaire (stockage sous forme de chaîne d'un objet).
après si c'est juste pour enlever des objets à une liste du peux simplement par courir la liste complète et retirer ceux qui ne conviennent pas. Le principe est le même il faut toujours parcourir un tableau.

si c'est juste pour la transformation tu peux voir avec array_map
par exemple
<?php
class AutreChose
{
    public $id;
    public $nom;
    public function __construct($id, $nom)
    {
        $this->id = $id;
        $this->nom= $nom;
    }
}
class Machine
{
    public $id;
    public $nom;
    public function __construct($id, $nom)
    {
        $this->id = $id;
        $this->nom= $nom;
    }
}

$o = [new Machine(1, 'je suis 1'),new Machine(2, 'je suis 2'),new Machine(3, 'je suis 3')];

$f = array_map(function ($item) {
    return new AutreChose($item->id, $item->nom);
}, $o);
echo '<pre>';
var_dump($f);
résultat

Code : Tout sélectionner

array(3) { [0]=> object(AutreChose)#5 (2) { ["id"]=> int(1) ["nom"]=> string(9) "je suis 1" } [1]=> object(AutreChose)#6 (2) { ["id"]=> int(2) ["nom"]=> string(9) "je suis 2" } [2]=> object(AutreChose)#7 (2) { ["id"]=> int(3) ["nom"]=> string(9) "je suis 3" } }
@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 53 Messages

30 sept. 2016, 09:30

Salut Moogli,

J'avais pas vu ta réponse hier apres-midi dsl :( ! Grâce à une inspiration que m'a donné ta méthode, je ne suis plus très loin du but !

Le problème étant au niveau du remplissage, tu le fais en dur et moi en dynamique, c'est ici que je rencontre un problème.

J'arrive à stocker un object type machine dans un array, mais pas plusieurs objets.
$i = 0;
while ($i < strlen($strID)) {
	if ($strID[$i] != ',') {
	     var_dump($strID[$i]);
	     $res = [new Machine($strID[$i])];
	}
	$i++;
}
Mon $strID est une string contenant les ID des machines à ajouter dans la liste. Il ressemble à : "string '3,2,7' (length=5)". Je le parse donc pour récupérer les ID et construire les objets machines.

Le problème qui se pose est que mon $res ne récupère que la dernière valeur d'ID, j'ai essayé un $res = $res + [new Machine($strID[$i]); mais l'ordinateur ne l'accepte pas.

Si je règle ce problème après je suis okay je pense :)

Avatar de l’utilisateur
Modérateur PHPfrance
Modérateur PHPfrance | 8728 Messages

30 sept. 2016, 10:36

pour répondre à ton problème, c'est parce qu'il autre utiliser un tableau et donc ajouter [] => $res[] =
quand tu utilises les crochets comme tu le fait c'est pour déclarer un tableau avec des valeurs, mais pour ajouter simplement c'est [] ou array_push

ton code à un problème, si l'id est supérieur à 9 il ne fonctionne plus ;)

il existe la fonction explode pour récupérer un tableau à partir de ta chaîne
du coup on peu simplifier le code
<?php
class Machine
{
    private $id;

    public function __construct($id)
    {
        $this->id = $id;
    }
}
$strID = '3,4,15,42,1337';
$tabID = explode(',', $strID);
$res = array_map(function ($id) {
    return new Machine($id);
}, $tabID);
echo '<pre>';
var_dump($res);
résultat

Code : Tout sélectionner

array(5) { [0]=> object(Machine)#2 (1) { ["id":"Machine":private]=> string(1) "3" } [1]=> object(Machine)#3 (1) { ["id":"Machine":private]=> string(1) "4" } [2]=> object(Machine)#4 (1) { ["id":"Machine":private]=> string(2) "15" } [3]=> object(Machine)#5 (1) { ["id":"Machine":private]=> string(2) "42" } [4]=> object(Machine)#6 (1) { ["id":"Machine":private]=> string(4) "1337" } }
voilà c'est pas plus compliquer ;)


@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 53 Messages

30 sept. 2016, 10:41

Il n'y a que 11 machines :) C'est pour cela qu'un id supérieur ne passe pas ! J'ai réglé tout mes problèmes et je t'en remercie. Même si tu trouveras ça peut etre un peu "deguelasse", je te montre mon code que tu puisses récupérer le bénéfice de m'avoir aidé :D .
while ($i < strlen($strID)) {
	if ($strID[$i] != ',') {
		array_push($res, new Machine($strID[$i]));
	}
	$i++;
}
Merci encore bonne journée et bon week end !

Avatar de l’utilisateur
Modérateur PHPfrance
Modérateur PHPfrance | 8728 Messages

30 sept. 2016, 10:58

ce n'est pas forcément dégeux, c'est jusque c'est pas évolutif. D'ailleurs ton code n'est utilisable que sur 10 machines (zéro à neuf ;) ).

le principal c'est que cela fonctionne comme tu le souhaites pour tout tes cas.

@+

ps :pense au bouton "résolu" en haut a gauche du titre ;)
merci
Il en faut peu pour être heureux ......

Eléphant du PHP | 53 Messages

30 sept. 2016, 11:34

Pour le 0 à 9 effectivement je vais m'en charger :p Il va falloir passer par un stockage mais mes expériences en C vont me permettre de le faire rapidement :)

Merci !

Avatar de l’utilisateur
Modérateur PHPfrance
Modérateur PHPfrance | 8728 Messages

30 sept. 2016, 12:51

utilise ma solution tu seras pas emmerdé pour le moment ;)

de rien

@+
Il en faut peu pour être heureux ......