30

lol :- )
lui c'est la cerise, faut se faire un peu plaisir des fois happy

31

Han j'avais pas vu (ouais je regarde pas trop souvent ce topic) mais:
iwannabeamaki (./17) :
Le souci, c'est que potentiellement tu peux avoir un caractère codé sur 3 octets dont les deux derniers sont les mêmes que les 2 octets qui servent à coder un '§', d'où un faux positif : tu vas couper un caractère UTF-8 en deux, et produire un résultat totalement invalide. C'est peu probable, mais ça peut arriver.
C'est absolument faux ! grin
En plus je suis certain qu'on a déjà du en discuter sur yN (mais dans quel topic… grin). Je croyais aussi que c'était le cas au début, mais c'est une légende urbaine. (Je suis en train de me demander si c'est pas moi qui l'ait lancée au départ… faut que je consulte mon ami google…) En fait il est impossible de confondre des caractères UTF-8 entre eux, car l'encodage a été prévu pour. (Les bits de poids forts diffèrent selon que ce soit le premier caractère de la séquence utf-8 ou non… Il suffit de jeter un coup d'oeil sur l'encodage utf-8 pour comprendre ^^)
iwannabeamaki (./19) :
spa bien l'utf8 ? sad

Ben si mais pas pour le code source grin (déjà t'aurais pu choisir un caractère ASCII pour tes tags, parceque là c'est vraiment chercher les ennuis ^^)
Au contraire, c'est très bien ! (cf. le point précédent ^^)
Il faut juste éviter d'utiliser des caractères unicode pour nommer des variables en PHP. (De mémoire, il me semble que c'est possible)
Car le php ne supporte pas vraiment l'utf-8. (Disons qu'il y a des bidouilles utf-8 et que dans la majorité des cas, tout fonctionne sans souci même si tu ne sais pas trop ce que tu fais… Et pour le reste tu peux toujours t'en démerder si tu sais ce que tu fais)
Non, faut juste coder proprement et arrêter d'essayer de parser une chaine UTF-8 avec une fonction non-UTF-8 pour gagner 3 poulièmes de secondes. Si tu voulais faire un truc rapide, fallait déjà pas choisir PHP tongue
En l'occurrence, c'est parfaitement adapté. (cf le premier point toujours)
En fait le problème de l'utf-8 se situe effectivement dans le fait que les caractères sont encodés sur un nombre variable, mais cela ne joue que lorsque tu veux compter les caractères et non pas les octets. L'autre problème c'est qu'en tant qu'unicode, il y a les caractères combinables (diacritiques), et ça pose de sérieux problèmes pour les comparaisons de chaînes de caractères quelconques. Mais dans le cas de r043v ça ne causait aucun problème ! sad

Bref, j'espère que ça n'a pas changé tous les plans pour rien… De toutes façons j'arrive après la bataille sad
avatarLe scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

32

non ca n'as rien changé j'ai gardé mon § love
mais j'ai tout de même testé tous les char unicode possible ^^"

en tout cas merci pour ces précisions :- )

33

vu l'engouement que vous portez à mon projet, je vous met un shoot du site sur lequel on taffe actuellement, fait avec fastIce à 100%, ca devrais plus vous motiver embarrassed

JPnAfouet

voila le code qui affiche les produits associés :
[nosmile] echo sredisHashFill(redisPrefix.':prdlist', 'design-produit-thumb', function($w,$d,$n) { switch($w) { case 'img': return '[url]images/'.$d['ref'].'/'.$d['ref'].'.1.200.jpg'; break; case 'prix': case 'nom': case 'ref': return $d[$w]; break; default: return ''; break; } }, redisPrefix.':prd:','',function($k,$key,$nb,$nbok) { global $curprdref; if($nbok >= 10 || strpos($k,':') || $k == $curprdref) return 0; return 1; },'shuffle');

la prochaine release intègre des filtres sur les requêtes fillDesign ainsi que des callback de classement

</b> + d\'infos</a></div>'et le design des "thumbs" design-produit-thumb = '<div class="prods-modul"><a href="[url]$ref$/produit"><h1 alt="$nom$">$nom$</h1><figure><img src="$img$" alt="$desc$" width="120" height="180" class="fade" /></figure><b>$prix$ € |

d'ailleurs qq pourrais m'expliquer clairement comment on fait pour mettre n'importe quel char dans un fichier ini ?

34

soyez pas timide, faut signer juste la pacte.jpg

35

nouvelle fonction prenant un élément aléatoire d'une liste et remplissant un design avec, les filtres sont supportés pour évincer certaines entrées non désirées
[nosmile] <?php global $curprdref; $curprdref = getUrlPath(); echo srandRedisHashFill(redisPrefix.':prdlist','design-produit-mod-left',function($w,$d) { switch($w) { case 'img': return '[url]images/'.$d['ref'].'/'.$d['ref'].'.1.200.jpg'; break; case 'prix': case 'nom': case 'ref': return $d[$w]; break; default: return ''; break; } },redisPrefix.':prd:','',function($k,$key) { global $curprdref; return !($k == $curprdref || strpos($k,':')); }); noDesignCache(); ?>

attention, l'utilisation de toute ces nouvelles fonction de design peu "brouiller" noDesignCache, celui ci DOIT être appelé APRÈS ces fonctions de remplissages, autrement c'est le design de ces fonctions qui sera évincé du cache corrigé

36

[nosmile]wow les closure lié à array_map c'est pawa Oo foreach($data as $dta) { $out .= str_replace(array_map(function($w){return '$'.$w.'$';},$keywords),array_map(function($w)use($callback,$dta,$n){return $callback($w,$dta,$n);},$keywords),$design); $n++; }

37

je suis tombé sur des pages benchmarquant foreach, array_walk, array_map, et toute indiquais que foreach étais imbattable

bref je me suis fait mon bench à moi,
source bench
),3); ?>[nosmile]<?php $data = array ( 0 => array ( 'nom' => 'Love Me Body', 'ref' => '8705body..', 'prix' => '31.00', 'txt' => 'Un body plein d\'érotisme en dentelle rouge...', 'img' => '2', ), 1 => array ( 'prix' => '31.00', 'img' => '2', 'ref' => '0303body..', 'txt' => 'Tout en charme ce body avec ses liserets fushia sur résille noire...', 'nom' => 'Heart Body', ), 2 => array ( 'prix' => '31.00', 'img' => '2', 'ref' => '8662body..', 'txt' => 'Captivant body noir, idéal pour une soirée coquine a deux. Le tour de la ceinture est agrémenté de zircons chatoyants, ainsi qu\'une broche sertie de pierres brillantes sur le buste.', 'nom' => 'Forget Me Not Body', ), 3 => array ( 'nom' => 'Combinaison bodystocking Lingerie', 'ref' => 'CR3237body..', 'prix' => '19.99', 'txt' => 'Plus qu\'un simple bodystocking, presqu\'une seconde peau !', 'img' => '2', ), 4 => array ( 'prix' => '27.99', 'img' => '2', 'ref' => 'CR3167body', 'txt' => 'Ensemble très sexy comprenant une guepière à manches longues avec un ruban permettant de cintrer la taille, incluant porte-jarretelles réglable et son string assorti. Couleur : Rose Tailles disponibles : SM ou LXL Matière : 85% Polyestere, 15% Elastane', 'nom' => 'Guepière filet Rose', ), 5 => array ( 'nom' => 'Combinaison bodystocking', 'ref' => '7010-BLKBODY', 'prix' => '19.99', 'txt' => 'Combinaison bodystocking noir...', 'img' => '2', ), 6 => array ( 'prix' => '40.00', 'img' => '2', 'ref' => 'CR3229body', 'txt' => 'Ensemble top et pantalon en dentelle transparente, ultra sexy, ultra glamour....', 'nom' => 'Bodystocking 2 pièces', ), 7 => array ( 'prix' => '15.99', 'img' => '2', 'ref' => 'CR3243body..', 'txt' => 'Combinaison bodystocking avec ouverture a l\'entre-jambe. Taille : S/M Livré en boite rigide.', 'nom' => 'Combinaison bodystocking', ), 8 => array ( 'prix' => '24.99', 'img' => '1', 'ref' => 'CR3093body', 'txt' => 'Body noir tres envoutant, a dentelle et volant sur le devant et resille au dos, avec bretelles rehausse de petits flots et fentes sur la poitrine et a l\'arriere.', 'nom' => 'Body dentelle ouvert', ), 9 => array ( 'nom' => 'clean', 'ref' => 'clean', 'prix' => '999', 'txt' => 'bla!', 'img' => '2', ) ); $keywords = array ( 0 => 'ref', 1 => 'nom', 2 => 'nom', 3 => 'img', 4 => 'desc', 5 => 'prix' ); $callback = function($w,$d,$n) { return 'w:'.$w.' n:'.$n; }; $design='<pre>truc machin chose</pre>'; $tstart = microtime(true); $iterate = 10000; while(--$iterate) { $arrayin = array_map(function($w){return '$'.$w.'$';},$keywords); $out=''; $n=0; reset($data); foreach($data as $dta) { $out .= str_replace($arrayin,array_map(function($w)use($callback,$dta,$n){return $callback($w,$dta,$n);},$keywords),$design); $n++; } } echo '<br> full array map benchmark : '.round(((microtime(true)-$tstart)*1000),3); $tstart = microtime(true); $iterate = 10000; while(--$iterate) { $out=''; $n=0; $arrayin = array(); array_walk($keywords,function($k)use($arrayin){$arrayin[]='$'.$k.'$';}); // faster reset($data); foreach($data as $dta) { $arrayout = array(); array_walk($keywords,function($w)use($arrayout,$callback,$dta,$n) { $arrayout[] = $callback($w,$dta,$n); //array_push($arrayout,$callback($w,$dta,$n)); }); $out .= str_replace($arrayin,$arrayout,$design); $n++; } } echo '<br> full array walk benchmark : '.round(((microtime(true)-$tstart)*1000),3); $tstart = microtime(true); $iterate = 10000; while(--$iterate) { $out=''; $n=0; $arrayin = array(); array_walk($keywords,function($k)use($arrayin){$arrayin[]='$'.$k.'$';}); // faster //foreach($keywords as $w) $arrayin[]='$'.$k.'$'; // slow! //foreach($keywords as $w) array_push($arrayin,'$'.$k.'$'); // slower reset($data); foreach($data as $dta) { $arrayout = array(); reset($keywords); foreach($keywords as $k) $arrayout[] = $callback($w,$dta,$n); $out .= str_replace($arrayin,$arrayout,$design); $n++; } } echo '<br> full foreach benchmark : '.round(((microtime(true)-$tstart)*1000),3); $tstart = microtime(true); $iterate = 10000; while(--$iterate) { $out=''; $n=0; $arrayin = array(); array_walk($keywords,function($k)use($arrayin){$arrayin[]='$'.$k.'$';}); // faster reset($data); foreach($data as $dta) { $out .= str_replace($arrayin,array_map(function($w)use($callback,$dta,$n){return $callback($w,$dta,$n);},$keywords),$design); $n++; } } echo '<br> best combinaison benchmark : '.round(((microtime(true)-$tstart)*1000),3); $tstart = microtime(true); $iterate = 10000; while(--$iterate) { $out=''; $n=0; $arrayin = array(); array_walk($keywords,function($k)use($arrayin){$arrayin[]='$'.$k.'$';}); // faster array_walk($data,function($dta)use($callback,$arrayin,$n,$keywords,$out,$design) { $out .= str_replace($arrayin,array_map(function($w)use($callback,$dta,$n){return $callback($w,$dta,$n);},$keywords),$design); $n++; }); } echo '<br> best combinaison benchmark with replacing the foreach with array walk : '.round(((microtime(true)-$tstart)*1000[/nosmile]


résultats :
full array map benchmark : 2914.525
 full array walk benchmark : 3107.557
 full foreach benchmark : 10894.946
 best combinaison benchmark : 2605.041
 best combinaison benchmark with replacing the foreach with array walk : 3053.353


conclusion : pas de conclusion c'est vraiment de la merde, et les bench que j'avais lu aussi ^^

38

est ce possible de filer une closure à n'importe qu'elle fonction ?

typiquement je voudrais remplacer ca :

array_map(function($w)use($callback,$dta,$n){return $callback($w,$dta,$n);},$keywords);

par en gros ca :

array_map($callback use ($dta,$n),$keywords);

pour que mon callback ai accès à l'élément du tableau que file array_map et au reste des variables que fournis la closure

39

À ma connaissance non, les "closures" de PHP sont assez limitées (à cause de ce "use"), si tu veux pouvoir accéder à tes variables sans ça il faudrait qu'elles soient globales et utiliser "global" à l'intérieur du callback, mais c'est crade :/

Et puis même si l'écriture est pas top ça doit quand même être globalement efficace ton truc là, non ?
avatarAll right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

40

ca marche bien mais c'est débile de lancer une fonction qui simplement lance une autre fonction :/

41

Bah oui mais si tu ne passes pas $dta et $n en globales (et tu as raison de ne pas le faire !) et que tu ne définis pas "$callback" à l'endroit où il est utilisé (j'imagine qu'il est utilisé ailleurs, donc c'est mort ?), en PHP je ne vois pas trop comment tu peux t'en sortir :/

(et il y a pas mal de langages où on a besoin de ce genre de double appel pour simuler exactement l'effet inverse, c'est à dire figer des variables locales comme ce que fait le "use" de PHP ^^)
avatarAll right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

42

$callback est un des argument fourni à la fonction lançant ce bout de code, donc j'y ai carrément accès, autant que $dta et $n ^^

de plus $callback est une fonction anonyme spécifié par l'utilisateur, donc elle pourrais très bien prendre aussi une closure défini par l'user (ce qui va d'ailleurs bien arranger le ./35 car à ce moment la je connaissais pas les closures ^^)


par contre correction du bench, c'est ca de tester sans aller voir que les valeur de retour sont ok tongue
$arrayin = array(); array_walk($keywords,function($k)use($arrayin){$arrayin[]='$'.$k.'$';});ne marche pas, il faut une référence

$arrayin = array(); array_walk($keywords,function($k)use(&$arrayin){$arrayin[]='$'.$k.'$';});et à ce moment la, array_map est plus rapide de 5ms sur 1000 itérations.

#php#

43

je te met le code complet de la fonction qui utilise le callback et ces array_map
[nosmile]
fillDesign
function fillDesign($data, $design, $callback=false) { global $nodesigncache; $savenodesign=$nodesigncache; $nodesigncache=0; $design=getDesign($design); $nodesigncache=$savenodesign; $keywords = array(); $offset=0; // search all keywords in the design $arrayin = array(); for(;;) { $start = strpos($design,'$',$offset); if($start === false) break; $off = $start+1; $end = strpos($design,'$',$off); if($end === false) break; $size = $end-$off; $word = substr($design,$off,$size); if(!isset($keywords[$word])) { $keywords[$word] = $word; $arrayin[$word] = '$'.$word.'$'; } $offset = $end+1; } $out = ''; if($callback !== false) { $n=0; if(is_array($callback)) // callback is function array { foreach($data as $dta) { $out .= str_replace($arrayin,array_map(function($w)use($callback,$dta,$n) { if(isset($callback[$w])) { if(isset($dta[$w])) return $callback[$w]($dta[$w],$n); return $callback[$w]($dta,$n); } else return ''; },$keywords),$design); $n++; } } else { // callback is a generic function, who get word and complete data foreach($data as $dta) { $out .= str_replace($arrayin,array_map(function($w)use($callback,$dta,$n){return $callback($w,$dta,$n);},$keywords),$design); $n++; } } } else foreach($data as $dta) $out .= str_replace($arrayin,array_map(function($w)use($dta){if(isset($dta[$w])) return $dta[$w]; return '';},$keywords),$design); return $out; }


en gros suivant les cas ca lance différemment callback mais la base est très simple et est la même partout

44

vous auriez pu être sympa et me filer la méthode pour la réponse043 voyons embarrassed

lol

sinon, visiblement c'est pas possible de toucher la closure une fois celle ci crée, bien dommage sad

45

La réponse à quoi ? À vrai dire j'ai pas capté où était la question, pas plus qu'entre le post ./42 et la choucroute ^^

Si je comprends bien ton besoin, ce que tu veux c'est effectivement des closures, manque de bol le PHP ne propose pas des "vraies" closures qui ont accès au scope dans lequel elles ont été créées, il s'agit juste d'un hack pour déclarer des fonctions inline mais ça n'apporte rien de plus que si elle avait été déclarée explicitement.
avatarAll right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

46

non mais j'avais rien trouvé de mieux que réponse et voyons tongue

oui ce que je voulais étais simplement faire un append à la closure avec deux trois variables pour justement faire l'appel direct du callback de l'user, mais bon, tant pis, ca aurais été sympa :- )

mais même limité les closures php sont bien utile ca viens de me changer la vie ^^

47

ajout de needPlugin($pluginName) et callPlugin($pluginName,$argsArray)

needPlugin va charger un plugin spécifié, si il ne l'est pas déjà

callPlugin le charge et appelle sa fonction principale

les deux retourne false si le plugin ne peu être chargé, needPlugin renvois true en cas de succès ou si le plugin étais déjà chargé,
callPlugin en cas de succès renverra la sortie 'texte' de l'exécution de la fonction.
[nosmile]
load and call plugin
function needPlugin($plg) { $fn = 'fn_'.$plg; if(function_exists($fn)) return true; $path = module_path.'/'.$plg.'/'.$plg.'.php'; if(is_file($path)) { include($path); return true; } return false; } function callPlugin($plg,$args) { if(false === needPlugin($plg)) return false; $fn = 'fn_'.$plg; ob_start(); $fn($args); $out = ob_get_contents(); ob_end_clean(); return $out; }


pour rappel, un plugin est un fichier simple dans un répertoire placé dans le répertoire (par defaut) "plugins"

exemple pour un plugin nommé "str" : fichier /plugins/str/str.php

une fonction nommé "fn_str" sera la fonction principale du plugin, c'est elle qui sera appelé par callPlugin ou, via le système de template via : §str|mes|arguments§ pour ici le plugin str

mis à part cette fonction principale, c'est très utile pour déclarer de nouvelles fonctions qui n'ont rien à foutre dans le cœur du moteur


exemple :
str.php
} ?>[nosmile]<?php function fn_str($args) { print '<pre>'; print_r($args); print '</pre>'; } function strcut($str, $l=120) { if(strlen($str)<$l) return $str; preg_match("/(.{1,$l})\s/u", $str, $match); return $match[1].'...';

if(!needPlugin('str')) die('impossible de charger le plugin "str"'); print strcut('hello fucking world !!! !! :)',10);
affichera "hello..."

48

"hello fucking world !!! !! :)" très exactement embarrassed
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !

49

(j'ai pas trop lu en détail, mais à mon avis, le strcut(s, 10) ne doit pas être là par hasard trinon)

50

De toute façon, elle est boguée cette fonction embarrassed
avatar

51

La fonction Hello Fucking World ?
avatarLe scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

52

Non, la fonction strcut, et il n'y a pas qu'un seul bogue cheeky
avatar

53

utiliser une regexp pour limiter le nombre de caractères maximal dans une chaine, c'est original ^^

(mais sinon, cas $l == 0 qui provoque une regexp invalide, problèmes avec une chaine vide, problème si la chaine contient un retour à la ligne, etc...)
avatarAll right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

54

Cette fonction devrait être reprise entièrement je pense, parce que le nombre de bogues est impressionnant ^^
Par exemple, si la chaîne fait exactement la longueur demandée, le dernier mot est retiré sans raison. Aussi, une chaîne plus longue que la contrainte ne contenant pas de caractères blancs causera une tentative de lecture à un indice invalide dans un tableau. Enfin, l'un des bogues les plus étranges est certainement celui qui se produit lorsque le premier caractère blanc se trouve après la longueur de contrainte... C'est la fin du premier mot qui est conservée grin
avatar

55

on se calme c'est un exemple bidon que j'avais...
arf, strcut ma coupé :P

en fait la c'est juste un exemple, j'ai récupéré le code sur le net...
vous voulez pas plutôt me chercher des bug du moteur ? :- D

ici c'était pour montrer que vous pouvez intégrer très simplement du code externe, même pourri, rassurez vous le moteur est mieux codé et testé à fond, mais je vous déconseille tout de même la dernière release "publique" qui va charger à chaque coup le .ini embarrassed

esign qq post plus haut quant je faisais if(!isset($keywords[$word])) $keywords[] = $word;par contre vous aviez pas vu l'énormité sur fillD