Question : Je ne comprends pas, dans l'action en développement
ActionRssgpcomment? arriver à récupérer le tableau associatif $k_w dans la fonction endElement.
Si quelqu'un a une idée, je lui en serai éternellement reconnaissant! :-) .
Réponse : Ce devrait fonctionner en rajoutant en tout début :
global $cur_item, $store, $total, $k_w; (j'ai modifié le code ci dessous). --
DavidDelon
Yep, ça marche. Merci David. c'est lié au fait qu'une action est exécutée dans une méthode de la classe Wiki ? --yann Oui, apparemment, je ne sais pas si c'est un bug ou une fonctionnalité de php, voir également :
http://fr2.php.net/language.variables.scope#30345 .--
DavidDelon
- En fait ce n'est ni un bug ni une véritable fonctionnalité, c'est le comportement habituel de la plupart des langages de programmation (si pas tous): si une variable est déclarée à l'intérieur d'une fonction (ou d'une méthode), alors elle n'est disponible que dans le contexte de celle-ci. -- LordFarquaad
- Dans ce cas de figure on était dans le cas Example 12-1. Using global de http://fr2.php.net/language.variables.scope, qui aurait du fonctionner non ? -- DavidDelon
- Nous sommes dans le cas de l'Exemple 16-34. Inclusion de fichiers dans une fonction http://fr2.php.net/manual/fr/function.include.php. L'action est en effet déjà un fichier inclus depuis une fonction et non depuis l'environnement global.
- ob_start(); include($fullfilename); $output = ob_get_contents(); ? --yann
- Oui c'est ça, technique pas très appropriée d'ailleurs, c'est dommage de ne pas utiliser la possibilité en PhP4? de retourner une valeur comme résultat d'un fichier inclus... (Mais bon ça n'a pas de rapport) -- LordFarquaad
- Donc la variable $k_w dans notre exemple est bien déclarée dans la méthode Action de de la classe Wiki. Elle (la variable) devrait donc être accessible depuis une fonction déclarée dans l'action en la déclarant globale (la variable) dans cette (sous-)fonction sans nécessité de la déclarer globale au niveau de la fonction Action ? Pourquoi devoir déclarer la variable globale au niveau de la fonction Action, ce qui suppose qu'elle serait accessible en dehors de la méthode Action ? --yann
- Non, comme je le dis juste après, une fonction n'hérite pas de l'environnement dans lequel elle est déclarée (en php), et d'ailleurs il n'y a aucune différence entre une fonction déclarée dans l'environnement global et une fonction déclarée à l'intérieur d'une autre fonction/méthode. -- LordFarquaad
- j'ai bien compris qu'une fonction n'hérite pas de l'environnement dans lequel elle est déclarée mais pourquoi devoir déclarer une variable globale en dehors de la fonction dans le cas présent ? ou alors je ne saisis pas bien cette notion d'environnement. --yann
- Pour clarifier: un environnement représente un ensemble de variables, leur valeur et les fonctions et classes déclarées. En php il existe trois types d'environnement: l'environnement $_GLOBAL, celui des fonctions et celui des méthodes (semblable à celui des fonctions sauf qu'il possède en plus les variables de classe). L'environnement $_GLOBAL est le seul qui peut être partagé et donc est $_GLOBAL et il est impossible de récupérer des variables provenant de l'environnement des fonctions, à moins qu'elles aient au préalable été déclarées globales.
- Dans le cas présent, lors de l'éxécution d'une action, nous nous trouvons bien à l'intérieur d'une fonction (ou plutôt d'une méthode), puisque l'inclusion se fait dans IncludeBuffered?, et l'environnement est donc local.
function myfunc() {
$a = 17;
function multiplier2() {
global $a;
$b = 10*$a;
return $b;
}
return multiplier2();
}
echo myfunc(); //affiche 0
echo multiplier2(); //affiche 0
Pour vérifier si j'ai bien compris: dans l'exemple ci-dessus: $a est bien local à la fonction myfunc, cette variable fait donc parti de l'environnement des fonctions et non de l'environnement global, elle n'est donc pas accessible depuis une autre fonction, même en la déclarant globale dans cette dernière. Pour y accéder dans multiplier2(), il faut la déclarer globale dans myfunc(). Le code ci-dessus est de ce point de vue équivalent au code ci-dessous:
function myfunc() {
$a = 17;
return multiplier2();
}
function multiplier2() {
global $a;
$b = 10*$a;
return $b;
}
echo myfunc();
echo multiplier2();
on comprend bien ici que multiplier2() n'accède pas à $a. --yann
- Oui les codes sont plus ou moins équivalents, la seule différence réside dans le fait que dans le premier code la fonction multiplier2() n'est déclarée que lors du premier appel de myFunc(), et que les appels suivant produiront une erreur car php essaiera de redéclarer la fonction alors qu'elle existe déjà... -- LordFarquaad
pour régler le problème des variables globales dans les actions, une solution serait par exemple:
Class Test {
var $a;
var $b;
function test($z) {
$this->a = $z;
return $this;
}
function myfunc5() {
return $this->multiplier5();
}
function multiplier5() {
$this->b = 10 * $this->a;
return $this->b;
}
}
$n = new Test(17);
echo $n->myfunc5();
echo $n->multiplier5();
Ce serait en effet une excellente solution. A chaque exécution d'une action il suffirait donc d'appeler une des fonctions de l'objet, avec un tableau contenant les paramètres fournis par l'utilisateur (ce qui simplifierait aussi la récupération des paramètres, et permettrait éventuellement de créer une action dont les noms de paramètres pourraient être variables) --
LordFarquaad
- Le fichier étant inclus dans le même environnement que le reste de la fonction, ses variables sont, elles aussi, locales. En php, une fonction n'héritant pas de l'environnement où elle est déclarée, les fonctions déclarées dans les actions n'ont pas accès à ses variables. L'accès aux variables globales est cependant permis, ce qui n'est pas toujours une solution idéale: on "polue" l'environnement global avec des variables qui n'ont parfois qu'une utilité très restreinte (ce qui risque de provoquer des conflits si on oublie leur existence...), par ailleurs on rend parfois la fonction sensibles à d'éventuels changements dans l'environnement global (par exemple la façon dont ces variables sont déclarées, leur type etc.) ce qui rend plus difficile la maintenance... Aaah si les actions étaient des objets, les choses seraient sûrement beaucoup plus simples dans ce genre de cas... -- LordFarquaad
- tu veux dire ecrire les actions comme des classes qui étendent la classe Wiki ?
- Non car ce serait beaucoup trop lourd et ça ne présenterait aucun intêret, sans compter la difficulter qu'on aurait à transmettre les appels de méthodes de cette classe vers l'objet $wiki. Par contre ce qui serait intéressant, ce serait que tout action se présente sous la forme d'une classe. Au premier appel de l'action la classe est incluse, et le système instancie un objet de cette classe (ce qui implique que la classe doit porter un nom correspondant au nom de l'action). Cette objet est ensuite stocké, et une de ses méthodes est appelée à chaque fois que l'action est demandée. Il peut ainsi stocker toutes les donnéesil a besoin dans ses propres variables d'instancedont sans interférer avec l'environnement global ou la classe Wiki, par ailleurs ces données peuvent être très facilement accédées par toutes ses méthodes (ce qu'il faudrait dans le cas présent apparemment). Ceci nécessiterait cependant une réécriture de toutes les actions (donc totalement exclu dans les versions 0.x.y), mais je crois que ce serait vraiment une bonne chose dans les prochaines versions majeures -- LordFarquaad
- ça se passe comment une inclusion de classe ? une classe dans un autre ? j'avoue que des choses m'échappent ... faut que je révise mon modèle objet :-) --yann
- En php une classe ou une fonction peut être déclarée depuis pratiquement n'importe où sans que cela ait d'importance (mis à part les fonctions déclarées directement dans une classe et qui sont alors des méthodes). La déclaration se fait donc comme n'importe où ailleurs. Par exemple dans WikiNi beaucoup de fonctions sont déclarés à l'intérieur d'une instruction de contrôle (if) se trouvant dans un fichier inclus appelé depuis une méthode (IncludeBuffered?) à l'intérieur d'une classe (Wiki). Il est vrai que ceci n'est pas courant, le seul autre langage que je connaisse où l'on peut faire ça est Oz, mais rien à voir avec du php, à part le typage dynamique (les environnements sont hérités, les classes et fonctions sont elles-mêmes des variables locales... qui ne sont pas variables puisque ce langage est déclaratif. Les boucles n'existent pas vraiment [impossible en modèle déclaratif] et pratiquement tout se fait donc par récursion...) -- LordFarquaad
Bon, c'est plus buggé (merci David) mais je ne comprends pas encore comme tu affectes les cases à telle ou tel feed? --
OlivierAuber
Dans le script, les feeds sont lus et affichés de gauche à droite et de haut en bas (même sens de lecture qu'un texte), à la queue leuleu et dans l'ordre où ils sont dans le paramètre de l'action, donc en fait on n'affecte pas directement une case à un feed. --yann
Pour clarifier, peut-être faudrait-il dessiner des séparateurs? (des |)? --
OlivierAuber