Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

comment se passer d'eval()

9 réponses
Avatar
J-F Portala
Bonjour,
lors d'un post precedent,
"utilisation d'eval()"
j'ai cru comprendre que cette fonction n'était pas ideale et qu'il valait
mieux essayer de s'en passer.

Est ce qu'il existe d'autres methodes que cette fonction
Voici le contenu de mon post précedent decrivant mon probleme

A partir d'une requete mysql, je souhaite réaliser un tableau décrivant les
résultats de la requete.
Ce que j'essaie de faire , c'est de préparer la requete et la description du
tableau à l'avance afin que l'affichage soit géré
automatiquement.

exemple:

$query = "select code,nom,prenom from users where validite =1" ;
j'ai donc créé une classe decrivant chaque colonne resultat de la requete
$elt->add("code","Code") ; le premier argument est le nom de la colonne
dans la requete, le second est le titre de la colonne
$elt->add(nom,"Nom") ;
$elt->add(prenom,"Prénom") ;

J'ai aussi ajouté un format (utile pour les nombres)

Et enfin, a la fin de chaque ligne, je souhaite ajouter des liens qui
permettent de valider/devalider, modifier (renvoie vers un formulaire)
Dans le cas des liens, il faut definir pour chaque ligne un lien intégrant
le code de l'enregistrement à valider ou modifier ou autre.

L'appel a la fonction display de cette classe m'affiche mon tableau avec les
liens, les formats, les noms de colonne, etc.

C'est pourquoi j'essaie de mettre en oeuvre eval(), qui pour moi est
actuellement la seule reponse que j'ai trouvée.

Comment preparer avant de lancer la requete, un lien avec $val->code en
supposant que la boucle de lecture des resultats est du type
foreach ($resultquery as $val)


merci de vos opinions

Jeff

9 réponses

Avatar
Olivier Miakinen

lors d'un post precedent,
"utilisation d'eval()"
j'ai cru comprendre que cette fonction n'était pas ideale et qu'il valait
mieux essayer de s'en passer.


Oui, d'autant plus que :
- elle est difficile à utiliser (tu l'as bien vu avec le mélange de
simples et doubles guillemets) ;
- on peut en général s'en sortir très facilement avec une fonction et/ou
une méthode objet plus une boucle (un foreach par exemple).

Est ce qu'il existe d'autres methodes que cette fonction
Voici le contenu de mon post précedent decrivant mon probleme

A partir d'une requete mysql, je souhaite réaliser un tableau décrivant les
résultats de la requete.
Ce que j'essaie de faire , c'est de préparer la requete et la description du
tableau à l'avance afin que l'affichage soit géré
automatiquement.

exemple:

$query = "select code,nom,prenom from users where validite =1" ;
j'ai donc créé une classe decrivant chaque colonne resultat de la requete
$elt->add("code","Code") ; le premier argument est le nom de la colonne
dans la requete, le second est le titre de la colonne
$elt->add(nom,"Nom") ;
$elt->add(prenom,"Prénom") ;


C'est déjà un bon point de départ. Tu peux alors avoir un tableau
d'éléments, un par ligne résultat de ta requête sql.

J'ai aussi ajouté un format (utile pour les nombres)


Une fois que tu auras le mécanisme général, rajouter un attribut, ou
deux, ou N, ne posera pas de problème particulier.

Et enfin, a la fin de chaque ligne, je souhaite ajouter des liens qui
permettent de valider/devalider, modifier (renvoie vers un formulaire)
^^

Si ce n'était l'accent manquant, je croirais que tu veux dévaliser
quelqu'un.

Dans le cas des liens, il faut definir pour chaque ligne un lien intégrant
le code de l'enregistrement à valider ou modifier ou autre.

L'appel a la fonction display de cette classe m'affiche mon tableau avec les
liens, les formats, les noms de colonne, etc.


Eh bien où est le problème ? Je fais exprès de donner un code en
français plutôt qu'en PHP pour montrer l'essentiel plutôt que les détails :

fonction display(élément)
{
affiche "<tr>n";
affiche "<td>" . nom de l'élément . "</td>n";
affiche "<td>" . format de l'élément . "</td>n";
affiche "<td>" . validé ou non validé . "</td>n";
affiche "</tr>n";
}

Avec au début :

fonction entetes()
{
affiche "<table>n";
affiche "<tr>n";
affiche "<th>nom de l'élément</th>n";
affiche "<th>format de l'élément</th>n";
affiche "<th>validé ou non validé</th>n";
affiche "</tr>n";
}

Et bien entendu, si les colonnes sont variables, il te suffit d'utiliser
un tableau associatif au lieu de les afficher en dur.

C'est pourquoi j'essaie de mettre en oeuvre eval(), qui pour moi est
actuellement la seule reponse que j'ai trouvée.


Si tu arrives à faire un code propre et sans bug avec eval(), qui plus
est sans risque de détournement par un crackeur, n'hésite pas à nous
faire signe. Mais si au contraire tu veux plus de détails sur les
tableaux (indexés par un entier) de tableaux (associatifs) et la façon
de s'en servir, tu peux demander ici.

--
Olivier Miakinen

Avatar
J-F Portala
Bonjour Olivier et merci de reprendre contact.

J'ai l'impression de ne pas bien présenter mon problème.

Le but est de préparer la requête et son affichage avant de lancer la
requête elle même.

J'ai donc une classe "select" dans laquelle je cree des objets "elt".
"elt" correspond à une colonne resultat de la requête.
Je donne donc à "elt" toutes les informations pour afficher le titre de la
colonne, et les données de chaque
cellule de cette colonne. (nom retourné par mysql, titre de la colonne,
format de la cellule, à afiicher ou pas, par la suite total à prévoir ou pas
etc...)

Lorsque tout est prêt, je lance la méthode select->display() qui va lancer
la requête et l'afficher

Toute cette partie est faite de façon automatique.
Ce sera peut être plus simple si je joins les classes et un exemple.
La preparation se fait dans queryliste(). C'est là que je prepare les
chaines de caracteres qui seront apres "evaluées"
dans dbSelect::display($db)
Il est fait appel à la classe table. Elle concerne l'affichage du tableau.
Les fonctions les plus utilisées sont:
function AddRef($name,$post,$strclick="",$title="")
{
$str = '<A HREF="'.$post.'" title="'.$title.'"
onClick="'.$strclick.'">'.$name.'</A>' ;
$this->AddCell($str) ;
}

function AddCell($val="",$format="")
{
$str0 = '<td colspan="'.$this->nbcolspan.'"
rowspan="'.$this->nbrowspan.'" class="'.$this->cellclass.'">' ;
$str1 = "</td>n" ;
if ( $format != "" )
{
printf("$str0$format$str1",$val);
}
else
{
if ( $val == "" )
echo "$str0&nbsp$str1" ;
else
echo "$str0$val$str1";
}
}



<?php

class eltLien
{
var $nomLien ;
var $urlLien ;
var $strClick ;

function __construct($nomLien,$urlLien,$strClick)
{
$this->nomLien= $nomLien ;
$this->urlLien= $urlLien ;
$this->strClick = $strClick ;
}

function __destruct()
{
}

}

class eltSelect
{
var $nom ;
var $nomCol ;
var $titreCol ;
var $format ;
var $cellFormat ;
var $bVisible ;

function
__construct($nom,$nomCol,$titreCol,$cellFormat,$bVisible=true,$format="")
{
$this->nom = $nom ;
$this->nomCol = $nomCol ;
$this->titreCol = $titreCol ;
$this->format= $format ;
$this->cellFormat= $cellFormat ;
$this->bVisible = $bVisible ;
}

function __destruct()
{
}

function getNom()
{
return $this->nom;
}

function getNomCol()
{
return $this->nomCol;
}

function getTitreCol()
{
return $this->titreCol;
}

function getFormat()
{
return $this->format;
}

function getCellFormat()
{
return $this->cellFormat;
}

function isVisible()
{
return $this->bVisible;
}
}

class dbSelect
{
var $elt ;
var $nbelt ;
var $lien ;
var $nblien ;
var $query ;
var $queryWhere ;
var $queryGroup ;
var $queryOrder ;
var $queryHaving ;
var $queryFrom ;
var $titre ;
var $tableFormat ;


function __construct($titre,$tableFormat="")
{
$this->elt = array() ;
$this->nbelt = 0 ;
$this->lien = array() ;
$this->nblien = 0 ;
$this->queryWhere = "" ;
$this->queryGroup = "" ;
$this->queryOrder = "" ;
$this->queryHaving = "" ;
$this->queryFrom = "" ;
$this->titre= $titre ;
$this->tableFormat = $tableFormat ;
}

function __destruct()
{
}

public function
add($nom,$nomcol,$titrecol,$cellFormat,$bVisible=true,$format="")
{
$this->elt[$this->nbelt]= new
eltSelect($nom,$nomcol,$titrecol,$cellFormat,$bVisible,$format) ;
$this->nbelt++ ;
}

public function addLien($nom,$url,$strClick='')
{
$this->lien[$this->nblien] = new eltLien($nom,$url,$strClick) ;
$this->nblien++;
}

public function setFrom($queryFrom)
{
$this->queryFrom = $queryFrom ;
}

public function setWhere($queryWhere)
{
$this->queryWhere = $queryWhere ;
}

public function setGroup($queryGroup)
{
$this->queryGroup = $queryGroup ;
}

public function setHaving($queryHaving)
{
$this->queryHaving = $queryHaving ;
}

public function setOrder($queryOrder)
{
$this->queryOrder = $queryOrder ;
}

public function createQuery()
{
$this->query = "select " ;
for ( $i = 0 ; $i < $this->nbelt; $i++ )
{
if ( $i > 0 ) $this->query.= ' , ' ;
$this->query .= $this->elt[$i]->getNom() ;
}
$this->query .= " ".$this->queryFrom." " ;
$this->query .= " ".$this->queryWhere." " ;
$this->query .= " ".$this->queryGroup." " ;
$this->query .= " ".$this->queryHaving." " ;
$this->query .= " ".$this->queryOrder ;

}

public function display($db)
{
$this->createquery();
$pagecour = "http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'] ;
$db->query($this->query) ;
$result = $db->get_results() ;
$nb = $db->nb_affected_rows ;
$nbfields = $db->nbfields;

include_once('class.table.php') ;
$table = new Table($this->tableFormat) ;
$table->AddTitle($this->titre) ;
$table->AddRow();
for ( $i = 0 ; $i < $this->nbelt ; $i++ )
{
if ( !$this->elt[$i]->isVisible() )
continue ;
$table->AddCellTitle($this->elt[$i]->getTitreCol()) ;
}
for ( $i = 0 ; $i < $this->nblien ; $i++ )
$table->AddCellTitle();
if ( $nb >= 1 )
foreach ( $result as $val )
{
$table->AddRow();
for ( $i = 0 ; $i < $nbfields ; $i++ )
{
if ( !$this->elt[$i]->isVisible() ) continue ;
if ( $this->elt[$i]->getCellFormat() != "" )
$table->CellClass($this->elt[$i]->getCellFormat()) ;
$nom = $this->elt[$i]->getNomCol();
$value = $val->$nom ;
if ( $this->elt[$i]->getFormat() != "" )
$table->AddCell($value,$this->elt[$i]->getFormat());
else
$table->AddCell($value) ;
}
for( $i = 0 ; $i < $this->nblien; $i++ )
{
eval($this->lien[$i]->nomLien) ;
eval($this->lien[$i]->urlLien) ;
eval($this->lien[$i]->strClick) ;
$table->AddRef($nomLien,$strLien,$strClick) ;
}
}
$table->Close();
}
}
?>
class commande
{
function __construct()
{
}

function queryliste()
{
include_once('class.dbselect.php') ;
$this->sel = new dbselect("","Liste des commandes") ;
$this->sel->add("a.code","code","Code","data") ;
$this->sel->add("a.numCde","numCde","Numero","data") ;
$this->sel->add("c.nom as client","client","Client","data-center") ;
$this->sel->add("a.ouvrage","ouvrage","Ouvrage","data-center") ;
$this->sel->add("date_format(a.dateCde,'%d/%m/%Y') as
dateCde","dateCde","Création","data-center") ;
$this->sel->add("u.nom as
operateur","operateur","operateur","data-center") ;
$this->sel->add("if(a.gdeDist=0,'o','n') as gdeDist","gdeDist","Gde
distribution","data-center") ;
$this->sel->setFrom("from ".$this->nomTable." a, utilisateur
u,client c") ;
$this->sel->setWhere("where a.numClient = c.code and
u.code=a.operateur order by a.numCde") ;

// c'est ici que je ne vois pas comment faire autrement qu'utiliser eval()
$nomLien = '$nomLien = $val->gdeDist==0?"Valider":"Dévalider" ;' ;
$strLien = '$str = $val->gdeDist==1?CST_INVALIDATION:CST_VALIDATION
;' ;// ce spon,t des constantes
$strLien .= '$strLien = "$pagecour?code=$val->code&Mode=$str" ;' ;
$strClick = '$str = $val->gdeDist==0?"valider":"dévalider" ;' ;
$strClick .= '$strClick = "return confirm('vous allez $str la
commande $val->gdeDist ') ;";' ;
$this->sel->addLien($nomLien,$strLien,$strClick) ;

$strLien ='$strLien =
"$pagecour?code=$val->code&Mode=".CST_FORM_MODIFICATION ;' ;
$this->sel->addLien('$nomLien = "Modifier";',$strLien,'$strClick =
"" ;') ;

$strClick = '$post =
"$pagecour?Mode=".CST_SELECTION."&code=$val->code" ;' ;
$strClick .= '$strClick = "window.open('$post')" ;' ;
$this->sel->addLien('$nomLien = "Etiquette" ;','$strLien = "#"
;',$strClick) ;
}

function __destruct()
{
}

}

include_once('class.commande.php') ;
include_once('class.pysql.php') ;
$db = new db() ;
$obj = new commande() ;
$obj->queryliste() ;
$obj->sel->display($db) ;
$db->Close() ;
?>

Est ce que je prends le problème par le mauvais bout.

Merci de ton aide

Jeff
Avatar
Olivier Miakinen
Les fonctions les plus utilisées sont:
function AddRef($name,$post,$strclick="",$title="")
{
$str = '<A HREF="'.$post.'" title="'.$title.'"
onClick="'.$strclick.'">'.$name.'</A>' ;
$this->AddCell($str) ;
}


Puisque je fais de la relecture de code, j'en profite pour te signaler
ce que j'aurais écrit différemment, pour une meilleure lisibilité. Ici,

$str = "<a href='$post' title='$title' " .
"onClick='$strclick'>$name</a>n" ;


function AddCell($val="",$format="")
{
$str0 = '<td colspan="'.$this->nbcolspan.'"
rowspan="'.$this->nbrowspan.'" class="'.$this->cellclass.'">' ;
$str1 = "</td>n" ;
if ( $format != "" )
{
printf("$str0$format$str1",$val);
}
else
{
if ( $val == "" )
echo "$str0&nbsp$str1" ;
else
echo "$str0$val$str1";
}
}


Tiens, on a déjà dit que « eval is evil », mais si on peut éviter des
if() cela supprime aussi pas mal de sources de bugs.

Par exemple ici :

if ( $val == "" )
echo "$str0&nbsp$str1" ;
else
echo "$str0$val$str1";

Le &nbsp; ne sert qu'à contourner un problème de rendu chez les
navigateurs qui ont la valeur 'empty-cells' à "hide" par défaut.
Il suffit d'une ligne de CSS et tu peux virer ce if() inutile pour
ne laisser que « echo "$str0$val$str1"; » :

<http://www.yoyodesign.org/doc/w3c/css2/tables.html#empty-cells>
Cette règle autorise le dessin des bordures autour de chacune des cellules :
TABLE { empty-cells: show }
</>

Autre exemple, tu fais un cas particulier selon que format est à sa
valeur par défaut ("") ou pas. Mais il suffirait de changer la valeur
par défaut à "%s" pour ne plus avoir besoin de cas particulier !

Cela donne donc au final :

function AddCell($val="", $format="%s")
{
$str0 = '<td colspan="'.$this->nbcolspan.'"
rowspan="'.$this->nbrowspan.'" class="'.$this->cellclass.'">';
$str1 = "</td>n" ;
printf("$str0$format$str1", $val);
}

N'est-ce pas que c'est plus facile à relire ?


public function addLien($nom,$url,$strClick='')
{
$this->lien[$this->nblien] = new eltLien($nom,$url,$strClick) ;
$this->nblien++;
}


Voilà encore un truc inutile : $this->nblien (et $this->nbelt dans la
fonction précédente).

Moi je ferais :

public function addLien($nom, $url, $strClick='')
{
$this->lien[] = new eltLien($nom, $url, $strClick);
}

... et si à un moment j'ai besoin du nombre d'éléments, j'utilise tout
simplement count($this->lien). Cela élimine un cas de bug potentiel
(celui où $this->nblien serait différent de la taille réelle du
tableau).


public function createQuery()
{
$this->query = "select " ;
for ( $i = 0 ; $i < $this->nbelt; $i++ )
{
if ( $i > 0 ) $this->query.= ' , ' ;
$this->query .= $this->elt[$i]->getNom() ;
}
[...]
}


Voilà justement l'exemple. Au lieu d'utiliser $this->nbelt, on peut
utiliser count($this->elt). Mais il y aurait encore mieux à faire, si en
plus (ou à la place ?) d'un tableau de elt tu avais un tableau de noms,
un tableau de noms de colonnes, un tableau de titres, etc. Je veux dire
que dans la fonction add, si tu avais « $this->noms[] = $nom », tu
pourrais remplacer toute la boucle for()+if() par une seule ligne :

public function createQuery()
{
$this->query = "select " ;
$this->query .= implode(", ", $this->noms);
[...]
}

N'est-ce pas Saint-Exupéry qui disait que « la perfection est atteinte
non pas lorsqu'il n'y a plus rien à ajouter, mais lorsqu'il n'y a plus
rien à retirer » ?


foreach ( $result as $val )
{
[...]
for( $i = 0 ; $i < $this->nblien; $i++ )
{
eval($this->lien[$i]->nomLien) ;
eval($this->lien[$i]->urlLien) ;
eval($this->lien[$i]->strClick) ;
$table->AddRef($nomLien,$strLien,$strClick) ;
}
}


Ah, nous y voilà enfin. Je recopie aussi la ligne d'initialisation de
machintruc->nomLien :

$nomLien = '$nomLien = $val->gdeDist==0?"Valider":"Dévalider" ;' ;


J'espère que tu es conscient que cette utilisation de '$val' lors de
l'initialisation détruit toute ta belle construction objet ? En effet,
si dans un an tu décides de remplacer '$val' par '$value' dans le
foreach (tout-à-fait valide : c'est une variable locale), ton programme
se cassera la gueule et tu ne sauras pas pourquoi. Idem pour $nomLien.

La solution la plus simple, si l'initialisation de nomLien est toujours
du même type, c'est de remplacer :
eval($this->lien[$i]->nomLien) ;
par :
$nomLien = $val->gdeDist==0 ? "Valider" : "Dévalider";

Maintenant, si les classes de PHP permettent le polymorphisme, c'est :
$nomLien = $this->obtenirNomLien($val);
... où la méthode obtenirNomLien() fera potentiellement des choses
différentes selon le type de lien (et le paramètre $val bien sûr).


Voilà, j'espère que cela t'aidera à y voir plus clair.

Cordialement,
--
Olivier Miakinen
Troll du plus sage chez les conviviaux : le nouveau venu, avec
son clan, s'infiltre dans les groupes de nouvelles. (3 c.)

Avatar
J-F Portala
Merci de ta relecture constructive.

Je vais faire les modifs que tu proposes, elle vont dans le bon sens.


public function createQuery()
{
$this->query = "select " ;
for ( $i = 0 ; $i < $this->nbelt; $i++ )
{
if ( $i > 0 ) $this->query.= ' , ' ;
$this->query .= $this->elt[$i]->getNom() ;
}
[...]
}


Voilà justement l'exemple. Au lieu d'utiliser $this->nbelt, on peut
utiliser count($this->elt). Mais il y aurait encore mieux à faire, si en
plus (ou à la place ?) d'un tableau de elt tu avais un tableau de noms,
un tableau de noms de colonnes, un tableau de titres, etc. Je veux dire
que dans la fonction add, si tu avais « $this->noms[] = $nom », tu
pourrais remplacer toute la boucle for()+if() par une seule ligne :

public function createQuery()
{
$this->query = "select " ;
$this->query .= implode(", ", $this->noms);
[...]
}
C'est effectivement une solution, mais cela m'oblige à préparer ma requête

en cr"ant
un tableau avec les noms, un autre avec les titres des colonnes, un autre
avec les formats...
Je préfère décrire un objet intégrant directement ces informations pour une
plus grande simplicité d'utilisation.
Si j'ai besoin d'une autre information, j'insère une seule ligne plutot que
d'insérer au bon endroit dans différents tableaux les informations.


N'est-ce pas Saint-Exupéry qui disait que « la perfection est atteinte
non pas lorsqu'il n'y a plus rien à ajouter, mais lorsqu'il n'y a plus
rien à retirer » ?


foreach ( $result as $val )
{
[...]
for( $i = 0 ; $i < $this->nblien; $i++ )
{
eval($this->lien[$i]->nomLien) ;
eval($this->lien[$i]->urlLien) ;
eval($this->lien[$i]->strClick) ;
$table->AddRef($nomLien,$strLien,$strClick) ;
}
}


Ah, nous y voilà enfin. Je recopie aussi la ligne d'initialisation de
machintruc->nomLien :

$nomLien = '$nomLien = $val->gdeDist==0?"Valider":"Dévalider" ;'
;


Cette initialisation permet d'afficher soit valider soit invalider en

fonction du resultat de la requete sur
une ligne donnée. La plupart du temps, les liens sont figés "modifier"
"clôturer" "annuler",etc

J'espère que tu es conscient que cette utilisation de '$val' lors de
l'initialisation détruit toute ta belle construction objet ? En effet,
si dans un an tu décides de remplacer '$val' par '$value' dans le
foreach (tout-à-fait valide : c'est une variable locale), ton programme
se cassera la gueule et tu ne sauras pas pourquoi. Idem pour $nomLien.


Tu as completement raison sur ce point.

C'est ici que j'ai du mal à comprendre comment je peux me passer d'eval().

La solution la plus simple, si l'initialisation de nomLien est toujours
du même type, c'est de remplacer :
eval($this->lien[$i]->nomLien) ;
par :
$nomLien = $val->gdeDist==0 ? "Valider" : "Dévalider";

Suivant les tables, le test se fera sur des noms de variables différentes

(ici gdeDist mais je voulais que cela reste dynamique).

Maintenant, si les classes de PHP permettent le polymorphisme, c'est :
$nomLien = $this->obtenirNomLien($val);
... où la méthode obtenirNomLien() fera potentiellement des choses
différentes selon le type de lien (et le paramètre $val bien sûr).

Si dans ma classe toto, je prepare une requete à l'aide d'un objet dbselect,

lorsque je vais
vouloir afficher le resultat a l'aide de dbselect->display(), je ne vois pas
comment dans la boucle foreach
je vais pouvoir lancer une fonction de la classe toto permettant d'afficher
les liens.

foreach ( $result as $val )
{
// affiche des lignes "normales"
...
// affichage des liens
toto::afficheliens($table,$val) ;
}

la fonction afficheliens appartenant à la classe toto
function affichelien($table,$val)
{
$nomlien = $val->ceque je veux == 0 ? "blabla" : "noblabla" ;
$urlLien = "";
$strClick = "" ;
$table->addRef($nomLien,$urlLien,$strClick) ;
}

Je ne sais pas si c'est cela à quoi tu pensais, mais cela fonctionne en
mettant en "dur" l'appel
toto::afficheLiens($table,$val) ;
J'ai essayé de passer le nom de fonction dans une variable mais cela me
donne une erreur
setFctLien("toto::affichelien") ;

$this->fctLien($tablen,$val) ;
call to undefined function toto::afficheliens() in dbselect.php

Est ce normal?

merci de ton aide

Jeff


Avatar
Olivier Miakinen

La solution la plus simple, si l'initialisation de nomLien est toujours
du même type, c'est de remplacer :
eval($this->lien[$i]->nomLien) ;
par :
$nomLien = $val->gdeDist==0 ? "Valider" : "Dévalider";

Suivant les tables, le test se fera sur des noms de variables différentes

(ici gdeDist mais je voulais que cela reste dynamique).


Bon. Alors plutôt que passer un « nomLien » qui est une instruction
complète, pourquoi ne pas passer simplement le nom de la variable à
tester ?

Je ne suis pas 100 % sûr de la syntaxe, mais un truc comme ça devrait
avoir une chance de marcher :

$testNomLien = $this->lien[$i]->testNomLien;
$nomLien = ${val->$testNomLien) ? "Valider" : "Invalider" ;

function affichelien($table,$val)
toto::afficheLiens($table,$val) ;
setFctLien("toto::affichelien") ;
call to undefined function toto::afficheliens() in dbselect.php

Est ce normal?


Ce qui me semble anormal, c'est surtout que tu aies trois noms
différents pour la même fonction :

affichelien
afficheliens
afficheLiens

Cela dit, encore une fois je n'ai jamais fait de programmation objet
en PHP, aussi je ne suis pas très habitué à la syntaxe particulière aux
classes dans ce langage.

--
Olivier Miakinen
Troll du plus sage chez les conviviaux : le nouveau venu, avec
son clan, s'infiltre dans les groupes de nouvelles. (3 c.)


Avatar
Olivier Miakinen

Bon. Alors plutôt que passer un « nomLien » qui est une instruction
complète, pourquoi ne pas passer simplement le nom de la variable à
tester ?

Je ne suis pas 100 % sûr de la syntaxe, mais un truc comme ça devrait
avoir une chance de marcher :

$testNomLien = $this->lien[$i]->testNomLien;
$nomLien = ${val->$testNomLien) ? "Valider" : "Invalider" ;


Et si là encore cela ne suffit pas parce que tu veux avoir des tas de
tests ou de valeurs différentes, tu passes le nom de la méthode et tu
appelles une fonction :

function valeurNomLien($test, $val)
{
switch($test) {
case "valider si gdeDist est nul" :
return ($val->gdeDist == 0) ? "Valider" : "Invalider";
case "OK si trucBidule plus grand que 3" :
return ($val->trucBidule > 3) ? "OK" : "Erreur";
case "J'ai piscine si on est lundi" :
return ($val->jour == "lundi") ? "Piscine" : "Athlétisme";
...
}
}

...
$nomLien = valeurNomLien($this->lien[$i]->testNomLien, $val)

Toutes les fantaisies te sont alors permises... le tout sans eval().

--
Olivier Miakinen
Troll du plus sage chez les conviviaux : le nouveau venu, avec
son clan, s'infiltre dans les groupes de nouvelles. (3 c.)

Avatar
J-F Portala
Merci de ne pas lacher l'affaire

L'initialisation des liens

J'ai musieurs types de liens
function afficheliens($table,$val)
{
// lien sans javascript- redirection vers une autre page avec parametres
$pagecour = "http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'] ;
$strLien = "$pagecour?code=$val->code&Mode=".CST_FORM_MODIFICATION ;
$strClick = "" ;
$table->AddRef("Modification",$strLien,$strClick) ;

// lien avec boite confirmation javascript - redirection vers une autre page
avec parametres
$nomLien = $val->brut==1?"Valider":"Invalider" ;
$strLien =
"$pagecour?code=$val->code&Mode=".($val->brut==0?CST_INVALIDATION:CST_VALIDATION)
;
$strClick = "return confirm('vous allez
".($val->brut==0?"valider":"invalider")." la repartition ".$val->num."') ;";
$table->AddRef($nomLien,$strLien,$strClick) ;

// lien ouverture d'une autre page en javascript
$post1 = '$pagecour?Mode=".CST_ETIQUETTE_USER."&codeuser=$val->code'
;
$strClick = 'window.open(''.$post1.'') ;' ;
$this->setLien("Impression etiquettes","#",$strClick) ;
}

Chaque lien est compose de 3 variables (le libelle, la page cible et du
javascriptsur le onclick)
Bien sûr, l'exemple plus haut peut varier dans les constantes ainsi que dans
les variables passées (idem pour le javascript).

Puisque les liens seront souvent spécvifiques aux classes (souvent liées à
des tables),
j'ai essayé d'exploiter ton idée de faire appel à une fonction extérieure
lors de la construction des liens.

Cette fonction est définie dans ma classe de base, et j'ai juste à passer en
parametre le nom de la fonction qui sera appelée
systémaitquemen lors de la construction du tableau résultat, mais je me
heurte à un refus de PHP.
(Ce n'est pas un probleme d'orthographe...)

Plus généralement, je n'arrive pas à utiliser passer d'une fonction
dans une classe
class test
{
var $fct ;
function affiche
{
echo "ca roule raoul " ;
}

function essai()
{
$fct = 'affiche' ;
$fct() ; // j'ai aussi essayé avec $fct = '$this->affiche' ;
}
}
$obj = new test ;
$obj->essai() ;

Hors d'une classe, cela fonctionne (voir les exemples de la doc PHP), mais
pas à l'intérieur
sauf ...
si on utilise eval()
function essai()
{
$fct = '$this->affiche()' ;
eval($fct;) ;
}

Qu'en penses tu?


cordialement

Jeff
Avatar
Fredchou
Hors d'une classe, cela fonctionne (voir les exemples de la doc PHP), mais
pas à l'intérieur
sauf ...
si on utilise eval()


Chez moi ceci fonctionne parfaitement :

class test
{
var $fct ;

function affiche()
{
echo "ca roule raoul " ;
}

function essai()
{
$fct = 'affiche' ;
$this->$fct() ; // <-- Il faut bien utiliser $this mais avec un "$"
devant "fct()"
}
}
$obj = new test ;
$obj->essai() ;

--
Fredchou
mailto:

Avatar
J-F Portala
Merci je n'avais pas pensé à cela

Jeff