Appel fonction et paramètres variables

Appel fonction et paramètres variables - PHP - Programmation

Marsh Posté le 03-09-2017 à 17:45:22    


   Bonjour
 
  J'ai des fonctions dans des variables ( $func1, $func2 etc...  ),et des paramètres dans $arg11, $arg12, $arg21, $arg22 etc..., comment appeler une fonction, si on ne connait pas à l'avance le nombre d'arguments de la fonction ?
 
  En effet, ce sont plusieurs fonctions, pour chaque fonction il peut avoir un ou plusieurs arguments, et le traitement étant dynamique, on ne sait le nombre d'arguments qu'au moment de l'exécution.
 
  C'est pour ma version perso de l'ORM Eloquent, plus précisément pour le formulaire de test, les fonctions sont les fonctions Eloquent ( méthodes de ma classe Database ).
 
  Merci beaucoup pour votre aide.
 
  Amicalement.
 
 Jean François Ortolo
 
 

Reply

Marsh Posté le 03-09-2017 à 17:45:22   

Reply

Marsh Posté le 03-09-2017 à 18:13:18    

Je connais pas PHP mais je dirais que tu cherches les "variadic functions". http://php.net/manual/en/functions [...] e-arg-list

Reply

Marsh Posté le 03-09-2017 à 18:45:30    

Bonjour Monsieur
 
  Il ne s'agit pas de la *réception* des paramètres par la fonction, mais de l'écriture de l'appel à la fonction.
 
  Par exemple, la fonction : $func1 et les paramètres : $arg11, $arg12 et $arg13.
 
  On ne sait qu'à l'exécution combien de paramètres il y a.
 
  Comment  appeler la fonction $func1(), c'est-à-dire comment rédiger ses paramètres dans le code source PHP, alors que l'on ne sait pas pendant l'écriture du programme, combien il y aura   de paramètres ?
 
  Merci beaucoup de vos réponses.
 
  Respectueusement.
 
  Jean François Ortolo
 
 
 


Message édité par ortolojf le 03-09-2017 à 18:51:31
Reply

Marsh Posté le 03-09-2017 à 18:55:41    

Ne serait-ce pas mieux de passer directement par un tableau ?
 
L'appel n'est pas un problème non plus, tu peux écrire :

Code :
  1. $func1($arg11, $arg12, $arg13);


 
Ou encore :

Code :
  1. call_user_func($func1, $arg11, $arg12, $arg13);


 
Ou encore :

Code :
  1. $args = [
  2.    $arg11,
  3.    $arg12,
  4. ];
  5. if ($machin > 1) {
  6.    $args[] = $arg13;
  7. }
  8. call_user_func_array($func1, $args);


 
Il y a encore la reflection pour un appel dynamique mais c'est similaire aux fonctions call_user_func(_array).


Message édité par pluj le 03-09-2017 à 18:58:19
Reply

Marsh Posté le 03-09-2017 à 19:23:16    

(Sur les forums je tutoie, libre à toi de faire la même chose, inutile de se compliquer la vie. ;) )
 
J'ai pas vraiment compris, mais comme pluj je pensais aux tableaux aussi, peut-être c'est une solution?

Reply

Marsh Posté le 03-09-2017 à 19:31:16    

+1 pour l'utilisation de tableaux en argument quand la fonction prend un nb variable de paramètres. Si c'est une fonction à moi, je fais mafonc($ArrayParams); et ma fonction se débrouille à l'intérieur pour interpréter le contenu de $ArrayParams ;)
 
Edit : mais les solutions de pluj sont biens aussi.


Message édité par rufo le 03-09-2017 à 19:31:47

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 03-09-2017 à 19:41:54    


  Je m'explique.
 
  Il y a un nombre n de paramètres, ce nombre n'est *pas* connu au moment de l'écriture du programme.
 
  Les variables ( leurs valeurs ), ne sont également connues *qu'à* l'exécution du programme pas avant.
 
  Comment  écrire *l'appel* à la fonction, avant même de savoir le nombre de paramètres ?
 
  Et puis, très important : Les fonctions ont des signatures données, impossible de changer ces signatures.
 
  Ces fonctions suivent la syntaxe de l'ORM Eloquent.
 
  Et enfin, ( last but not least ) : Des fonctions ( entre autres ), peuvent avoir un certain nombre de paramètres, ce nombre ( et les paramètres ), ne sont connus qu'à l'appel de la fonction.
 
  Il s'agit d'appeler ces fonctions, pas de lire les paramètres  ( çà je sais faire ).
 
  Merci beaucoup de vos réponses.
 
  Amicalement.
 
  Jean François Ortolo
 
 

Reply

Marsh Posté le 03-09-2017 à 19:45:28    


  Et puis aussi :
 
  Voici ces fonctions, par exemple :
 
  $conn = new Database("" );
 
  $conn->TABLE('CHEVAUX')->SELECT('NUMCH', 'NOMCH')->WHERE('NUMCH', 2000)->GET();
 
  Merci beaucoup.
 
  Jean François Ortolo
 
 

Reply

Marsh Posté le 03-09-2017 à 20:57:03    

Ben sinon, méthode bourrin : tu construits une string $MaChaine qui contient ton code à exécuter et tu le fais exécuter par eval($MaChaine);
Cela dit, faudrait faire attention à pas faire exécuter du code malveillant :/
 
Edit : cela dit, ça confirme ce que j'ai toujours pensé à propos des ORM : c'est de la merde :o Quand on voit la difficulté du code à pondre pour faire une simple requête SQL.  :pt1cable: Dans ton cas, ça donnerait : SELECT NUMCH, NOMCH FROM CHEVAUX WHERE NUMCH = 2000
 
Je te dis même pas comment tu vas galérer quand tu vas devoir faire des requêtes plus complexes qui vont nécessiter des sous-requêtes à l'intérieur de ton FROM ou de ton WHERE :sweat:


Message édité par rufo le 03-09-2017 à 21:00:44

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 03-09-2017 à 21:31:23    


  Bonjour Monsieur
 
  Cà marche même quand il y a plusieurs paramètres ?
 
  Si je fais :
 
  $func = 'SELECT';
  $args = $arg11 . ", " . $arg12 . "," . $arg13;
 
  Et :
 
   $func(eval($args));
 
  Celà est correct ?
 
  Merci beaucoup.
 
  Respectueusement.
 
 Jean François Ortolo
 
 

Reply

Marsh Posté le 03-09-2017 à 21:31:23   

Reply

Marsh Posté le 03-09-2017 à 21:43:27    

Non, ça serait plutôt :
$MaChaine = '$conn->TABLE(\'CHEVAUX\')->SELECT(\'NUMCH\', \'NOMCH\')->WHERE(\'NUMCH\', 2000)->GET();';
eval($MaChaine);
 
Mais comme indiqué, eval() peut présenter un soucis de sécurité. Je recommanderais plutôt de se passer de l'ORM qui, à mon avis, apporte plus de pbs qu'il n'en résout. Franchement, se faire quelques requêtes SQL à la main + utiliser PDO, c'est pas très compliqué :o

Message cité 1 fois
Message édité par rufo le 03-09-2017 à 21:45:28

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 04-09-2017 à 08:30:00    

rufo a écrit :

Non, ça serait plutôt :
$MaChaine = '$conn->TABLE(\'CHEVAUX\')->SELECT(\'NUMCH\', \'NOMCH\')->WHERE(\'NUMCH\', 2000)->GET();';
eval($MaChaine);
 
Mais comme indiqué, eval() peut présenter un soucis de sécurité. Je recommanderais plutôt de se passer de l'ORM qui, à mon avis, apporte plus de pbs qu'il n'en résout. Franchement, se faire quelques requêtes SQL à la main + utiliser PDO, c'est pas très compliqué :o


 
 
  Bonjour Monsieur
 
  Là encore, vous ne comprenez pas :
 
  Mon problème est d'écrire les paramètres sans savoir à l'écriture, le nombre  de paramètres par fonction.
 
  C'est sûr, que si j'avais cette instruction connue à l'avance je pourrais la lancer telle quelle, je n'aurais pas besoin de eval().
 
  Le problème est : Comment spécifier les paramètres ?
 
  C'est sûr, je peux faire :
 
$virgule = "";
$args = "";
 
  for($i = 0; $i < $arg_num; $i++)
{
    $arg = ${"arg". $i};
 
    $args .= $virgule . $arg;
 
    $virgule = ",";
}
 
  1)  Est-ce que le paramètre(s) $args pourra être interprété avec eval($args) ?
 
  2)  Et ceci, même si un ${"arg" . $i}   est une classe et un autre ${"arg" . $i} une string ?
 
  Merci beaucoup de votre réponse.
 
  Amicalement.
 
  Jean François
 
 

Reply

Marsh Posté le 04-09-2017 à 10:42:41    

C'est pour ça qu'on propose de passer par un array ou une string pour construire à la volée le code php à passer à la fonction de l'ORM ou carrément à eval();
 
Je pense qu'on est plusieurs à bien avoir compris le besoin, mais c'est toi qui ne comprends pas comment mettre en oeuvre les différentes solutions proposées, peut-être par manque de connaissances de PHP et du développement web...


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 04-09-2017 à 13:27:03    

Bonjour Monsieur rufo
 
  Si j'ai bien compris, vous m'avez recommandé de spécifier toute la chaîne en eval().
 
  Ceci, après avoir construit le paramètre composite de chaque fonction.
 
  Je vais essayer et reporter le résultat.
 
  Respectueusement.
 
   Jean François Ortolo
 


Message édité par ortolojf le 04-09-2017 à 13:27:33
Reply

Marsh Posté le 04-09-2017 à 14:31:28    

C'est pas tout à fait ça. L'idée est de CONSTRUIRE la chaîne de caractères dynamiquement (en fonction de ce que l'appli a besoin à un instant t) qui va contenir le code PHP à exécuter via eval().
 
Mais comme indiqué, l'utilisation d'eval() est dangereuse et il vaudrait mieux l'éviter.
 
Perso, je trouve que passer par la lib PDO et construire ces propres requêtes SQL au lieu de passer par un ORM serait bien plus simple, plus rapide et plus performant...


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 04-09-2017 à 21:51:28    

Bonjour Monsieur
 
  Quand je fais ceci pour afficher les variables indicées :  
                         
   echo "\t\t" . '$func1( ' . $arg1 . ' )->$func2( ' . $arg2 . ' )->$func3( ' . $arg3 . ' )->$func4( ' . $arg4 . ' )' . "\n\n";
 
  ( Les fonctions contiennent bien : 'TABLE', 'SELECT', 'WHERE' et 'GET' ).
 
  J'obtiens :
 
  $func1( 'CHEVAUX' )->$func2( 'NUMCH', 'NOMCH' )->$func3( 'NUMCH', 2000 )->$func4(  )
 
  Et quand je fais:  
 
   $conn = new Database("" );
 
   $conn->$func1($arg1)->$func2(eval($arg2))->$func3(eval($arg3))->$func4($arg4);
 
 
  J'obtiens :
 
Parse error: syntax error, unexpected ',' in /home/ortolojf/MVC/Parse_MySQL/new/new/essai/essai_mysql/interface_orm.php(6631) : eval()'d code on line 1
 
  Le eval() ne supporte pas de rencontrer une virgule.
 
  Comment puis-je spécifier le paramètre dans une fonction ?
 
  Par exemple :  
 
  eval(echo $arg2; )
 
  Cà marcherait ?
 
  Merci beaucoup pour ta réponse.
 
  Respectueusement.
 
  Jean François Ortolo


Message édité par ortolojf le 04-09-2017 à 21:53:11
Reply

Marsh Posté le 04-09-2017 à 22:21:37    

Un eval utilisé comme ça ne fonctionnera pas.
 
Il faudrait faire :

Code :
  1. $func1 = 'TABLE';
  2. $args1 = ['CHEVAUX'];
  3.  
  4. $func2 = 'SELECT';
  5. $args2 = ['NUMCH', 'NOMCH'];
  6.  
  7. $func3 = 'WHERE';
  8. $args3 = ['NUMCH', 2000];
  9.  
  10. $func4 = 'GET';
  11. $args4 = [];
  12.  
  13.    call_user_func_array([call_user_func_array([call_user_func_array([call_user_func_array([$conn, $func1], $args1), $func2], $args2), $func3], $args3), $func4], $arg4)
  14. );


Je ne sais pas ce que renvoie tes méthodes, si elles renvoient le même objet, on pourrait "simplifier".
 
Ca a beau être mieux qu'un eval, ça reste peu "élégant".


Message édité par pluj le 04-09-2017 à 22:34:42
Reply

Marsh Posté le 05-09-2017 à 08:30:23    

eval('$conn->'.$func1.'(' . $arg1 . ' )->'.$func2.'( ' . $arg2 . ' )->'.$func3.'( ' . $arg3 . ' )->'.$func4.'( ' . $arg4 . ' )');


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 05-09-2017 à 10:14:02    

Comme l'a dit les autres, il est beaucoup plus facile de passer un array de taille variable qui contient toutes tes données dans ce genre de cas... Charge à ta fonction de prendre ce qu'elle a besoin dans ce tableau.

Reply

Marsh Posté le 05-09-2017 à 11:13:34    


  Cà marche.
 
  J'ai fait :
 
  eval('echo $conn->'.$func1.'(' . $arg1 . ' )->'.$func2.'( ' . $arg2 . ' )->'.$func3.'( ' . $arg3 . ' )->'.$func4.'( ' . $arg4 . ' );');
 
  Il m'a rendu ( visible ) le résultat de mon ORM :
 
  SELECT NUMCH, NOMCH FROM `CHEVAUX` WHERE `NUMCH`=2000
 
  Pour l'instant mon ORM est configuré pour les tests, affiche simplement le résultat sous forme SQL relationnel.
 
  Je vais tester prochainement avec des strings et arrays ( en même temps ) comme paramètres.
 
  Merci beaucoup beaucoup pour votre aide.
 
  Respects.
 
  Jean FRançois Ortolo
 
 
 

Reply

Marsh Posté le 27-09-2017 à 23:54:33    

Bon, tout d'abord, je n'ai pas tout lu ... Ensuite je suis sur téléphone, donc je vais faire ce que je peux .
 
Si j'ai bien compris, vous chercher la fonction "func_get_args()"
 
Exemple :  
[PHP]function foo(){
Var_dump(func_get_array());
}
 
//Var_dump d'un tableau contenant "bar"
foo("bar" );
 
//Var_dump d'un tableau contenant arg1, arg2, arg3
foo("arg1", "arg2", "arg3" );
[/PHP]
 
Ensuite, on n'utilise jamais, au grand jamais de eval !!!! ( Bon ok je l'ai utilisé une fois car je n'ai pas trouvé d'autre moyen) .
 
L'autre solution étant évidemment d'utiliser un tableau en entrée :)


---------------
Mon petit topic d'achat ventes
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed