Index: phpdoc/fr/appendices/phpdevel.xml
diff -u phpdoc/fr/appendices/phpdevel.xml:1.2 phpdoc/fr/appendices/phpdevel.xml:1.3
--- phpdoc/fr/appendices/phpdevel.xml:1.2 Sat Jul 22 07:29:37 2000
+++ phpdoc/fr/appendices/phpdevel.xml Thu Oct 26 23:55:25 2000
@@ -1,829 +1,867 @@
-
- Développement PHP
-
-
-
-
- Adding functions to PHP3
-
- Prototypes de fonctions
-
- Toutes les fonctions suivent le schéma suivant :
-
-void php3_foo(INTERNAL_FUNCTION_PARAMETERS) {
-
-}
-
- Même si votre fonction ne prend aucun argument, c'est comme cela qu'elle doit être
- appelée.
-
-
-
-
- Arguments de fonctions
-
- Les arguments sont toujours de type val. Ce type contient un membre de type union,
- qui indique le type réél d'argument. De cette façon, si votre fonction prend deux
- arguments, elle ressemble à ceci :
-
-
-
-
- Argument de fonction de lecture
-
-pval *arg1, *arg2;
-if (ARG_COUNT(ht) != 2 || getParameters(ht,2,&arg1,&arg2)==FAILURE) {
- WRONG_PARAM_COUNT;
-}
-
-
-
- NOTE: Les arguments peuvent être passé par valeur ou par référence. Dans les deux cas,
- vous devez passer &(pval *) à getParameters. Si vous voulez vérifier que le n-ième
- paramètre a été passé par référence ou par valeur, vous devez utiliser la fonction
- ParameterPassedByReference(ht,n). Elle retournera 1 ou 0.
-
-
-
- Lorsque vous modifiez l'un des paramètres, qu'ils soient envoyés par référence ou par
- valeur, vous pouvez le passer à pval_destructor pour le réinitialiser, ou, s'il s'agit
- d'un tableau et que vous voulez ajouter des valeurs, vous pouvez utiliser des fonctions
- similaires à celles qui sont dans internal_functions.h, qui manipule
- return_value comme tableau.
-
-
-
- Par ailleurs, si vous modifiez un paramètre en IS_STRING, assurez vous que
- vous avez bien assigné un nouvelle chaîne avec estrdup()'ed et une nouvelle longueur
- de chaîne. Seulement après, vous pouvez modifier le type en IS_STRING.
- Si vous modifiez une chaîne en IS_STRING ou IS_ARRAY vous devez d'abord appeler le
- destructeur pval_destructor.
-
-
-
-
- Fonctions à nombre d'arguments variable
-
- Une function peut prendre un nombre variable d'arguments. Si votre fonction peut prendre
- deux ou trois arguments, utiliser la syntaxe suivante :
-
-
-
-
- Fonctions à nombre d'arguments variable
-
-pval *arg1, *arg2, *arg3;
-int arg_count = ARG_COUNT(ht);
-
-if (arg_count < 2 || arg_count > 3 ||
- getParameters(ht,arg_count,&arg1,&arg2,&arg3)==FAILURE) {
- WRONG_PARAM_COUNT;
-}
-
-
-
-
-
-
- Utiliser les arguments d'une fonction
-
- De type de chaque argument est stocké dans le champs pval. Ce champs peut prendre les
- valeurs suivantes :
-
-
- Types de données interne PHP
-
-
-
- IS_STRING
- Chaîne de caractères
-
-
- IS_DOUBLE
- Nombre à virgule flottante, en précision double
-
-
- IS_LONG
- Entier long
-
-
- IS_ARRAY
- Tableau
-
-
- IS_EMPTY
- Aucune
-
-
- IS_USER_FUNCTION
- ??
-
-
- IS_INTERNAL_FUNCTION
- ?? (Si ce type ne peut pas être passé à une fonction, effacez le)
-
-
- IS_CLASS
- ??
-
-
- IS_OBJECT
- ??
-
-
-
-
-
-
- Si vous recevez un argument d'un type, te que vous voulez l'utiliser avec un autre
- type, ou si vous voulez simplement forcer le type, vous pouvez utiliser l'une des
- fonctions de conversion suivante :
-
-
-convert_to_long(arg1);
-convert_to_double(arg1);
-convert_to_string(arg1);
-convert_to_boolean_long(arg1); /* Si la chaîne est "" ou "0" elle devient 0, 1 sinon */
-convert_string_to_number(arg1); /* Converti une chaîne en LONG ou DOUBLE suivant la chaîne */
-
-
-
- Ces fonctions convertissent sur place : elles ne retourne aucune valeur.
-
-
-
- La valeur de l'argument est enregistrées dans une union. Les membres sont :
-
- IS_STRING: arg1->value.str.val
- IS_LONG: arg1->value.lval
- IS_DOUBLE: arg1->value.dval
-
-
-
- Gestion de la mémoire dans une fonction
-
- Toute la mémoire nécessaire à une fonctoin doit être allouée avec emalloc() ou
- estrdup(). Ces fonctions ont le gout et l'odeur des classiques malloc() et
- strdup(). La mémoire doit êtrel libérée avec efree().
-
-
-
- Il y a deux types de mémoire dans ce programme : la mémoire qui est retournée à l'
- analyseur, et la mémoire qui nécessaire pour le stockage temporaire dans la fonction.
- Lorsque vous assignes une chaîne dans une variable qui est retournée à l'analyseur,
- assurez vous de bien allouer la mémoire avec emalloc() ou estrdup(). Cette mémoire
- ne doit JAMAIS être libérée, sauf si vous réécrivez votre original plus loin, dans
- la même fonction (mais ce n'est pas de la programmation propre).
-
-
-
- Pour tous vos besoins en mémoire temporaire/permanante dont vous avez besoin dans
- vos fonctions/librairies, vous devez utiliser les fonctions emalloc(), estrdup(),
- et efree(). Elles se comportent EXACTEMENT comme leur homologues. Tout ce qui
- est créé avec emalloc() ou estrdup() doit être libéré avec efree()
- à un moment ou un autre, à moins que ce ne soit utile ailleurs dans le programme;
- sinon, il va y avoir une fuite de mémoire. La signification de "Elles se comportent
- EXACTEMENT comme leur homologues" est que si vous libérez une variable qui n'a pas
- été créée avec emalloc() ou estrdup(), vous courez droit à la "segmentation fault".
- Soyez alors extrêmement prudent, et libérez toute votre mémoire inutilisée.
-
-
-
- Si vous compilez avec "-DDEBUG", PHP3 affichera la liste de tous les appels à
- emalloc() et estrdup() mais jamais à efree() lorsque ce intervient dans un script
- spécifié.
-
-
-
-
- Affecter une variable dans la table des Symboles
-
- Un grand nombre de macros sont disponibles pour rendre plus facile l'insertion de
- variables dans la table des symboles :
-
-
- SET_VAR_STRING(name,value)
- SET_VAR_DOUBLE(name,value)
- SET_VAR_LONG(name,value)
-
-
-
-
-
- Soyez prudent. La valeur doit être placée dans une portion de mémoire créée avec
- malloc(), sinon le gestionnaire de mémoire essayera de libérer le pointeur plus
- tard. Ne passez aucune mémoire allouée statiquement à SET_VAR_STRING.
-
-
-
-
- Les tables des symboles de PHP 3.0 est une table de hash. A n'importe quel moment,
- &symbol_table est un pointeur sur la table principale, et
- active_symbol_table pointe sur la table actuellement utilisée.
- (ces deux tables peuvent être identiques au démarrage, ou différent, suivant que
- vous etes dans une fonction ou non).
-
-
-
- Les exemples suivants utilisent 'active_symbol_table'. Vous devriez la remplacer par
- &symbol_table si vous voulez travailler sur la table principale.
- De plus, les mêmes fonctions peuvent être appliquées à des tableaux, comme expliqué
- ci dessous.
-
-
-
-
- Vérification de l'existance de $foo dans la table des sympboles
-
-if (hash_exists(active_symbol_table,"foo",sizeof("foo"))) { existe... }
-else { n'existe pas }
-
-
-
-
- Rechercher la taille d'une variable dans la table des symboles
-
-hash_find(active_symbol_table,"foo",sizeof("foo"),&pvalue);
-check(pvalue.type);
-
-
-
- En PHP 3.0, les tableaux sont implémentés en utilisant les mêmes tables de hash que
- les variables. Cela signifie que les deux fonctions ci dessus peuvent être appelées
- pour vérifier la présence de variables dans un tableau.
-
-
-
- Si vous voulez définir un nouveau tableau dans la table des symboles, utiliser le code
- suivant.
-
-
-
- D'abord, vous devez vérifier qu'il n'existe pas, avec hash_exists() ou
- hash_find().
-
-
-
- Puis, initialisez le tableau :
-
-
-
- Initialisation d'un tableau
-
-pval arr;
-
-if (array_init(&arr) == FAILURE) { failed... };
-hash_update(active_symbol_table,"foo",sizeof("foo"),&arr,sizeof(pval),NULL);
-
-
-
- Ce code déclare un nouveau tableau, appelé $foo, dans la table de symbole Ce tableau est vide.
-
-
-
- Voici comment ajouter deux nouvelles entrées dans ce tableau :
-
-
-
-
- Ajout d'entrées dans un tableau.
-
-pval entry;
-
-entry.type = IS_LONG;
-entry.value.lval = 5;
-
-/* définit $foo["bar"] = 5 */
-hash_update(arr.value.ht,"bar",sizeof("bar"),&entry,sizeof(pval),NULL);
-
-/* définit $foo[7] = 5 */
-hash_index_update(arr.value.ht,7,&entry,sizeof(pval),NULL);
-
-/* définit la prochaine place libre dans $foo[],
- * $foo[8], qui sera 5 (comme en php2)
- */
-hash_next_index_insert(arr.value.ht,&entry,sizeof(pval),NULL);
-
-
-
- Si vous voulez modifier une valeur que vous avez inséré dans une table de hash,
- vous devez d'abord la lire dans la table. Pour éviter cette recherche, vous pouvez
- fournir une pval ** à la fonction d'ajout dans la table de hash, et elle modifiera
- la valeur à l'adresse pval *, avec la valeur donnée. Si cette valeur est NULL,
- (comme dans tous les exemples ci dessus), ce paramètre sera ignoré.
-
-
-
- hash_next_index_insert() utiliser plus ou moins la même logique que
- "$foo[] = bar;" in PHP 2.0.
-
-
- Si vous construisez un tableau, pour le retourner, vous pouvez l'initialiser comme ceci
- :
-
-
-
-if (array_init(return_value) == FAILURE) { échec...; }
-
-
-
- ...puis ajouter les valeurs grâces aux macros:
-
-
-add_next_index_long(return_value,long_value);
-add_next_index_double(return_value,double_value);
-add_next_index_string(return_value,estrdup(string_value));
-
-
-
- Bien sur, si l'ajout n'est pas fait juste après l'initialisation, vous devrez
- d'abord rechercher le tableau :
-
-
-pval *arr;
-
-if (hash_find(active_symbol_table,"foo",sizeof("foo"),(void **)&arr)==FAILURE) { introuvable... }
-else { utilisez arr->value.ht... }
-
-
-
- Notez que hash_find recoit un pointeur sur un pointeur sur pval, et pas un
- pointeur sur pval.
-
-
- Toutes les fonctions d'accès aux hash retourne SUCCES (SUCCES) ou ECHEC (FAILURE), excepté hash_exists(), qui retourne un booléen.
-
-
-
-
- Retourne une valeur simple
-
- Un grand nombre de macros sont disponible pour simplifier le retour des valeurs.
-
-
-
- La macro RETURN_* fixe la valeur de retour, et termine la fonction :
-
- RETURN
- RETURN_FALSE
- RETURN_TRUE
- RETURN_LONG(l)
- RETURN_STRING(s,dup) Si dup est TRUE, duplique la chaîne.
- RETURN_STRINGL(s,l,dup) Retourne la chaîne (s) en spécifiant la longueur (l).
- RETURN_DOUBLE(d)
-
-
-
- La macro RETVAL_* macros fixe la valeur de retour, mais ne termine pas la fonction.
-
- RETVAL_FALSE
- RETVAL_TRUE
- RETVAL_LONG(l)
- RETVAL_STRING(s,dup) Si dup est TRUE, duplique la chaîne
- RETVAL_STRINGL(s,l,dup) Retourne la chaîne (s) en spécifiant la longueur (l).
- RETVAL_DOUBLE(d)
-
-
-
- Les macros ci dessus vont utiliser estrdup() sur les arguments passés. Cela vous
- permet de libérer tranquillement les arguments après avoir appelé cette fonction,
- ou bien, utiliser de la mémoire allouée statiquement.
-
-
-
- Si votre fonction retourne un booléen de succès/erreur, utilisez toujours
- RETURN_TRUE et RETURN_FALSE respectivement.
-
-
- Retourner des valeurs complexes
-
- Votre fonction peut aussi retourner des valeurs complexes, tels que des objets ou
- tableaux.
-
-
- Retourner un objet:
-
-
- Appeler object_init(return_value).
- Remplissez les valeurs. Les fonctions utilisables sont listées ci
- dessous.
- Eventuellement, enregistrez les fonctions pour cet objet.
- Afin de lire des valeurs de cet objet, la fonction doit lire dans "this",
- dans la table de symbole active active_symbol_table. Son type doit être
- IS_OBJECT, et c'est une table de hash basique. (i.e., vous pouvez utiliser les
- fonctions habituelles de .value.ht). L'enregistrement réél peut être fait comme suit :
-
-add_method( return_value, function_name, function_ptr );
-
-
-
-
- Les fonctions d'accès aux objets sont :
-
- add_property_long( return_value,
- property_name, l ) - Ajoute un membre nommé 'property_name', de type long, égal à
- 'l'
- add_property_double( return_value,
- property_name, d ) - Idem, ajoute un double
- add_property_string( return_value,
- property_name, str ) - Idem, ajoute une chaîne
- add_property_stringl( return_value,
- property_name, str, l ) - Idem, ajoute une chaîne de longueur 'l'.
-
-
-
- Retournez un tableau :
-
-
- Appelez array_init(return_value).
- Remplisez les valeurs. Les fonctions disponibles sont listées
- ci dessous.
-
-
-
- Les fonctions utilisées pour accéder à un tableau sont :
-
- add_assoc_long(return_value,key,l) - Ajoute une entrée
- associative avec la clé 'key' et la valeur 'l', de type long
- add_assoc_double(return_value,key,d) - Ajoute une entrée
- associative avec la clé 'key' et la valeur 'l', de type double
- add_assoc_string(return_value,key,str,duplicate)
- add_assoc_stringl(return_value,key,str,length,duplicate)
- specify the string length
- add_index_long(return_value,index,l) - Ajoute
- une entrée d'index index' avec la valeur 'l', de type long
- add_index_double(return_value,index,d)
- add_index_string(return_value,index,str)
- add_index_stringl(return_value,index,str,length)
- - spécifie la longueur de la chaîne.
- add_next_index_long(return_value,l) - ajoute une entrée tableau,
- dans le prochain offset libre, de longueur 'l', de type long
- add_next_index_double(return_value,d)
- add_next_index_string(return_value,str)
- add_next_index_stringl(return_value,str,length)
- - specify the string length
-
-
-
- Using the resource list
-
- PHP 3.0 dispose de standard pour traiter un certains nombre de ressources.
- Ils remplacent tous les listes de PHP 2.0.
-
-
-
- Fonctions accessibles :
-
-
- php3_list_insert(ptr, type) - retourne l'identifiant 'id'
- de la nouvelle ressource insérée.
- php3_list_delete(id) - efface la ressource
- d'identifiant id
- php3_list_find(id,*type)
- - retourne le pointeur de la ressource d'identifiant id,
- et modifie le type 'type'
-
-
- Typiquement, ces fonctions sont utilisées pour les pilotes SQL, mais elles peuvent
- servir n'importe quoi d'autre. Par exemple, conserver un pointeur de fichier.
-
-
-
- La liste standard de code ressemble à ceci :
-
-
-
-
- Ajouter une nouvelle ressource
-
-RESOURCE *resource;
-
-/* ...alloue de la mémoire pour la ressource, et l'acquiert ... */
-/* Ajoute la nouvelel ressource dans la liste */
-return_value->value.lval = php3_list_insert((void *) resource, LE_RESOURCE_TYPE);
-return_value->type = IS_LONG;
-
-
-
-
- Utiliser une ressource existante
-
-pval *resource_id;
-RESOURCE *resource;
-int type;
-
-convert_to_long(resource_id);
-resource = php3_list_find(resource_id->value.lval, &type);
-if (type != LE_RESOURCE_TYPE) {
- php3_error(E_WARNING,"resource index %d has the wrong type",resource_id->value.lval);
- RETURN_FALSE;
-}
-/* ...utiliser la ressource... */
-
-
-
-
- Effacer une ressource existante
-
-pval *resource_id;
-RESOURCE *resource;
-int type;
-
-convert_to_long(resource_id);
-php3_list_delete(resource_id->value.lval);
-
-
-
- Les types de ressources doivent être enregistré dans le fichier php3_list.h, dans
- l'énumération list_entry_type. En plus, il faut penser à ajouter une fonctoin
- de terminaison, pour chaque type de ressource défini, dans le fichier list.c, pour
- la fonction list_entry_destructor() (même si vous n'avez rien de particulier à faire
- lors de la terminaison, vous devez au moins ajouter un cas vide.
-
-
-
-
- Utiliesr la table des ressources persistantes.
-
- PHP 3.0 dispose d'une lieu de stockage des ressources persistantes (i.e., les ressources
- qui doivent être conservées d'un hit à l'autre). Le premier module a utiliser cette
- capacité a été MySQL, et mSQL suivi, ce qui fait que l'on peut se faire une impression
- du fonctionnement de cette fonctoin avec mysql.c. Les fonctions ressemblent à ceci :
-
-
- php3_mysql_do_connect
- php3_mysql_connect()
- php3_mysql_pconnect()
-
-
-
- L'idée conductrice de ces modules est la suivante :
-
- Programmez tout votre module pour qu'il travailel avec les
- ressources standard, comme mentionné dans la section (9).
- Ajoutez un autre fonctoin de connexion, qui vérifie d'abord que
- la ressource existe dans la liste des ressources persistantes. Si c'est le cas,
- enregistrez cette ressource comme pour les ressources standard (et grâce à la
- première étape, cela va fonctionner immédiatement). Si la ressource n'existe pas,
- créez la, ajoutez la à la liste de ressources persistantes, et ajoutez la à la
- liste de ressource, ce qui fait que le code va fonctionner, et que le prochain
- appel renvoiera une ressource éxistante. Vous devez enregistrer ces fonctions avec
- un type différent (LE_MYSQL_LINK pour les liens non persistants, et LE_MYSQL_PLINK
- pour les liens persistants).
-
-
-
-
- Si vous jetez un oeil dans mysql.c, vous verrez que, hormis la fonction de connexion
- complexe, rien n'a du être changé dans le module.
-
-
-
- La même interface existe pour la liste des ressources standard, et pour la liste des
- ressources persistantes, seule la 'list' est remplacée par 'plist':
-
-
-
- php3_plist_insert(ptr, type) - retourne l'identifiant 'id'
- de la nouvelle ressource insérée.
- php3_plist_delete(id) - efface la ressource
- d'identifiant id
- php3_plist_find(id,*type)
- - retourne le pointeur de la ressource d'identifiant id,
- et modifie le type 'type'
-
-
-
- Cependant, il est probable que ces fonctions seront inutiles pour vous, lorsque vous
- essayerez d'implémentez un module persistant. Typiquement, on utiliser le fait que
- la liste de ressources persistante est une table de hash. Par exemple, dans les modules
- MySQL/mSQL, lors d'un appel à pconnect(), la fonction construit une chaîne avec
- l'hôte/utilisateur/mot_de_passe, et l'utilise pour enregistrer dans la table de hash.
- Au prochain appel, avec les mêmes hôte/utilisateur/mot_de_passe, la même clé sera
- générée, et la ressource associée sera retrouvée.
-
-
-
- Jusqu'à ce que la documentation s'étoffe, jetez un oeil aux fichiers mysql.c ou msql.c
- pour voir comment implémentez vos accès aux ressources persistantes.
-
-
-
- Une chose importante à noter : les ressources qui sont enregistrées dans la liste
- de ressource persistante ne DOIVENT PAS être allouée avec le gestionnaire de mémoire
- PHP, c'est à dire qu'elles ne doivent pas être créée avec emalloc(), estrdup(), etc.
- Au contraire, il faut utiliser les fonctions standard malloc(), strdup(), etc.
- La raison est for simple : à la fin de la requête, la mémoire sera supprimée par le
- gestionnaire. Etant donné que les liens persistants doivent être conservés, il ne
- faut pas utiliser le gestionnaire de mémoire.
-
-
-
- Lorsque vous enregistrez une ressource qui sera placé dans la liste de ressource
- persistantes, il faut ajouter les destructeurs dans les deux listes de ressources,
- persistante ou pas. Le destructeur de la liste de ressources non persistantes ne doit
- rien faire du tout, tandis que celui de la liste de ressources persistantes doit
- libérer proprement toutes les ressources acquises (mémoire, lien SQL...). Commep pour
- les ressources non persistantes vous DEVEZ ajouter un destructeur, même si il ne fait
- rien. N'oubliez pas que emalloc() et compagnie ne doivent pas être utilisé en
- conjonction avec la liste de ressources persistantes, et donc, vous ne devez pas
- utiliser efree() non plus.
-
-
-
- Ajouter des directives de configuration à l'exécution
-
- De nombreuses caractéristiques de PHP3 peuvent être configurée à l'éxécution. Ces
- directives peuvent apparaitre dans le fichier php3.ini, ou, dans le cas du module
- Apache, dans le fichier .conf. L'avantage de l'avoir dans le fichier .conf, est
- que ces caractéristiques peuvent être configurées dossier par dossier. Cela
- signifie qu'un dossier peut avoir un safe mode exec dir, tandis qu'un autre en
- aura un autre. Cette granularité de la configuration peut être extrêmement pratique
- lorsque le serveur supporte plusieurs serveurs virtuels.
-
-
-
- Les étapes de configuration d'une nouvelle directive sont :
-
-
- Ajouter la directive à la structure php3_ini_structure dans le
- fichier mod_php3.h.
-
- Dans main.c, éditez la fonction php3_module_startup
- et ajoutez l'appel aproprié à cfg_get_string() ou cfg_get_long().
-
-
- Ajoutez la directive, ses restrictions et un commentaire dans
- la structure php3_commands du fichier mod_php3.c. Notez la partie restrictions.
- RSRC_CONF sont des directives qui ne peuvent être disponibles que dans le fichier
- de conf Apache. Toutes les directives OR_OPTIONS peuvent être placées n'importe ou,
- y compris dans un fichier .htaccess.
-
- Soit dans php3take1handler(), soit dans php3flaghandler(), ajoutez
- l'entrée appropriée pour votre directive.
-
- Dans la section de configuration, de _php3_info(), dans le fichier functions/info.c, vous devez ajouter votre configuration.
-
- Finalement, vous devez utiliser votre configuration quelque part.
- Elle sera accessible par php3_ini.directive.
-
-
-
-
- Appeler des fonctions utilisateurs
-
-
- Pour appelrr des fonctions utilisateurs depuis une fonction interne, vous devez utiliser
- la fonction call_user_function.
-
-
-
- call_user_function retourne SUCCESS en cas de succès,
- et FAILURE en cas d'échec, ou si la fonction n'a pas été trouvée. Vous devez vérifier
- cette valeur. Si la réponse est SUCCESS, vous êtes responsble de la destruction de
- retval (ou alors, retournez la comme valeur de réponse de votre fonction). Si la réponse
- est FAILURE, la valeur de retval est indéfinie, et vous ne devez pas y toucher.
-
-
-
- Toutes les fonctions internes qui appelent une fonction utilisateur,
- DOIVENT être réentrante. En particulier, elles ne doivent pas
- utiliser de valeurs globales, ou de variables statiques.
-
-
-
- call_user_function prend 6 arguments :
-
-
-
- HashTable *function_table
-
- La table de hash dans laquelle le fonction doit être recherchée.
-
-
-
- pval *object
-
- Un pointeur sur un objet sur lequel la fonctoin est invoquée. Il devrait être à NULL,
- si on invoque une fonction globale. Si il n'est pas à NULL (ie, il pointe sur un
- objet), l'argument function_table est ignorée, et la liste des fonctions sera lue
- dans l'objet, plutôt que dans l'argument. L'objet PEUT être modifié par la fonction
- qui est appelée (la fonction y aura accès via $this). Si, vous quelque raison, vous
- ne le voulez pas, envoyez une copie de l'ojbet à la place.
-
-
-
- pval *function_name
-
- Le nom de la fonction à appeler. Elle doit être de type pval, IS_STRING, avec les
- valeurs de function_name.str.val et function_name.str.len correctes.
- function_name est modifié par call_user_function -
- il est converti en minuscule. Si vous voulez préserver la casse, envoyez une copie
- du nom de la fonction.
-
-
-
- pval *retval
-
- Un pointeur sur une structure pval, dans laquelle la valeur de retour de la fonction
- sera placée. La structure doit avoir été allouée au préalable,
- - call_user_function ne l'allouera pas.
-
-
-
- int param_count
-
- Le nombre de paramètre passé à la fonction.
-
-
-
- pval *params[]
-
- Un tableau de pointeur sur les valeurs qui vont être passées comme arguments à la
- fonction. Le premier argument est à l'offset 0, le second à l'offset 1,... Le tableau
- est un tableau de pointeurs sur pval; Les pointeurs sont envoyés tels quels à la
- fonction, ceq ui signifie que si la fonction modifie les arguments, les valeurs
- originales seront modifiées. Si vous voulez l'éviter, passez une copie à la place.
-
-
-
- Rapport d'erreurs
-
-
- Pour signaler les erreurs d'une fonction interne, vous devez appelez la fonctoin
- php3_error. Cette fonction prend deux arguments au
- moins : le niveau de l'erreur, et le message d'erreur, sous forme de chaîne de
- caractères. Tous les arguments suivants sont des paramètres de formats de chaîne.
- Les niveaux d'erreurs sont :
-
-
-
- E_NOTICE
-
- Notes ne sont pas affichées par défaut, et indique que le script a rencontré quelque
- chose qui peut être une erreur, mais peut aussi être un événement normal dans la vie
- du script. Par exemple, essayer d'accéder à une valeur qui n'a pas été déclarée, ou
- appeler stat sur un fichier qui n'existe pas.
-
-
-
-
- E_WARNING
-
- Les alertes sont affichées par défaut, mais n'interrompent pas l'éxécution du script.
- Elles indiquent un problème qui doit être intercepté par le script avant que l'appel
- . Par exemple, appeler ereg avec une regex invalide.
-
-
-
-
- E_ERROR
-
- Les erreurs sont aussi affichées par défaut, et l'exécution du script est
- interrompue. Elles indiquent des erreurs qui ne peuvent pas être ignorées, comme des
- problèmes d'allocation de mémoire, par exemple.
-
-
-
-
- E_PARSE
-
- Les erreurs d'analyse de doivent être générées que par l'analyseur. Elles ne sont
- citées ici que dans le but d'être exhaustif.
-
-
-
-
- E_CORE_ERROR
-
- Elles sont similaires aux erreurs E_ERROR, mais elles sont générées par le code
- de PHP. Les fonctions ne doivent pas générer ce genre d'erreur.
-
-
-
-
- E_CORE_WARNING
-
- Elles sont similaires à E_WARNING, mais elles sont générées par le code
- de PHP. Les fonctions ne doivent pas générer ce genre d'erreur.
-
-
-
-
-
-
+
+ Développement PHP
+
+
+
+
+ Adding functions to PHP3
+
+ Prototypes de fonctions
+
+ Toutes les fonctions suivent le schéma suivant :
+
+void php3_foo(INTERNAL_FUNCTION_PARAMETERS) {
+
+}
+
+ Même si votre fonction ne prend aucun argument, c'est comme cela qu'elle doit être
+ appelée.
+
+
+
+
+ Arguments de fonctions
+
+ Les arguments sont toujours de type val. Ce type contient un membre de type
+ union, qui indique le type réél d'argument. De cette façon,
+ si votre fonction prend deux arguments, elle ressemble à ceci :
+
+
+
+
+ Argument de fonction de lecture
+
+pval *arg1, *arg2;
+if (ARG_COUNT(ht) != 2 || getParameters(ht,2,&arg1,&arg2)==FAILURE) {
+ WRONG_PARAM_COUNT;
+}
+
+
+
+ NOTE: Les arguments peuvent être passé par valeur ou par
+ référence. Dans les deux cas, vous devez passer &(pval *)
+ à getParameters. Si vous voulez vérifier que le n-ième
+ paramètre a été passé par référence
+ ou par valeur, vous devez utiliser la fonction
+ ParameterPassedByReference(ht,n). Elle retournera 1 ou 0.
+
+
+
+ Lorsque vous modifiez l'un des paramètres, qu'ils soient envoyés
+ par référence ou par valeur, vous pouvez le passer à
+ pval_destructor pour le réinitialiser, ou, s'il s'agit d'un tableau et
+ que vous voulez ajouter des valeurs, vous pouvez utiliser des fonctions
+ similaires à celles qui sont dans internal_functions.h, qui manipule
+ return_value comme tableau.
+
+
+
+ Par ailleurs, si vous modifiez un paramètre en IS_STRING, assurez vous
+ que vous avez bien assigné un nouvelle chaîne avec estrdup
+ et une nouvelle longueur de chaîne. Seulement après, vous pouvez
+ modifier le type en IS_STRING. Si vous modifiez une chaîne en IS_STRING
+ ou IS_ARRAY vous devez d'abord appeler le destructeur pval_destructor.
+
+
+
+
+ Fonctions à nombre d'arguments variable
+
+ Une function peut prendre un nombre variable d'arguments. Si votre fonction peut
+ prendre deux ou trois arguments, utiliser la syntaxe suivante :
+
+
+
+
+ Fonctions à nombre d'arguments variable
+
+pval *arg1, *arg2, *arg3;
+int arg_count = ARG_COUNT(ht);
+
+if (arg_count < 2 || arg_count > 3 ||
+ getParameters(ht,arg_count,&arg1,&arg2,&arg3)==FAILURE) {
+ WRONG_PARAM_COUNT;
+}
+
+
+
+
+
+
+ Utiliser les arguments d'une fonction
+
+ De type de chaque argument est stocké dans le champs pval. Ce champs peut
+ prendre les valeurs suivantes :
+
+
+ Types de données interne PHP
+
+
+
+ IS_STRING
+ Chaîne de caractères
+
+
+ IS_DOUBLE
+ Nombre à virgule flottante, en précision double
+
+
+ IS_LONG
+ Entier long
+
+
+ IS_ARRAY
+ Tableau
+
+
+ IS_EMPTY
+ Aucune
+
+
+ IS_USER_FUNCTION
+ ??
+
+
+ IS_INTERNAL_FUNCTION
+ ?? (Si ce type ne peut pas être passé à une fonction, effacez le)
+
+
+ IS_CLASS
+ ??
+
+
+ IS_OBJECT
+ ??
+
+
+
+
+
+
+ Si vous recevez un argument d'un type, te que vous voulez l'utiliser
+ avec un autre type, ou si vous voulez simplement forcer le type, vous
+ pouvez utiliser l'une des fonctions de conversion suivantes :
+
+
+convert_to_long(arg1);
+convert_to_double(arg1);
+convert_to_string(arg1);
+convert_to_boolean_long(arg1); /* Si la chaîne est "" ou "0" elle devient 0, 1 sinon */
+convert_string_to_number(arg1); /* Converti une chaîne en LONG ou DOUBLE suivant la chaîne */
+
+
+
+ Ces fonctions convertissent sur place : elles ne retourne aucune valeur.
+
+
+
+ La valeur de l'argument est enregistrées dans une union. Les membres sont :
+
+ IS_STRING: arg1->value.str.val
+ IS_LONG: arg1->value.lval
+ IS_DOUBLE: arg1->value.dval
+
+
+
+ Gestion de la mémoire dans une fonction
+
+ Toute la mémoire nécessaire à une fonction doit être
+ allouée avec emalloc() ou estrdup(). Ces fonctions ont le gout et l'odeur
+ des classiques malloc() et strdup(). La mémoire doit êtrel
+ libérée avec efree().
+
+
+
+ Il y a deux types de mémoire dans ce programme : la mémoire qui est
+ retournée à l'analyseur, et la mémoire qui nécessaire
+ pour le stockage temporaire dans la fonction. Lorsque vous assignez une
+ chaîne dans une variable qui est retournée à l'analyseur,
+ assurez vous de bien allouer la mémoire avec emalloc() ou estrdup().
+ Cette mémoire ne doit JAMAIS être libérée, sauf si
+ vous réécrivez votre original plus loin, dans la même
+ fonction (mais ce n'est pas de la programmation propre).
+
+
+
+ Pour tous vos besoins en mémoire temporaire/permanante dont vous avez
+ besoin dans vos fonctions/librairies, vous devez utiliser les fonctions
+ emalloc(), estrdup() et efree(). Elles se comportent EXACTEMENT comme leurs
+ homologues. Tout ce qui est créé avec emalloc() ou estrdup()
+ doit être libéré avec efree() à un moment ou un
+ autre, à moins que ce ne soit utile ailleurs dans le programme;
+ sinon, il va y avoir une fuite de mémoire. La signification de
+ "Elles se comportent EXACTEMENT comme leurs homologues" est que si vous
+ libérez une variable qui n'a pas été créée
+ avec emalloc() ou estrdup(), vous courez droit à au crash
+ ("segmentation fault"). Soyez alors extrêmement prudent, et
+ libérez toute votre mémoire inutilisée.
+
+
+
+ Si vous compilez avec "-DDEBUG", PHP 3 affichera la liste de tous les appels
+ à emalloc() et estrdup() mais jamais à efree() lorsque celui-ci
+ intervient dans un script spécifié.
+
+
+
+
+ Affecter une variable dans la table des symboles
+
+ Un grand nombre de macros sont disponibles pour rendre plus facile l'insertion de
+ variables dans la table des symboles :
+
+
+ SET_VAR_STRING(name,value)
+ SET_VAR_DOUBLE(name,value)
+ SET_VAR_LONG(name,value)
+
+
+
+
+
+ Soyez prudent. La valeur doit être placée dans une portion de
+ mémoire créée avec malloc(), sinon le gestionnaire de
+ mémoire essayera de libérer le pointeur plus tard. Ne passez
+ aucune mémoire allouée statiquement à SET_VAR_STRING.
+
+
+
+
+ Les tables des symboles de PHP 3 est une table de hash. A n'importe quel moment,
+ &symbol_table est un pointeur sur la table principale, et
+ active_symbol_table pointe sur la table actuellement utilisée.
+ (ces deux tables peuvent être identiques au démarrage, ou
+ différent, suivant que vous êtes dans une fonction ou non).
+
+
+
+ Les exemples suivants utilisent 'active_symbol_table'. Vous devriez la remplacer
+ par &symbol_table si vous voulez travailler sur la table principale.
+ De plus, les mêmes fonctions peuvent être appliquées
+ à des tableaux, comme expliqué ci dessous.
+
+
+
+
+ Vérification de l'existance de $foo dans la table des sympboles
+
+if (hash_exists(active_symbol_table,"foo",sizeof("foo"))) { existe... }
+else { n'existe pas }
+
+
+
+
+ Rechercher la taille d'une variable dans la table des symboles
+
+hash_find(active_symbol_table,"foo",sizeof("foo"),&pvalue);
+check(pvalue.type);
+
+
+
+ En PHP 3.0, les tableaux sont implémentés en utilisant les
+ mêmes tables de hash que les variables. Cela signifie que les deux
+ fonctions ci dessus peuvent être appelées pour vérifier
+ la présence de variables dans un tableau.
+
+
+
+ Si vous voulez définir un nouveau tableau dans la table des symboles,
+ utilisez le code suivant.
+
+
+
+ D'abord, vous devez vérifier qu'il n'existe pas, avec hash_exists() ou
+ hash_find().
+
+
+
+ Puis, initialisez le tableau :
+
+
+
+ Initialisation d'un tableau
+
+pval arr;
+
+if (array_init(&arr) == FAILURE) { failed... };
+hash_update(active_symbol_table,"foo",sizeof("foo"),&arr,sizeof(pval),NULL);
+
+
+
+ Ce code déclare un nouveau tableau, appelé $foo, dans la table de symbole Ce tableau est vide.
+
+
+
+ Voici comment ajouter deux nouvelles entrées dans ce tableau :
+
+
+
+
+ Ajout d'entrées dans un tableau.
+
+pval entry;
+
+entry.type = IS_LONG;
+entry.value.lval = 5;
+
+/* définit $foo["bar"] = 5 */
+hash_update(arr.value.ht,"bar",sizeof("bar"),&entry,sizeof(pval),NULL);
+
+/* définit $foo[7] = 5 */
+hash_index_update(arr.value.ht,7,&entry,sizeof(pval),NULL);
+
+/* définit la prochaine place libre dans $foo[],
+ * $foo[8], qui sera 5 (comme en php2)
+ */
+hash_next_index_insert(arr.value.ht,&entry,sizeof(pval),NULL);
+
+
+
+ Si vous voulez modifier une valeur que vous avez inséré dans une table de hash,
+ vous devez d'abord la lire dans la table. Pour éviter cette recherche, vous pouvez
+ fournir une pval ** à la fonction d'ajout dans la table de hash, et elle modifiera
+ la valeur à l'adresse pval *, avec la valeur donnée. Si cette valeur est NULL,
+ (comme dans tous les exemples ci dessus), ce paramètre sera ignoré.
+
+
+
+ hash_next_index_insert() utiliser plus ou moins la même logique que
+ "$foo[] = bar;" in PHP 2.0.
+
+
+ Si vous construisez un tableau, pour le retourner, vous pouvez l'initialiser comme ceci
+ :
+
+
+
+if (array_init(return_value) == FAILURE) { échec...; }
+
+
+
+ ...puis ajouter les valeurs grâces aux macros:
+
+
+add_next_index_long(return_value,long_value);
+add_next_index_double(return_value,double_value);
+add_next_index_string(return_value,estrdup(string_value));
+
+
+
+ Bien sur, si l'ajout n'est pas fait juste après l'initialisation, vous devrez
+ d'abord rechercher le tableau :
+
+
+pval *arr;
+
+if (hash_find(active_symbol_table,"foo",sizeof("foo"),(void **)&arr)==FAILURE) { introuvable... }
+else { utilisez arr->value.ht... }
+
+
+
+ Notez que hash_find recoit un pointeur sur un pointeur sur pval, et pas un
+ pointeur sur pval.
+
+
+ Toutes les fonctions d'accès aux hash retourne SUCCES (SUCCES) ou ECHEC (FAILURE), excepté hash_exists(), qui retourne un booléen.
+
+
+
+
+ Retourne une valeur simple
+
+ Un grand nombre de macros sont disponible pour simplifier le retour des valeurs.
+
+
+
+ La macro RETURN_* fixe la valeur de retour, et termine la fonction :
+
+ RETURN
+ RETURN_FALSE
+ RETURN_TRUE
+ RETURN_LONG(l)
+ RETURN_STRING(s,dup) Si dup est TRUE, duplique la chaîne.
+ RETURN_STRINGL(s,l,dup) Retourne la chaîne (s) en spécifiant la longueur (l).
+ RETURN_DOUBLE(d)
+
+
+
+ La macro RETVAL_* macros fixe la valeur de retour, mais ne termine pas la fonction.
+
+ RETVAL_FALSE
+ RETVAL_TRUE
+ RETVAL_LONG(l)
+ RETVAL_STRING(s,dup) Si dup est TRUE, duplique la chaîne
+ RETVAL_STRINGL(s,l,dup) Retourne la chaîne (s) en spécifiant la longueur (l).
+ RETVAL_DOUBLE(d)
+
+
+
+ Les macros ci dessus vont utiliser estrdup() sur les arguments passés. Cela vous
+ permet de libérer tranquillement les arguments après avoir appelé cette fonction,
+ ou bien, utiliser de la mémoire allouée statiquement.
+
+
+
+ Si votre fonction retourne un booléen de succès/erreur, utilisez toujours
+ RETURN_TRUE et RETURN_FALSE respectivement.
+
+
+ Retourner des valeurs complexes
+
+ Votre fonction peut aussi retourner des valeurs complexes, tels que des objets ou
+ tableaux.
+
+
+ Retourner un objet:
+
+
+ Appeler object_init(return_value).
+ Remplissez les valeurs. Les fonctions utilisables sont listées ci
+ dessous.
+ Eventuellement, enregistrez les fonctions pour cet objet.
+ Afin de lire des valeurs de cet objet, la fonction doit lire dans "this",
+ dans la table de symbole active active_symbol_table. Son type doit être
+ IS_OBJECT, et c'est une table de hash basique. (i.e., vous pouvez utiliser les
+ fonctions habituelles de .value.ht). L'enregistrement réél peut être fait comme suit :
+
+add_method( return_value, function_name, function_ptr );
+
+
+
+
+ Les fonctions d'accès aux objets sont :
+
+ add_property_long( return_value,
+ property_name, l ) - Ajoute un membre nommé 'property_name', de type long, égal à
+ 'l'
+ add_property_double( return_value,
+ property_name, d ) - Idem, ajoute un double
+ add_property_string( return_value,
+ property_name, str ) - Idem, ajoute une chaîne
+ add_property_stringl( return_value,
+ property_name, str, l ) - Idem, ajoute une chaîne de longueur 'l'.
+
+
+
+ Retournez un tableau :
+
+
+ Appelez array_init(return_value).
+ Remplisez les valeurs. Les fonctions disponibles sont listées
+ ci dessous.
+
+
+
+ Les fonctions utilisées pour accéder à un tableau sont :
+
+ add_assoc_long(return_value,key,l) - Ajoute une entrée
+ associative avec la clé 'key' et la valeur 'l', de type long
+ add_assoc_double(return_value,key,d) - Ajoute une entrée
+ associative avec la clé 'key' et la valeur 'l', de type double
+ add_assoc_string(return_value,key,str,duplicate)
+ add_assoc_stringl(return_value,key,str,length,duplicate)
+ specify the string length
+ add_index_long(return_value,index,l) - Ajoute
+ une entrée d'index index' avec la valeur 'l', de type long
+ add_index_double(return_value,index,d)
+ add_index_string(return_value,index,str)
+ add_index_stringl(return_value,index,str,length)
+ - spécifie la longueur de la chaîne.
+ add_next_index_long(return_value,l) - ajoute une entrée tableau,
+ dans le prochain offset libre, de longueur 'l', de type long
+ add_next_index_double(return_value,d)
+ add_next_index_string(return_value,str)
+ add_next_index_stringl(return_value,str,length)
+ - specify the string length
+
+
+
+ Using the resource list
+
+ PHP 3.0 dispose de standard pour traiter un certains nombre de ressources.
+ Ils remplacent tous les listes de PHP 2.0.
+
+
+
+ Fonctions accessibles :
+
+
+ php3_list_insert(ptr, type) - retourne l'identifiant 'id'
+ de la nouvelle ressource insérée.
+ php3_list_delete(id) - efface la ressource
+ d'identifiant id
+ php3_list_find(id,*type)
+ - retourne le pointeur de la ressource d'identifiant id,
+ et modifie le type 'type'
+
+
+ Typiquement, ces fonctions sont utilisées pour les pilotes SQL, mais elles peuvent
+ servir n'importe quoi d'autre. Par exemple, conserver un pointeur de fichier.
+
+
+
+ La liste standard de code ressemble à ceci :
+
+
+
+
+ Ajouter une nouvelle ressource
+
+RESOURCE *resource;
+
+/* ...alloue de la mémoire pour la ressource, et l'acquiert ... */
+/* Ajoute la nouvelel ressource dans la liste */
+return_value->value.lval = php3_list_insert((void *) resource, LE_RESOURCE_TYPE);
+return_value->type = IS_LONG;
+
+
+
+
+ Utiliser une ressource existante
+
+pval *resource_id;
+RESOURCE *resource;
+int type;
+
+convert_to_long(resource_id);
+resource = php3_list_find(resource_id->value.lval, &type);
+if (type != LE_RESOURCE_TYPE) {
+ php3_error(E_WARNING,"resource index %d has the wrong type",resource_id->value.lval);
+ RETURN_FALSE;
+}
+/* ...utiliser la ressource... */
+
+
+
+
+ Effacer une ressource existante
+
+pval *resource_id;
+RESOURCE *resource;
+int type;
+
+convert_to_long(resource_id);
+php3_list_delete(resource_id->value.lval);
+
+
+
+ Les types de ressources doivent être enregistré dans le fichier php3_list.h, dans
+ l'énumération list_entry_type. En plus, il faut penser à ajouter une fonctoin
+ de terminaison, pour chaque type de ressource défini, dans le fichier list.c, pour
+ la fonction list_entry_destructor() (même si vous n'avez rien de particulier à faire
+ lors de la terminaison, vous devez au moins ajouter un cas vide.
+
+
+
+
+ Utiliesr la table des ressources persistantes.
+
+ PHP 3.0 dispose d'une lieu de stockage des ressources persistantes (i.e., les ressources
+ qui doivent être conservées d'un hit à l'autre). Le premier module a utiliser cette
+ capacité a été MySQL, et mSQL suivi, ce qui fait que l'on peut se faire une impression
+ du fonctionnement de cette fonctoin avec mysql.c. Les fonctions ressemblent à ceci :
+
+
+ php3_mysql_do_connect
+ php3_mysql_connect()
+ php3_mysql_pconnect()
+
+
+
+ L'idée conductrice de ces modules est la suivante :
+
+ Programmez tout votre module pour qu'il travailel avec les
+ ressources standard, comme mentionné dans la section (9).
+ Ajoutez un autre fonctoin de connexion, qui vérifie d'abord que
+ la ressource existe dans la liste des ressources persistantes. Si c'est le cas,
+ enregistrez cette ressource comme pour les ressources standard (et grâce à la
+ première étape, cela va fonctionner immédiatement). Si la ressource n'existe pas,
+ créez la, ajoutez la à la liste de ressources persistantes, et ajoutez la à la
+ liste de ressource, ce qui fait que le code va fonctionner, et que le prochain
+ appel renvoiera une ressource éxistante. Vous devez enregistrer ces fonctions avec
+ un type différent (LE_MYSQL_LINK pour les liens non persistants, et LE_MYSQL_PLINK
+ pour les liens persistants).
+
+
+
+
+ Si vous jetez un oeil dans mysql.c, vous verrez que, hormis la fonction de connexion
+ complexe, rien n'a du être changé dans le module.
+
+
+
+ La même interface existe pour la liste des ressources standard, et pour la liste des
+ ressources persistantes, seule la 'list' est remplacée par 'plist':
+
+
+
+ php3_plist_insert(ptr, type) - retourne l'identifiant 'id'
+ de la nouvelle ressource insérée.
+ php3_plist_delete(id) - efface la ressource
+ d'identifiant id
+ php3_plist_find(id,*type)
+ - retourne le pointeur de la ressource d'identifiant id,
+ et modifie le type 'type'
+
+
+
+ Cependant, il est probable que ces fonctions seront inutiles pour vous, lorsque vous
+ essayerez d'implémentez un module persistant. Typiquement, on utiliser le fait que
+ la liste de ressources persistante est une table de hash. Par exemple, dans les modules
+ MySQL/mSQL, lors d'un appel à pconnect(), la fonction construit une chaîne avec
+ l'hôte/utilisateur/mot_de_passe, et l'utilise pour enregistrer dans la table de hash.
+ Au prochain appel, avec les mêmes hôte/utilisateur/mot_de_passe, la même clé sera
+ générée, et la ressource associée sera retrouvée.
+
+
+
+ Jusqu'à ce que la documentation s'étoffe, jetez un oeil aux fichiers mysql.c ou msql.c
+ pour voir comment implémentez vos accès aux ressources persistantes.
+
+
+
+ Une chose importante à noter : les ressources qui sont enregistrées dans la liste
+ de ressource persistante ne DOIVENT PAS être allouée avec le gestionnaire de mémoire
+ PHP, c'est à dire qu'elles ne doivent pas être créée avec emalloc(), estrdup(), etc.
+ Au contraire, il faut utiliser les fonctions standard malloc(), strdup(), etc.
+ La raison est for simple : à la fin de la requête, la mémoire sera supprimée par le
+ gestionnaire. Etant donné que les liens persistants doivent être conservés, il ne
+ faut pas utiliser le gestionnaire de mémoire.
+
+
+
+ Lorsque vous enregistrez une ressource qui sera placé dans la liste de ressource
+ persistantes, il faut ajouter les destructeurs dans les deux listes de ressources,
+ persistante ou pas. Le destructeur de la liste de ressources non persistantes ne doit
+ rien faire du tout, tandis que celui de la liste de ressources persistantes doit
+ libérer proprement toutes les ressources acquises (mémoire, lien SQL...). Commep pour
+ les ressources non persistantes vous DEVEZ ajouter un destructeur, même si il ne fait
+ rien. N'oubliez pas que emalloc() et compagnie ne doivent pas être utilisé en
+ conjonction avec la liste de ressources persistantes, et donc, vous ne devez pas
+ utiliser efree() non plus.
+
+
+
+ Ajouter des directives de configuration à l'exécution
+
+ De nombreuses caractéristiques de PHP3 peuvent être configurée à l'éxécution. Ces
+ directives peuvent apparaitre dans le fichier php3.ini, ou, dans le cas du module
+ Apache, dans le fichier .conf. L'avantage de l'avoir dans le fichier .conf, est
+ que ces caractéristiques peuvent être configurées dossier par dossier. Cela
+ signifie qu'un dossier peut avoir un safe mode exec dir, tandis qu'un autre en
+ aura un autre. Cette granularité de la configuration peut être extrêmement pratique
+ lorsque le serveur supporte plusieurs serveurs virtuels.
+
+
+
+ Les étapes de configuration d'une nouvelle directive sont :
+
+
+ Ajouter la directive à la structure php3_ini_structure dans le
+ fichier mod_php3.h.
+
+ Dans main.c, éditez la fonction php3_module_startup
+ et ajoutez l'appel aproprié à cfg_get_string() ou cfg_get_long().
+
+
+ Ajoutez la directive, ses restrictions et un commentaire dans
+ la structure php3_commands du fichier mod_php3.c. Notez la partie restrictions.
+ RSRC_CONF sont des directives qui ne peuvent être disponibles que dans le fichier
+ de conf Apache. Toutes les directives OR_OPTIONS peuvent être placées n'importe ou,
+ y compris dans un fichier .htaccess.
+
+ Soit dans php3take1handler(), soit dans php3flaghandler(), ajoutez
+ l'entrée appropriée pour votre directive.
+
+ Dans la section de configuration, de _php3_info(), dans le fichier functions/info.c, vous devez ajouter votre configuration.
+
+ Finalement, vous devez utiliser votre configuration quelque part.
+ Elle sera accessible par php3_ini.directive.
+
+
+
+
+ Appeler des fonctions utilisateurs
+
+
+ Pour appelrr des fonctions utilisateurs depuis une fonction interne, vous devez utiliser
+ la fonction call_user_function.
+
+
+
+ call_user_function retourne SUCCESS en cas de succès,
+ et FAILURE en cas d'échec, ou si la fonction n'a pas été trouvée. Vous devez vérifier
+ cette valeur. Si la réponse est SUCCESS, vous êtes responsble de la destruction de
+ retval (ou alors, retournez la comme valeur de réponse de votre fonction). Si la réponse
+ est FAILURE, la valeur de retval est indéfinie, et vous ne devez pas y toucher.
+
+
+
+ Toutes les fonctions internes qui appelent une fonction utilisateur,
+ DOIVENT être réentrante. En particulier, elles ne doivent pas
+ utiliser de valeurs globales, ou de variables statiques.
+
+
+
+ call_user_function prend 6 arguments :
+
+
+
+ HashTable *function_table
+
+ La table de hash dans laquelle le fonction doit être recherchée.
+
+
+
+ pval *object
+
+ Un pointeur sur un objet sur lequel la fonctoin est invoquée. Il devrait être à NULL,
+ si on invoque une fonction globale. Si il n'est pas à NULL (ie, il pointe sur un
+ objet), l'argument function_table est ignorée, et la liste des fonctions sera lue
+ dans l'objet, plutôt que dans l'argument. L'objet PEUT être modifié par la fonction
+ qui est appelée (la fonction y aura accès via $this). Si, vous quelque raison, vous
+ ne le voulez pas, envoyez une copie de l'ojbet à la place.
+
+
+
+ pval *function_name
+
+ Le nom de la fonction à appeler. Elle doit être de type pval, IS_STRING, avec les
+ valeurs de function_name.str.val et function_name.str.len correctes.
+ function_name est modifié par call_user_function -
+ il est converti en minuscule. Si vous voulez préserver la casse, envoyez une copie
+ du nom de la fonction.
+
+
+
+ pval *retval
+
+ Un pointeur sur une structure pval, dans laquelle la valeur de retour de la fonction
+ sera placée. La structure doit avoir été allouée au préalable,
+ - call_user_function ne l'allouera pas.
+
+
+
+ int param_count
+
+ Le nombre de paramètre passé à la fonction.
+
+
+
+ pval *params[]
+
+ Un tableau de pointeur sur les valeurs qui vont être passées comme arguments à la
+ fonction. Le premier argument est à l'offset 0, le second à l'offset 1,... Le tableau
+ est un tableau de pointeurs sur pval; Les pointeurs sont envoyés tels quels à la
+ fonction, ceq ui signifie que si la fonction modifie les arguments, les valeurs
+ originales seront modifiées. Si vous voulez l'éviter, passez une copie à la place.
+
+
+
+ Rapport d'erreurs
+
+
+ Pour signaler les erreurs d'une fonction interne, vous devez appelez la fonctoin
+ php3_error. Cette fonction prend deux arguments au
+ moins : le niveau de l'erreur, et le message d'erreur, sous forme de chaîne de
+ caractères. Tous les arguments suivants sont des paramètres de formats de chaîne.
+ Les niveaux d'erreurs sont :
+
+
+
+ E_NOTICE
+
+ Notes ne sont pas affichées par défaut, et indique que le script a rencontré quelque
+ chose qui peut être une erreur, mais peut aussi être un événement normal dans la vie
+ du script. Par exemple, essayer d'accéder à une valeur qui n'a pas été déclarée, ou
+ appeler stat sur un fichier qui n'existe pas.
+
+
+
+
+ E_WARNING
+
+ Les alertes sont affichées par défaut, mais n'interrompent pas l'éxécution du script.
+ Elles indiquent un problème qui doit être intercepté par le script avant que l'appel
+ . Par exemple, appeler ereg avec une regex invalide.
+
+
+
+
+ E_ERROR
+
+ Les erreurs sont aussi affichées par défaut, et l'exécution du script est
+ interrompue. Elles indiquent des erreurs qui ne peuvent pas être ignorées, comme des
+ problèmes d'allocation de mémoire, par exemple.
+
+
+
+
+ E_PARSE
+
+ Les erreurs d'analyse de doivent être générées que par l'analyseur. Elles ne sont
+ citées ici que dans le but d'être exhaustif.
+
+
+
+
+ E_CORE_ERROR
+
+ Elles sont similaires aux erreurs E_ERROR, mais elles sont générées par le code
+ de PHP. Les fonctions ne doivent pas générer ce genre d'erreur.
+
+
+
+
+ E_CORE_WARNING
+
+ Elles sont similaires à E_WARNING, mais elles sont générées par le code
+ de PHP. Les fonctions ne doivent pas générer ce genre d'erreur.
+
+
+
+
+ E_USER_ERROR
+
+ E_USER_ERROR est comparable ˆ E_ERROR. Elle est gŽnŽrŽe en PHP par l'utilisation
+ de la fonction trigger_error. Les fonctions ne doivent
+ pas gŽnŽrer ce genre d'erreur.
+
+
+
+
+ E_USER_WARNING
+
+ E_USER_WARNING est comparable ˆ E_WARNING. Elle est gŽnŽrŽe en PHP par
+ l'utilisation de la fonction trigger_error. Les
+ fonctions ne doivent pas gŽnŽrer ce genre d'erreur.
+
+
+
+
+ E_USER_NOTICE
+
+ E_USER_WARNING est comparable ˆ E_NOTICE. Elle est gŽnŽrŽe en PHP par
+ l'utilisation de la fonction trigger_error. Les
+ fonctions ne doivent pas gŽnŽrer ce genre d'erreur.
+
+
+
+
+
+