J’ai été récemment ammené à parser un nombre important de fichiers de log compressés avec Gzip.

Je voulais traiter chaque fichier à la volée, ne pas avoir à écrire chaque fichier décompressé. Pour ce dernier point, rien de plus simple, il suffit d’utiliser les options “-cd” de gzip qui permettent de décompresser et de rediriger vers la sortie standard.

Voici ce à quoi je voulais arriver :
user@hostname$ gzip -cd mon_fichier_de_log.gz | ./parser.php

Concernant le parser PHP, j’ai utilisé les streams qui permettent notament de récupérer ce qui est écrit sur la sortie standard (comme ça tombre bien, n’est ce pas :) ).

La version simple

1. Le traitement du flux



<?php 
$input 
fopen('php://stdin''r'); // ouverture du flux
while (!feof($input)) {
    
$line fgets($input); // lecture ligne par ligne
    
parse($line); // ma fonction pour parser 
}
fclose($input); // fermeture du flux

2. Rendre le script php exécutable

Définir le bang dans le script PHP :

#!/usr/bin/php
<?php


Fixer l’attribut exécutable :
user@hostname$ chmod +x parser.php

3. L’exécution

user@hostname$ gzip -cd mon_fichier_de_log.gz | ./parser.php

Une version plus complète

CI-dessous une version plus structurée, facilement extensible dans laquelle il est possible d’appliquer plusieurs traitement.
<?php

interface ICommandBuilder {
    public function 
addCommand(ICommand $command);
}

interface ICommand {
    public function 
run($str);
    public function 
finalize();
}

/**
 * Read input on stdin and call a list of ICommand on each readed line.
 */
class Phpipe implements ICommandBuilder {
    
    
/**
     * Worker list, all workers are called for each readed line.
     * @var array of ICommand object
     */
    
protected $worker = array();
    
    public function 
__contruct() {}
    
    
/**
     * Append a new worker
     * @param ICommand $command
     * @return self
     */
    
public function addCommand(ICommand $command) {
        
array_push($this->worker$command);
        return 
$this;
    }
    
    
/**
     * Read stdin until feof
     */
    
public function read() {
        
        
$input fopen('php://stdin''r');
        
$exclude = array();
        
        while (!
feof($input)) {
            
$line fgets($input);
            foreach(
$this->worker as $worker) {
                
$worker->run($line);
            }
        }
        
        
fclose($input);
        
$this->finalize();
    }
    
    
/**
     * Call all ICommand::finalize
     */
    
protected function finalize() {
        foreach(
$this->worker as $worker) {
            
$worker->finalize();
        }
    }
    
}

/**
 * ICommand Null pattern
 */
class LineNull implements ICommand {
    public function 
run($str) {
        return;
    }
    public function 
finalize() {
        return;
    }

/**
 * ICommand Set line number and echo line.
 */
class LineEcho implements ICommand {
    
    public function 
run($str) {
        !isset(
$this->i) ?  $this->null;
        echo ++
$this->i': '$str;
    }
    
    public function 
finalize() {
        echo 
"\n";
    }
    

/**
 * ICommand Echo each line reversed.
 */
class LineReverse implements ICommand {
    
    public function 
run($str) {
        echo 
strrev(trim($str))."\n";
    }
    
    public function 
finalize() {}
}

/**
 * ICommand Append each line in a buffer. Buffer is echoed on finalieze() call. 
 */
class LineBuffer implements ICommand {
    
    public 
$buffer '';
    
    public function 
run($str) {
        
$this->buffer .= $str;
    }
    
    public function 
finalize() {
        echo 
$this->buffer;
    }
}

$worker = new LineEcho;

$phpipe = new Phpipe;
$phpipe->addCommand(new LineNull)
    ->
addCommand($worker)
    ->
addCommand(new LineReverse)
    ->
addCommand(new LineBuffer);
$phpipe->read();

echo "terminated\n";

Pour aller plus loin

  • Permettre la sélection du flux en entrée
  • Utiliser les stream de filtrage
, , ,

OpenID-largeOpenID permet d’utiliser le même crédential pour s’authentifier sur des sites différents. Plus besoin de créer un compte sur chaque service en ligne que l’on souhaite utiliser. Autre avantage, OpenId fonctionne de manière décentralisée et n’importe qui peut devenir son propre “hébergeur”. Et ça tombe plutôt bien, c’est ce qu’on va mettre en place grâce à la librairie phpMyId.

Premièrement, récupérer les fichier MyID.config.php et MyID.php sur github, seul le premier fichier sera à éditer.

1. Modifier le fichier de configuration

Ci-dessous les 4 champs à personnaliser.

'auth_username' => 'votre_login',
'auth_password' => 'hash',
'auth_realm' => 'phpMyID',
'idp_url' => 'http://monblog.tld/openid/',

  • auth_username correspond simplement au login que vous souhiatez utiliser.
  • auth_password correpsond au hash (md5) du tuple : ‘login:realm:votre_password’. Voilà comment le créer sous linux :

echo -n 'votre_login:phpMyID:votre_password' | openssl md5

C’est donc le hash généré par la commande précédente qui est renseigné dans ‘auth_password‘.

  • auth_realm est utilisé dans la génération du hash. Libre à vous de le modifier ou de le laisser tel quel.
    idp_url est l’url dans lesquels nous avons déposé les scripts.

2. Upload

Pour notre exemple, nous avons spécifié ‘http://monblog.tld/openid/’ comme url. Nous uploadons donc dans le répertoire ‘openid’ les deux fichiers. Nous pouvons renommer ‘MyID.config.php’ afin de simplifier l’url d’accès.

Nous avons donc :

/openid/index.php
/openid/MyID.php

3. Récupérer son identité

Arrivé à cette étape, vous pouvez utiliser ‘http://monblog.tld/openid/’ comme url de login. C’est bien, mais c’est pas top ;) . Nous allons modifiez une page existente, afin de la faire pointer vers l’authentification OpenID. Outre le fait qu’on peut choisir une url plus simple, cette manipulation a l’avantage de découpler l’url que l’on donne de celle qui fait réellement le boulot.
Cela permettra par exemple de changer de provider OpenID de manière totalement transparente.

Voici les deux lignes à ajouter en header de votre blog par exemple :
<link rel="openid.server" href="http://monblog.tld/openid/" />
<link rel="openid.delegate" href="http://monblog.tld/openid/" />

Voilà, vous pouvez utiliser ‘http://monblog.tld/’ pour vous authentifier sur les sites supportant OpenID.

4. Pour aller plus loin

Nous n’avons fait que survoler les grands principes d’OpenID, je vous invite à consulter le site officiel [en] pour une description détaillée des processus sous-jacents et des possiblités offertes.
Il est par exemple possible de rattacher un profile ou encore un avatar à votre compte.

5. Sources et liens utiles

, ,