Transformation d'un tableau php en texte

Mammouth du PHP | 991 Messages

25 oct. 2010, 09:50

Bonjour à toutes la communautés,

Je vous présente une classe de ma confection qui permet de générer rapidement (avec moi c'est tout relatif :mrgreen: ) des visualisations simple des tableaux php, dans un fichier texte simple , sans présence de mise en page "web" du style <table> etc.

La classe est pas vraiment documentée (je sais c'est maaaaaal :non: mais hein :p au départ je penser pas la diffuser :^o ).
Si les dieux du php veulent bien me pardonner 8-)


J'espère que vous allez appreciez mon code a sa juste valeur 8-)

Exemple :

Données entrantes :
$header = array(
 'col1',
 'col2',
 'col3',
 'col4'
);

$content = array(
 array('col1' => 'test1' , 'col2' => 'test2' , 'col3' => 'test3' , 'col4' => 'test4'),
 array('col1' => 'test1' , 'col2' => 'test2' , 'col3' => 'test3' , 'col4' => 'test4'),
 array('col1' => 'test1' , 'col2' => 'test2' , 'col3' => 'tqsdqsdqssdqssd1q515d1qsdest3' , 'col4' => 'test4'),
 array('col1' => 'test1' , 'col2' => 'test2' , 'col3' => 'testqsd3' , 'col4' => 'test4'),
 array('col1' => 'tesqsdqsdt1' , 'col2' => 'test2' , 'col3' => 'test3' , 'col4' => 'test4'),
 array('col1' => 'test1' , 'col2' => 'test2' , 'col3' => 'test3' , 'col4' => 'test4'),
 array('col4' => 'test1' , 'col2' => 'tqsdqsdest2' , 'col3' => 'test3' , 'col1' => 'test45555555555555'),
);
Code de traitement :
include_once 'Ascii_Table.php';
$ascii = new Ascii_Table();
$ascii->setBorderCrossDelimiter('+');
$ascii->setMargin(3);
$ascii->setBorderDelimiter('!');
$ascii->setTextSpacer(' ');
$ascii->setNL("\r\n");
$ascii->assignContent($content);
$ascii->assignHeader($header);
$o = $ascii->draw();
echo $o;

Résultat avec l'utilisation d'un <pre> pour une page web ou un fwrite dans un fichier texte :

Code : Tout sélectionner

+-------------------------+------------------+------------------------------------+------------+ ! col1 ! col2 ! col3 ! col4 ! +-------------------------+------------------+------------------------------------+------------+ ! test1 ! test2 ! test3 ! test4 ! +-------------------------+------------------+------------------------------------+------------+ ! test1 ! test2 ! test3 ! test4 ! +-------------------------+------------------+------------------------------------+------------+ ! test1 ! test2 ! tqsdqsdqssdqssd1q515d1qsdest3 ! test4 ! +-------------------------+------------------+------------------------------------+------------+ ! test1 ! test2 ! testqsd3 ! test4 ! +-------------------------+------------------+------------------------------------+------------+ ! tesqsdqsdt1 ! test2 ! test3 ! test4 ! +-------------------------+------------------+------------------------------------+------------+ ! test1 ! test2 ! test3 ! test4 ! +-------------------------+------------------+------------------------------------+------------+ ! test45555555555555 ! tqsdqsdest2 ! test3 ! test1 ! +-------------------------+------------------+------------------------------------+------------+
Bon la mise en page des éléments sur le forum sont un peu spéciale , mais tester sur un serveur cela marche :priere: enfin chez moi :mrgreen:

<?php
/*
 * @AUTHOR : thehawk
 * @VERSION : 1.00a
 * @CLASSNAME : Ascii_Table
*/

class Ascii_Table {
    private $borderDelimiter	    = '!';
    private $borderCrossDelimiter   = '+';
    private $textSpacer		    = ' ';
    private $borderChar		    = '-';
    private $textMargin		    = 3; // !&nbsp;&nbsp;
    private $contentElement	    = array();
    private $headerElement	    = array();
    private $maxStringLengthPerCols = array();
    private $drawBorder		    = null;
    private $nl			    = "\n";
    /*
     * Public function
    */
    // Setters
    // Ajout des données pour les entetes des tableaux
    public function assignHeader($array) {
	$this->headerElement = $array;
	$this->maxStringLengthHeader($this->headerElement);
    }
    //Ajout des lignes de contenu
    public function assignContent($array) {
	$contentElement = $this->contentElement;
	$this->contentElement = array_merge($contentElement, $array);
	$this->maxStringLength($this->contentElement);
    }
    //Gestion du décalage du contenu du tableau émulation du margin css
    public function setMargin($margin = 3) {
	$this->textMargin = (int)$margin;
    }
    /*
     * Gestion des affectations ascii
    */
    public function setBorderDelimiter($char = '!') {
	$this->borderDelimiter = $char[0];
    }
    public function setBorderCrossDelimiter($char = '+') {
	$this->borderCrossDelimiter = $char[0];
    }
    public function setTextSpacer($char = ' ') {
	$this->textSpacer = $char[0];
    }
    //Gestion du caractère de retour de ligne , utile pour les machines windows , linux etc ....
    public function setNL($char = "\n") {
	$this->nl = $char;
    }
    /*
     * fonction de traitement
    */
    public function draw() {
	return	$this->drawBorder().   $this->nl.
		$this->drawHeader().   $this->nl.
		$this->drawBorder().   $this->nl.
		$this->drawTuples();
	
    }
    /*
     * Algorithme
    */
    // Fonction pour trouver la taille maximal pour chaque colonne avec les données des headers
    private function maxStringLengthHeader($array) {
	$strlen = &$this->maxStringLengthPerCols;
	foreach($array as $element) {
	    if(array_key_exists($element, $strlen)) {
		if(strlen($element) > $strlen[$element]) {
		    $strlen[$element] = strlen($element);
		}
	    }
	    else {
		$strlen[$element] = strlen($element);
	    }
	}
    }
    // Fonction pour trouver la taille maximal pour chaque colonne avec les données du contenu
    private function maxStringLength($array) {
	foreach($array as $key => $element) {
	    if(is_array($element)) {
		$this->maxStringLength($element);
	    }
	    else {
		$strlen = &$this->maxStringLengthPerCols;
		if(array_key_exists($key, $strlen)) {
		    if(strlen($element) > $strlen[$key]) {
			$strlen[$key] = strlen($element);
		    }
		}
		else {
		    $strlen[$key] = strlen($element);
		}
		
	    }
	}
    }
    // On dessine les bordures
    private function drawBorder() {
	if(is_null($this->drawBorder)) {
	    $maxStr = $this->maxStringLengthPerCols;
	    $return = '';
	    $id = 0;
	    foreach($maxStr as $length) {
		$length += $this->textMargin;
		$length += $this->textMargin;
		$suffix = (count($maxStr) == ($id + 1)) ? $this->borderCrossDelimiter : '';
		$return .= $this->_c($this->borderChar , $length , $this->borderCrossDelimiter , $suffix);
		++$id;
	    }
	    $this->drawBorder = $return;
	}
	return $this->drawBorder;
    }
    // On dessine chaque cases
    private function drawTuples() {
	$array = $this->contentElement;
	$r = '';
	
	foreach($array as $o => $element) {
	    foreach($this->headerElement as $k => $col) {
		$end = (count($this->headerElement) == ($k + 1)) ? true : false;
		$r .= $this->drawCell($col, $element[$col], $end);
	    }
	    $h = (count($array) == ($o + 1)) ? '' : $this->nl;
	    $r .= $this->nl.$this->drawBorder.$h;
	}
	return $r;
    }
    // on dessine les entetes de colonnes
    private function drawHeader() {
	$array = $this->headerElement;
	$header = '';
	foreach($array as $id => $element) {
	    $end = (count($array) == ($id +1)) ? true : false;
	    $header .= $this->drawCell($element, $element, $end);
	}
	return $header;
    }
    /*
     * Low Level Function
    */
    // génération des caractère ascii
    private function _c($char , $nb , $prefix = '' , $suffix = '') {
	$return = $prefix;
	for($i = 0 ; $i <= $nb ; $i++) {
	    $return .= $char;
	}
	return $return.$suffix;
    }
    // génération des caractes ascii pour les cellules
    private function drawCell($cols , $texte , $end) {
	$lenght = round(($this->maxStringLengthPerCols[$cols] - strlen($texte)) , 0);
	$lenght += $this->textMargin - strlen($this->borderDelimiter);
	
	$c1 = $this->_c($this->textSpacer , $this->textMargin);
	$c2 = $this->_c($this->textSpacer , $lenght);
	$d = $this->borderDelimiter;
	$e = '';
	if($end) {
	    $e = ''.$this->borderDelimiter;
	}
	return $d.$c1.$texte.$c2.$e;
    }
}
?>

Comme a mon habitude j'ai codé et documenté sa avec mes pieds , mais je prends toutes remarques avec bon coeur :)
Allez @+Tard les amis :)

Remarque le code suivant , aurait donné la même chose :wink:
$header = array(
 'col1',
 'col2',
 'col3',
 'col4'
);

$content = array(
 array('col1' => 'test1' , 'col2' => 'test2' , 'col3' => 'test3' , 'col4' => 'test4'),
 array('col1' => 'test1' , 'col2' => 'test2' , 'col3' => 'test3' , 'col4' => 'test4'),
 array('col1' => 'test1' , 'col2' => 'test2' , 'col3' => 'tqsdqsdqssdqssd1q515d1qsdest3' , 'col4' => 'test4'),
 array('col1' => 'test1' , 'col2' => 'test2' , 'col3' => 'testqsd3' , 'col4' => 'test4'),
 array('col1' => 'tesqsdqsdt1' , 'col2' => 'test2' , 'col3' => 'test3' , 'col4' => 'test4'),
 array('col1' => 'test1' , 'col2' => 'test2' , 'col3' => 'test3' , 'col4' => 'test4'),
 array('col4' => 'test1' , 'col2' => 'tqsdqsdest2' , 'col3' => 'test3' , 'col1' => 'test45555555555555'),
);



include_once 'Ascii_Table.php';
$ascii = new Ascii_Table();
$ascii->assignContent($content);
$ascii->assignHeader($header);
$o = $ascii->draw();
echo $o;
Hawk
DevOps, Symfony4, Hoa

Eléphant du PHP | 74 Messages

01 nov. 2010, 11:59

Bonjour,

J'ai quelques remarques à te faire :mrgreen:

Premièrement, est-ce qu'il serait pas plus pertinent d'ajouter les tuples sans avoir à associer une colonne ?
Ainsi, la création du tableau serait moins "verbeuse" et ça serait l'ordre présent dans ce même tableau qui serait repris.
$content = array(
 array('test1' , 'test2' , 'test3' , 'test4'),
 array('test1' , 'test2' , 'test3' ,  'test4')
);
Pourquoi ne pas ajouter un constructeur avec arguments (header et content en paramètre) ?

Tu pourrais également renommer ta fonction draw en __toString !

Pour instancier et afficher le tableau il suffirait alors d'écrire ça :
$header = array('col1', 'col2', 'col3', 'col4');

$content = array(
 array('test1' , 'test2' , 'test3' , 'test4'),
 array('test1' , 'test2' , 'test3' ,  'test4')
);

include_once 'Ascii_Table.php';
$ascii = new Ascii_Table($header,$content);
echo $ascii;
:idea:

Mammouth du PHP | 991 Messages

03 nov. 2010, 20:15

Bonjour,

J'ai quelques remarques à te faire :mrgreen:

Premièrement, est-ce qu'il serait pas plus pertinent d'ajouter les tuples sans avoir à associer une colonne ?
Ainsi, la création du tableau serait moins "verbeuse" et ça serait l'ordre présent dans ce même tableau qui serait repris.
$content = array(
 array('test1' , 'test2' , 'test3' , 'test4'),
 array('test1' , 'test2' , 'test3' ,  'test4')
);
Pourquoi ne pas ajouter un constructeur avec arguments (header et content en paramètre) ?

Tu pourrais également renommer ta fonction draw en __toString !

Pour instancier et afficher le tableau il suffirait alors d'écrire ça :
$header = array('col1', 'col2', 'col3', 'col4');

$content = array(
 array('test1' , 'test2' , 'test3' , 'test4'),
 array('test1' , 'test2' , 'test3' ,  'test4')
);

include_once 'Ascii_Table.php';
$ascii = new Ascii_Table($header,$content);
echo $ascii;
:idea:
Concernant ta première remarques , ce tableau a était conçu pour faire des export de base de données , et ton principe de ne pas nommer les colonnes nécessite d'avoir les identifiants dans le bon ordre suivant l'ordre d'affichage, en soit ce n'est pas bien génant mais le script a était conçu dans une optique tres précise où la problématique n'a pas était posé :p et puis je trouvais que d'associer une information a une colonne peut importe l'ordre dans le array était pas si mal que ca :lol:

Sinon concernant les autres points , en effet c'est une possibilité :idea:

Cordialement Hawk
DevOps, Symfony4, Hoa