function foo(&$a = null){ ... }
a) est-ce que /null/ est une "bonne valeur par d�faut" ?
(j'ai l'impression que cela cr�� localement un variable
$a initialis�e � null).
b) comment savoir si un param�tre est effectivement transmis?
isset($a), ($a == null) ne semble pas permettre de d�cider.
nota: j'ai bien lu �17 "Making arguments be passed by reference"
et "Default argument values", mais je n'ai trouv� aucun passage
combinant les 2.
Sylvain.
? "variant" ?
> que l'on souhaite
> pouvoir appeler sans transmettre de param�tre:
>
> function foo(&$a = null){ ... }
>
> a) est-ce que /null/ est une "bonne valeur par d�faut" ?
C'est � toi de le savoir. Disons qu'en g�n�ral oui, du moins si tu veux
indiqu� que le param�tre n'a pas �t� transmis *ET* que NULL n'est pas
une valeur licite pour cet argument.
> (j'ai l'impression que cela cr�� localement un variable
> $a initialis�e � null).
nan ?
> b) comment savoir si un param�tre est effectivement transmis?
Dans la mesure o� rien n'emp�che d'appeler la fonction en lui passant
explicitement NULL, tu ne peux pas savoir !-)
Maintenant, si ta question est "comment savoir si la valeur de $a est
NULL", tu a deux tests possibles:
* is_null($a)
* $a === NULL (note les *3* '=')
> isset($a), ($a == null) ne semble pas permettre de d�cider.
D'apr�s la doc, isset() devrait fonctionner (=>"Determine if a variable
is set and is not NULL."). Par contre, c'est un peu overkill puisque tu
sais que $a sera d�finie de toute fa�on.
pour ce qui est de "$a == NULL", (et de tout autre test d'"�galit�" -
hum...), je te recommande de bien lire la doc (op�rateurs de
comparaison), la notion d'"�galit�" en PHP �tant pour le moins
particuli�re :-/
> nota: j'ai bien lu �17 "Making arguments be passed by reference"
> et "Default argument values", mais je n'ai trouv� aucun passage
> combinant les 2.
Ca ne fait gu�re de diff�rence pratique dans ton cas, il me semble.
Tu confonds deux notions : les fonctions � param�tres ayant une
valeur par d�faut et les fonctions variadiques (comme en C).
Tout d'abord, faire une r�f�rence � null en PHP5 est interdit. En
effet, il n'est possible de ne passer que des variables par r�f�rence.
null �tant un scalaire, ce n'est pas une variable. Ton code par d�faut
l�vera une Fatal error � Only variables can be passed by reference �
Quand aux fonctions � nombre variables d'arguments, tu as les
fonctions func_num_arg et func_get_args (attention au pluriel !) qui
fournissent respectivement le nombre d'arguments pass�s � la fonction et
un tableau des arguments pass�s � la fonction.
> a) est-ce que /null/ est une "bonne valeur par d�faut" ?
Oui, mais pas pour une r�f�rence ;)
> (j'ai l'impression que cela cr�� localement un variable
> $a initialis�e � null).
Oui.
> nota: j'ai bien lu �17 "Making arguments be passed by reference"
> et "Default argument values", mais je n'ai trouv� aucun passage
> combinant les 2.
C'est parce que tu ne regardais pas au bon endroit ;)
<http://fr.php.net/manual/en/book.funchand.php>
--
Micka�l Wolff aka Lupus Michaelis
http://lupusmic.org
Seeking for a position <http://lupusmic.org/pro/>
non je ne confonds pas !
le but est bien (ici) d'avoir un seul(!) param�tre variant (pass� par
r�f�rence).
le proto n'est pas variadique, si tu lis bien les *accolades* et non
les parenth�ses, tu liras que le corps de la fonction est ici sans
objet (ou presque), peut �tre que l'�criture suivante permettra de
limiter les mauvaises interpr�tations:
function foo(&$a = null)
{
// il y a surement un corps de fonction
// mais ce n'est pas l'objet de la question
}
> Tout d'abord, faire une r�f�rence � null en PHP5 est interdit.
je ne sais pas ce que voudrais dire "faire une r�f�rence" !
"transmettre une r�f�rence nulle" ou mieux inexistante devrait
�tre interdit / impossible, je m'attendais � cela, ce n'est pas le cas.
> effet, il n'est possible de ne passer que des variables par r�f�rence.
> null �tant un scalaire, ce n'est pas une variable. Ton code par d�faut
> l�vera une Fatal error � Only variables can be passed by reference �
nullement, as-tu essay� ?
j'aurais pr�f�r� qu'il couine sur un des appels mais ce n'est pas
le cas:
function foo(&$a = null){
$a++;
}
$k = 0;
echo $k;
foo($k);
echo $k;
foo();
echo $k;
affiche:
0
1
1
et pas la moindre fatal error.
or en effet, la r�f�rence � un "$a" quand rien n'est transmis ne devrait
pas exister.
> Quand aux fonctions � nombre variables d'arguments
elles ne sont pas le sujet.
>> a) est-ce que /null/ est une "bonne valeur par d�faut" ?
>
> Oui, mais pas pour une r�f�rence ;)
alors on mets quoi ?
en clair, quelle est l'approche la plus PHP possible de:
/* code C++ */
void foo(int* i = NULL)
{
if (i)
*i++;
}
int a = 0;
foo(&a);
foo();
> C'est parce que tu ne regardais pas au bon endroit ;)
> <http://fr.php.net/manual/en/book.funchand.php>
cela n'a rien � voir.
Sylvain.
ok, hormi func_num_args() qui permet (ici) de d�cider.
je note 'ici' car par extension, on pourrait regretter
qu'il ne comptabilise pas les param�tres substitu�s
dans les passages par valeurs, ie
function foo($a = ??){
echo func_num_args();
}
foo(/any/); => 1
foo(); => 0
mais dans ce cas on voudra g�n�ralement traiter la valeur
sans distinction (transmisse ou valeur par d�faut).
Sylvain.
> le but est bien (ici) d'avoir un seul(!) param�tre variant (pass� par
> r�f�rence).
Qu'est-ce que tu appelles � variant � ?
> le proto n'est pas variadique, si tu lis bien les *accolades* et non
> les parenth�ses, tu liras que le corps de la fonction est ici sans
> objet (ou presque), peut �tre que l'�criture suivante permettra de
> limiter les mauvaises interpr�tations:
J'avais bien compris que tes ... ne devaient pas �tre confondus avec
la liste de param�tres. J'essayais de faire avec ce que tu appelle � une
fonction � param. variant �. Les param�tres sont variables par d�faut,
j'essayais juste de comprendre si tu voulais des fonctions avec des
param�tres avec une valeur par d�faut ou des fonctions totalement
variadiques.
Dans le cas des param�tres � valeurs par d�faut, le nombre de
param�tres est **toujours** le m�me, que tu les indiques � l'utilisation
ou non. Dans l'autre cas, le seul moyen est d'utiliser func_get_args.
> function foo(&$a = null)
> {
> // il y a surement un corps de fonction
> // mais ce n'est pas l'objet de la question
> }
>
>> Tout d'abord, faire une r�f�rence � null en PHP5 est interdit.
>
> je ne sais pas ce que voudrais dire "faire une r�f�rence" !
<http://fr2.php.net/manual/en/language.references.php>
>
> "transmettre une r�f�rence nulle" ou mieux inexistante devrait
> �tre interdit / impossible, je m'attendais � cela, ce n'est pas le cas.
�a l'est. Tu es tomb� sur un bogue.
> nullement, as-tu essay� ?
Oui. Mais pas en donnant le scalaire en valeur par d�faut.
> et pas la moindre fatal error.
> or en effet, la r�f�rence � un "$a" quand rien n'est transmis ne devrait
> pas exister.
Vivi, c'est aussi un bogue pour moi. Car si tu �cris foo(null), il
couine. Toi aussi tu as le droit de contribuer <http://bugs.php.net/> ;)
J'ai cherch� un bogue �ventuellement d�j� d�clar�, mais je n'ai rien trouv�.
je viens de tomber sur �a
<http://stackoverflow.com/questions/280385/php-by-reference-parameters-and-default-null>
mais �a ne nous avance pas beaucoup.
>> Quand aux fonctions � nombre variables d'arguments
>
> elles ne sont pas le sujet.
Ben si, le seul moyen de savoir si on a pass� un argument est de
demander commbien d'arguments ont �t� pass�s � la fonction. Et pour
conna�tre ce nombre, il faut utiliser func_num_args.
> alors on mets quoi ?
Rien. Tu peux passer des param�tres surnum�raires sans que
l'interpr�teur couine, et de les exploiter avec func_get_args.
> en clair, quelle est l'approche la plus PHP possible de:
>
> /* code C++ */
>
> void foo(int* i = NULL)
> {
> if (i)
> *i++;
> }
Les pointeurs n'existent pas en PHP, et les r�f�rences n'en sont pas
l'�quivalent. Les r�f�rences en PHP5 se comportent comme les r�f�rences
de Java. Mais pas comme celles de C++, ce serait plut�t �quivalent � un
std::auto_ptr.
>> C'est parce que tu ne regardais pas au bon endroit ;)
>> <http://fr.php.net/manual/en/book.funchand.php>
>
> cela n'a rien � voir.
Ben si, compl�tement.
c'est explicit� dans la texte quot� ("pass� par r�f�rence",
soit "non par valeur"). je ne pensais pas ce terme ambigu.
> J'avais bien compris que tes ... ne devaient pas �tre confondus avec
> la liste de param�tres. [...]
bien, on peux s'en d�sint�resser alors.
>>> Tout d'abord, faire une r�f�rence � null en PHP5 est interdit.
>>
>> je ne sais pas ce que voudrais dire "faire une r�f�rence" !
> <http://fr2.php.net/manual/en/language.references.php>
hmmm, je sais ce qu'est une r�f�rence, merci.
par contre "faire une r�f�rence" ?!... (faire et avoir ne
sont pas les verbes les plus explicites).
>> "transmettre une r�f�rence nulle" ou mieux inexistante devrait
>> �tre interdit / impossible, je m'attendais � cela, ce n'est pas le cas.
> �a l'est. Tu es tomb� sur un bogue.
>> [...]
> Vivi, c'est aussi un bogue pour moi. Car si tu �cris foo(null), il
> couine. Toi aussi tu as le droit de contribuer <http://bugs.php.net/> ;)
bien sur, il traite correctement le passage (effectif) de tout scalaire
(dont 'null') et l'interdit; mais la possibilit� de d�finir une valeur
par d�faut pour une variable-r�f�rence est ambigue (pas n�cessairement
un "bug", juste "ambigu", ce support est peut �tre voulu mais je ne
trouve aucun exemple ni commentaire dans les docs).
>>> Quand aux fonctions � nombre variables d'arguments
>> elles ne sont pas le sujet.
> Ben si, le seul moyen de savoir si on a pass� un argument est de
> demander combien d'arguments ont �t� pass�s � la fonction. Et pour
> conna�tre ce nombre, il faut utiliser func_num_args.
oui, ma 2nd r�ponse, func_num_args() permet en effet de savoir
si le param�tre est effectivement transmis et si c'est la valeur
par d�faut.
>> en clair, quelle est l'approche la plus PHP possible de:
>> /* code C++ */
> Les pointeurs n'existent pas en PHP, et les r�f�rences n'en sont pas
> l'�quivalent. Les r�f�rences en PHP5 se comportent comme les r�f�rences
> de Java. Mais pas comme celles de C++, ce serait plut�t �quivalent � un
> std::auto_ptr.
on va dire que je sais ce qu'est un pointeur ou une r�f, hein.
une r�f. Java est toujours une instance or ici on parle (aussi)
de scalaire pass� par r�f�rence ce qui n'existe pas en Java.
le '&$' de PHP ressemble plus au '&' de C++ et lui interdirait
foo(type& x = /scalar/).
Sylvain.
> function foo(&$a = null){
> $a++;
> }
>
> $k = 0;
> echo $k;
> foo($k);
> echo $k;
> foo();
> echo $k;
>
> affiche:
> 0
> 1
> 1
>
> et pas la moindre fatal error.
> or en effet, la r�f�rence � un "$a" quand rien n'est transmis ne devrait
> pas exister.
Bonjour Sylvain,
As-tu regard� l� ? (note #3, exemple #2) :
http://fr.php.net/manual/fr/language.references.whatdo.php
Cordialement,
Pascal
merci, cela justifie le comportement observ�.
Sylvain.
> hmmm, je sais ce qu'est une r�f�rence, merci.
> par contre "faire une r�f�rence" ?!... (faire et avoir ne
> sont pas les verbes les plus explicites).
Certes, par � faire une r�f�rence � �, j'entends � d�clarer une
r�f�rence � �.
> bien sur, il traite correctement le passage (effectif) de tout scalaire
> (dont 'null') et l'interdit; mais la possibilit� de d�finir une valeur
> par d�faut pour une variable-r�f�rence est ambigue (pas n�cessairement
> un "bug", juste "ambigu", ce support est peut �tre voulu mais je ne
> trouve aucun exemple ni commentaire dans les docs).
J'ai pos� la question sur la ML. On va voir si �a d�clenche une
flamewar et �ventuellement un rapport de bogue ;) Entre temps, j'ai
aussi regard� le source de PHP, mais je ne suis pas parvenu � d�terminer
ce qui se passe � ce niveau. Je ne ma�trise malheureusement pas bison.
> on va dire que je sais ce qu'est un pointeur ou une r�f, hein.
> une r�f. Java est toujours une instance or ici on parle (aussi)
> de scalaire pass� par r�f�rence ce qui n'existe pas en Java.
> le '&$' de PHP ressemble plus au '&' de C++ et lui interdirait
> foo(type& x = /scalar/).
Ne te f�che pas, je pr�f�re dissiper les mal-entendus. J'ai moi-m�me
d�j� �t� embrouill� par ces histoires de r�f�rence (mais c'est surtout
d� au fait que je jongles parfois entre PHP4 et PHP5).
Je reviendrais quand j'aurais des r�ponses pertinentes sur la ML.
Bon, il suffisait de demander au bon endroit. La raison est tellement
�vidente que j'ai honte de ne pas y avoir pens� ^^; Bon, ben c'est
d�finitivement un effet de bord. Voici la r�ponse d'un participant
(David Otton) de la ML PHP General :
� The problem is that you can't pass literals by reference (which makes
sense):
function f(&$a) {}
f(45); // error
But default values must be literals (which also makes sense):
function f($a = $_POST) {} // error
So there's some serious impedance mismatch going on there to make both
features to work together. �
> � The problem is that you can't pass literals by reference (which makes
> sense) ...
J'ai chop� �a, aussi :
http://bugs.php.net/bug.php?id=6343
PP
c'est l'expos� du "probl�me": j'ai envie de dire que l'on ne
traite pas ici d'une "default value" (valeur stock�e par cette
variable) mais bien de l'existence de cette r�f�rence.
par exemple, j'appr�cierais de pouvoir �crire:
function f(&$a = new myClass()){
}
ce qui donne bien sur une erreur car seul un literal (une
valeur imm�diate) est attendu ici.
> So there's some serious impedance mismatch going on there to make both
> features to work together. �
indeed.
merci pour ton suivi et report.
Sylvain.