Structure declare

ViPHP
ViPHP | 5924 Messages

21 juil. 2007, 15:15

Bonjour,

J'ai un petit problème pour ceux qui s'intéressent aux recoins de php.
J'ai peut être pas tout capté dans la structure declare, mais j'ai fait ceci :
<?php

header('Content-Type: text/plain');

$test = 0;
declare(ticks=1)
{
	$test++;
	echo microtime(true) . "\n";
	if($test!=10) sleep(1);
}

?>
Et le bloc ne s'exécute qu'une seule fois, car il m'affiche simplement ceci :
1185023191.62
. Ne devrait-il pas s'éxécuter 10 fois ?

Et si je mets ce code :
<?php

header('Content-Type: text/plain');

function tick()
{
	static $test = 0;
	$test++;
	echo microtime(true) . "\n";
	if($test==10) exit();
}

register_tick_function('tick');

declare(ticks=1)
{
	while(true) sleep(1);
}

?>
C'est carrément le serveur httpd qui crashe...

Quelqu'un a-t-il déjà utilisé declare ? Et auquel cas, qu'est ce qui a pu m'échapper ?

Merci de votre aide :)

Mammouth du PHP | 505 Messages

22 juil. 2007, 00:35

Dans le premier cas, je ne vois pas pourquoi il s'éxécuterai 10 fois. Il n'y a aucun boucle.

Dans le 2eme cas, il devrait effectivement s'éxécuter 10 fois, on a bien une fonction qui va exit quand le compteur est = a 10, en revanche, le while(true) sleep dans le déclare ne sert strictement a rien.

une fois register, tu n'as plus qu'a faire un declare(ticks=1); Toutes les fonctions registers seront appelées a chaque tick.
Pour le httpd qui crash, tu es probablement en multithread et declare() n'est pas compatible avec les server multithread.

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

22 juil. 2007, 01:06

while(true) sleep dans le déclare ne sert strictement a rien.
Si tu n'as pas de boucle dans ton block "declare" PHP rentre et sort immédiatement du bloc. Sans "while", pas de boucle, donc on en revient au premier exemple.

À part ça, si mes souvenirs sont bons il y aura une nouvelle utilitée à declare en PHP 6 mais celle-ci m'échappe pour l'instant. Il fût pendant un temps question de désactiver/réactiver unicode par declare, mais je crois que cette piste avait été abandonnée. Pareil pour la déclaration de namespace dans un bloc.

ViPHP
ViPHP | 5924 Messages

22 juil. 2007, 01:34

Est ce qu'on peut m'expliquer en gros comment elle marche cette structure ? Parce que l'explication comme quoi elle s'exécute toutes les N commandes de bas niveau n'est pas claire du tout.

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

22 juil. 2007, 01:49

Avant toute chose, il faut bien séparer l'élément "declare" de la directive "tick". Le premier sert à dire "cette directive s'applique à l'ensemble du code de ce block". On pourrait imaginer avoir un truc du genre (cet exemple n'existe pas)
declare (error_reporting(0))
{
   // code PHP s'exécutant sans contrôle d'erreur
}

// contrôle d'erreur réactivé automatiquement
Donc apparement, le truc avec lequel tu as du mal ce sont les ticks... hmm, je ne saurais pas vraiment l'expliquer, d'autant plus que ma connaissance du sujet est très superficielle. Le mieux pour le résumer serait de le comparer à l'insertion d'une fonction "tick()" toutes les N instructions. Avec "ticks=1"
$a = 'foo';
bar();
...se transforme en
tick();
$a = 'foo';
tick();
bar();
tick();
...où tick() exécute les fonctions qui ont été enregistrées par register_tick_function(). C'est, à ma connaissance, très proche de son fonctionnement réel.

ViPHP
ViPHP | 5924 Messages

22 juil. 2007, 01:52

D'accord, c'est plus clair comme cela.
Reste plus qu'à savoir ce qu'est une commande bas niveau, c'est à dire si c'est une interruption, ou même une instruction assembleur, ou bien au contraire un truc un peu arbitraire...

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

22 juil. 2007, 01:57

En gros, à chaque fois que tu es (ou serais) obligé de mettre un ; pour séparer des instructions.
$a = 'foo';
if (1)
{
   $a = substr(strtoupper($a), 1);
}
else
{
}
...devient
tick();
$a = 'foo';
tick();
if (1)
{
   tick();
   $a = substr(strtoupper($a), 1);
   tick();
}
else
{
   tick();
}
tick();
Je ne sais pas pourquoi le manuel parle de "bas niveau".

ViPHP
ViPHP | 5924 Messages

22 juil. 2007, 02:15

Il ne fait rien entre strtoupper() et substr() et $a = ?

ViPHP
ViPHP | 4674 Messages

22 juil. 2007, 11:00

Quel est l'avantage à utiliser les tick ?

Un declare pourrait alors exécuter un code sans y insérer des ticks c'est ça ?
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

ViPHP
ViPHP | 5924 Messages

22 juil. 2007, 12:07

Non, les ticks, c'est justement l'intérêt du déclare. L'avantage, c'est que normalement, à ce que je crois, tu peux exécuter plusieurs codes en même temps.

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

22 juil. 2007, 15:40

Il ne fait rien entre strtoupper() et substr() et $a = ?
Pas à ma connaissance.
à ce que je crois, tu peux exécuter plusieurs codes en même temps.
C'est un mythe associé aux ticks, qui est malheureusement faux. Ils ne permettent pas d'exécuter 2 instructions en même temps, il ne font qu'intercaler du code. (c'est pourquoi je disais que mon exemple était très proche de son fonctionnement réel)

En gros, n'essaie pas d'utiliser les ticks pour gagner en performance.

ViPHP
ViPHP | 5924 Messages

22 juil. 2007, 17:38

C'était pas pour augmenter les performances, mais je comptais utiliser pour l'exécution de code en parallèle du code principal, un peu comme des thread. Je trouve dommage qu'il ne soit pas possible d'utiliser certaines commandes de manière asynchrone.

ViPHP
ViPHP | 4674 Messages

22 juil. 2007, 22:06

Si je comprends bien : on définit un tick (comment on traduit ça en français ? une « coche » :P), puis on lance l'éxecution du tick dans un bloc declare. On spécifie l'intervalle d'éxecution lors de la déclaration d'un bloc declare. Ai-je tout bien compris ? A vous de me ploussoyer ou de me moussoyner (il existe pas encore ce verbe ? Ca devrait arriver ;)).

Mais j'aimerais savoir : dans quel cas en avons-nous besoin ?
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).