7

lundi 30 novembre 2015

[PHP] Utiliser ncurse pour des petits projets php

Alors oui, le curse c'est pas vraiment aimé, puis on en croise de moins en moins. N’empêche que j'aime bien ça,  c'est classe et faire du curse en php c'est rigolo.


La lib Ncurse pour php est "standard" et le man Ncurse peut du coup être utilisé.

Pourquoi  faire ce petit article ?
Pour présenter la lib en php, faire une petite introduction du fonctionnement ...
Au final cette article est peut étre plus pour moi qu'autre chose.

! ATTENTION !
Les programmes écrit en C ont généralement deux fonctionnement True/False.
1) Ceux qui utilisent -1 en cas d'erreur et sinon 0 (plus répandus);
2) Ceux qui font l'inverse (plus classique);
Ncurse est le 1er cas, ne l'oubliez pas dans vos structures de testes.

Installation :
- Installer Ncurse
- Installe PECL
- $ svn checkout http://svn.php.net/repository/pecl/ncurses/ ncurses
- $ cd ncurses/tags/ncurses-1.0.2/trunk/

// J'ai un problème avec cette extension et PECL du coup ...
- $ pecl build

// Sois je copie a la main (crade)
- # cp <LienRetournéParPecl> /usr/lib/php/modules/

// Sois je compille puis install
- $ ./configure && make
- $ sudo make install OU # make install

Les pages a garder sous la main :
- Les couleurs prés définies
- Les Clés du clavier (les clés sont des int 8bit)
- Les actions de souris
- La liste des fonctions de Ncurse (a utiliser avec un ctrl+f)

La base :

Initialiser ncurse puis le détruire.
je vous donne le contenu de mes fonction, la source à la fin.
// Initialisation de la lib
ncurses_init();
// Désactivation de la souris
ncurses_curs_set(0);

// Vérifier si les couleurs sont supporté et les activer
if (ncurses_start_color() === -1) {
    exit('ERR : ncurses_newwin => Color not supported !');
}

// On enregistre la nouvelle window; // (0, 0, 0, 0) = Nombre de rangés, de colonnes, position x, y
$this->window = ncurses_newwin(0, 0, 0, 0);

// On check si la fenêtre est bien initialisé
if ($this->window !== -1) {
    ncurses_refresh();
    // Taille de la fenêtre,  STDSCR = default window, retourne height/width
    ncurses_getmaxyx(STDSCR, $this->size['height'], $this->size['width']);

    ncurses_noecho(); // Ne rien afficher d'exterieur
} else {
    exit('ERR : ncurses_newwin => FAIL !');
}

Histoire d'utiliser exit() proprement on utilise ici __destruct()
    private function __destruct() {
        $this->envSound();
        ncurses_end();
    }
Pour check les inputKey c'est simple, a savoir que les fonction de ncurses sont bloquantes donc pas vraiment intéressantes ... L'astuce est tout simplement d'ouvrir stdin en lecture, le définir comme non bloquant, puis de le lire ... Easy ! Il ne reste qu'a faire un switch pour gérer l'action de vos input.
    private function getStdin()
    {
            $stdin = fopen('php://stdin', 'r');
            stream_set_blocking($stdin, false);
            $this->usedKey = fread($stdin, 1);
    }

En gros voici la base, aprés il y a deux trois fonctions utile qu'il peut étre compliqué a comprendre ou trouver.

Ma fonction de "d'affichage" ce compose de :
- ncurses_wclear // Vide la fenetre
- ncurses_wrefresh // Rafraichir la fenetre
- ncurses_getmaxyx // Reprendre la taille de la fenêtre pour s'adapter a un resize
- ncurses_border // Retirer toutes bordures
pour ce qui concerne le petit coup de nettoyage avant affichage,
 - ncurses_wattron // Remplace les attributs de la fenêtre taille de police, couleur de fond ...
 - ncurses_wattroff // Retour a la normale
 - ncurses_wcolor_set // Changer les couleurs, dépends des couleurs déclaré avec ncurses_init_pair
voila ce qui concerne la partie mise en forme, puis un petit coup de rafraichissement
 - ncurses_wmove // Sortir le curseur du champ (dans ce cas précis)
 - ncurses_wrefresh // Rafraichir la fenetre

Pour gérer l'affichage de char on utilise juste
ncurses_wmove // Bouger le curseur où l'on veut afficher le char
ncurses_waddstr // Ajouter un char a l'emplacement du curseur
Il suffit de faire une boucle pour afficher une string

--- --- ---

Ba rien qu'avec cette mini base là il est possible de faire tout ce que l'on veut ou presque, que ce soit du jeux comme des logiciels. C'est vraiment super simple et pour les personnes qui ne font que du php ça fait le job !

La lib est pas vraiment pas lourde, elle ne bloque pas php (contrairement a php-gtk)
et est simple d'utilisation. En même temps cette lib a toujours était génial, php ou pas.

Voici la source de mon petit snake, bien sur il y a beaucoup d’améliorations possibles, je ne fais notamment que trés rarement du PHP OO, là ce fut un choix pour la porté des variables principalement, et la volonté de faire ça "propre" mais en un seul fichier.
C'est codé pas trop salement et en quelque heures sur deux jours.
http://inuit.iglou.eu/iglou.adrien/Snake/blob/master/snake

Prochaine fois petit tour sur PHP-GTK histoire de pas trop en chi*r si vous voulez débuter avec, je nais pas fini mon projet avec et ne le finirais jamais ...
C'est insupportable (pour moi) de ne pas gérer mes boucles et interactions à la main.



éa, les amis.

samedi 28 novembre 2015

[PHP] Benchmark a base de XDebug et graphiques by kcachegrind

Des bench, des bench, oui mais des bench xdbug !


Alors on trouve des Bench php partout sur le net, mais de deux choses l'une (ou plus):
- Ils ne sont pas actualisé
- La version php et les infos serveurs ne sont pas indiqué
- Chaque bench en contredis d'autres
- Ils utilisent time() et microtime()(plus rarement), n'utilisent pas les fonctions de math ... et presque jamais $_SERVER['REQUEST_TIME']
- Le temps d’exécution est en variation constante, il est donc logique de faire des résultats relatif (%)

Débutons donc avec ces bench qui sont peut être complétement débiles, mais tester par soi même avec des approches différentes c'est sympa :)

Toutes les sources et images sont dispo ici : https://git.iglou.eu/adrien/benchmark_php/tree/master

Méthode :
J'ai volontairement fais des scripts simples avec beaucoup de répétitions, j'ai tenté d'équilibrer le plus possible entre les entités à tester.
Pour tester les entités avec XDB et KCG, chaque entités est dans une fonction.
Les loop sont de 100.000 et ils sont externe à la fonction de l'entité testé, afin de ne pas la prendre en compte dans le résultat.
On obtiens la moyenne par fonction "TempsPour100.000/100.000" tout simplement ... TP100k étant le résultat de la définissions de main par les fonctions

Infos serveur :
- Serveur virtuel utilisé uniquement en teste
- 8Go ram
- 4core 3Ghz

Infos logiciel :
- Archlinux kernel 4.2.4
- Apache 2.4.17-2
- XDebug 2.3.3-1
- Php 5.6.14-1

Infos php :
- Cache désactivé
- GC activé
- Xdebug seulement le profileur est activé

Résultats :

Parcourir un tableau,
img : inuit.iglou.eu/adrien/benchmark_php/raw/master/php_arrayLoop.png
source : https://git.iglou.eu/adrien/benchmark_php/blob/master/php_arrayLoop.php

k = key; v = value; Pv = pointer to value;
Opérateurs de comparaison (égal et n'est pas égal),
img : inuit.iglou.eu/adrien/benchmark_php/raw/master/php_comparisonOperators.png
source : https://git.iglou.eu/adrien/benchmark_php/blob/master/php_comparisonOperators.php


Définir un array,
img : inuit.iglou.eu/adrien/benchmark_php/raw/master/php_deffineArray.png
source : https://git.iglou.eu/adrien/benchmark_php/blob/master/php_deffineArray.php


Utilisation de echo,
img : inuit.iglou.eu/adrien/benchmark_php/raw/master/php_echo.png
source : https://git.iglou.eu/adrien/benchmark_php/blob/master/php_echo.php


Utilisation de echo pour plusieurs variables (concat),
img : inuit.iglou.eu/adrien/benchmark_php/raw/master/php_echo_multiVar.png
source : https://git.iglou.eu/adrien/benchmark_php/blob/master/php_echo_multiVar.php


Définir des variables globales,
img : inuit.iglou.eu/adrien/benchmark_php/raw/master/php_globalVariables.png
source : https://git.iglou.eu/adrien/benchmark_php/blob/master/php_globalVariables.php


Is array ?
img : inuit.iglou.eu/adrien/benchmark_php/raw/master/php_isArray.png
source : https://git.iglou.eu/adrien/benchmark_php/blob/master/php_isArray.php


Afficher une chaine,
img : inuit.iglou.eu/adrien/benchmark_php/raw/master/php_outputAString.png
source : https://git.iglou.eu/adrien/benchmark_php/blob/master/php_outputAString.php


Concaténation d'un chaine,
img : inuit.iglou.eu/adrien/benchmark_php/raw/master/php_stringConcat%C3%A9nation.png
source : https://git.iglou.eu/adrien/benchmark_php/blob/master/php_stringConcatenation.php


If ou Switch ?
img : inuit.iglou.eu/adrien/benchmark_php/raw/master/php_switch.png
source : https://git.iglou.eu/adrien/benchmark_php/blob/master/php_switch.php


Unset me,
img : inuit.iglou.eu/adrien/benchmark_php/raw/master/php_unset.png
source : https://git.iglou.eu/adrien/benchmark_php/blob/master/php_unset.php


Pour ce qui est des licences vu que quand ont partage un truc c'est obligatoire si non vous ne pourrez pas réutiliser quoi que ce soit...
Je conserve la paternité, c'est obligatoire en france.

Donc pour le code :
/*
* Copyright 2015 Kara adrien
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

Pour les images :
Attribution (BY): Le titulaire des droits autorise toute exploitation de l’œuvre, y compris à des fins commerciales, ainsi que la création d’œuvres dérivées, dont la distribution est également autorisé sans restriction, à condition de l’attribuer à son l’auteur en citant son nom. Cette licence est recommandée pour la diffusion et l’utilisation maximale des œuvres.

Comme toujours si vous relevez des erreurs, merci de m'en faire part ça compte dans mes remises en question quotidiennes =D

Si je fais d'autres bench ils seront ajouté ici, peut probable de pondre un autre sujet pour ça. Sauf si les prochains bench sont sous PHP7.



éa, les amis.

vendredi 27 novembre 2015

[recette] Poéle à gaufres

Il y a bien longtemps que je voulais me prendre une poêle a gaufres, c'est pas trop gros et ça se range dans le placard.


On veut bien adrien, mais c'est bon ton truc ?
Ba ... De base non ! Ça ne ressemble vraiment pas au gout d'une gaufre, mais on y reviendra.

Et ça à quel tronche, c'est présentable au moins ?
C'est a dire que ... Nan c'est pas vraiment "présentable" non plus on dirait un genre de gaufre mais en beaucoup plus ... Moins ... Enfin voila quoi.

Mais du coup ça t'as pas fait chier d'acheter ça ?
Au départ j'étais vraiment, mais vraiment pas joice. Puis avec 2/3 expérience ça c'est amélioré.

Alors la recette en question, trouvé sur le net et légèrement modifié.
Pour ~6 Gaufres :
- 125g de farine
- 1/2 sachet de levure
- 1 œufs
- 20cl de lait tiéde
- De l'huile

Mélanger Farine, Levure, Oeufs,
Ajouter Le lait tiéde,
Huiler la poêle et hop mise en cuisson !

Retourner les gaufres quand vous le sentez, ça cuit vraiment vite !

La 1ere face de cuisson est "présentable", la 2eme ... pas vraiment.

Maintenant, si vous laissez ça reposer vous aurez la chance d'avoir une gaufre qui comme elle n'a pas suffisamment gonflé fait éponge et est donc toute mole, et un peu dégueu.

Alors soit vous les manger dans la seconde, soit ... Un fucking coup au grille pain et là, LÀ, pendant 2minutes vous avez une gaufre bien chaude qui est pas loin du gout d'une véritable gaufre. Mais juste pendant 2mn hein, sinon ça ce re gorge d'eau ...

Et sinon t'as un conseil en plus a nous donner ?
Oui, n'achetez pas de poêles a gaufres ...

Sauf si vous préférez avoir ça :


















A la place de ça :

















éa, les amis.