8797 sujets

Développement web côté serveur, CMS

Bien le bonjour,

Je suis actuellement bloqué sur un projet en php.

En effet, j'ai un fichier texte qui contient des journaux d’évènements comme suivent:

1300809100.513   1057 192.168.221.63 TCP_MISS/200 14454 GET  http://www2.mediadirect.ro/widgets/thumb-realitatea/thumbnail.jpg?  - HIER_DIRECT/178.21.120.30 image/jpeg
1300809106.445    243 192.168.221.63 TCP_MISS/200 14454 GET  http://www2.mediadirect.ro/widgets/thumb-realitatea/thumbnail.jpg?  - HIER_DIRECT/178.21.120.30 image/jpeg


Maintenant je suis dois traiter ce fichier afin de mettre chaque morceaux dans une base de donnée, pour ça, je procède tel que suit:

1°/-Ouverture fichier.
2°/-Lire la ligne n.
3°/-analyser la ligne n, supprimer les espaces, mettre le résultat en tableau indexé.
4°/-mettre chaque éléments du tableau en base de donnée.
4°/-Répéter l'opération 2-3-4 sur chaque lignes du fichier jusqu'à atteindre la fin de celui-ci.

En théorie pas de soucis, en pratique, on fait moins le malin Smiley bawling .
En fait, je n'arrive pas à extraire mes données de mon tableau indexé.

Voici mon code:

<?php
	// - LOG PROCESSING AND DATABASE PROVISIONING - //
	
function logparse() {
	
	// - LOGFILE PARSING AND PROCESSING - //
$squidlogfile = "/srv/www/squid/content/access.log";
$pattern = "/\s+/";

switch (is_readable($squidlogfile)) {
	
	case true:
			$stmt = $db_object->prepare('$db_insert');
                        $res = array();
                        $parsedfile = new SplFileObject("$squidlogfile","r");
				while(!$parsedfile->eof()){
					$lineread = $parsedfile->fgets();
					//print_r ($lineread."<br>"."<hr>");
					$linesplit = preg_split($pattern,$lineread,10,PREG_SPLIT_NO_EMPTY);
						foreach ($linesplit as $index){
							list($timestamp,$duration,$client,...,$type) = $index;
                                                        print_r($timestamp);
						}
				}
			break;
			
	case false:
			echo "the file: $squidlogfile is not readable:"."<br>";
			break;
}
	
	// - DATABASE CONNECTION AND PROVISIONING - //
$lisquiddbconf="/srv/www/squid/config/squidconf.ini";
$db_conf = parse_ini_file($squiddbconf);
$db_driver = $db_conf['db_driver'];
$db_host = $db_conf['db_host'];
$db_port = $db_conf['db_port'];
$db_name = $db_conf['db_name'];
$db_user = $db_conf['db_user'];
$db_password = $db_conf['db_password'];
$db_source = "$db_driver".":"."$db_host".";"."$db_name";
$db_table = 'access_log';
$db_insert = "INSERT INTO $db_table (timestamp,elapsed,client,action,code,size,method,url,ident,hierarchy,source,content) VALUES (a,b,c,...,l,)";

//$db_object = new PDO($db_source, $db_user, $db_password);

switch (is_readable($squiddbconf)) {
	
	case true:
			echo "This file is readable"."<br>";
			echo "$db_source";
			break;
			
	case false:
			echo "this file is not readable:"."<br>";
			break;
}

}

logparse();

?>


Le truc c'est que dans ma boucle foreach ça ne se passe pas comme je le souhaite.
normalement, avec un print_r($0) par exemple, je devrait avoir comme résultat quelque chose du genre:

1300809100.513
1300809106.445


avec un print_r($1) un résultat semblable à:

1057
243


et ainsi de suite.

mais au lieu de ça j'ai un beau...charabia:

111T1Gh-Hi121T1Gh-Hi101T2Gh-Ht111T3Gh-Ht131T3Gh-Ht131T3Gh-Ht151T2Gh-Hi151T5Gh-Ht101T7Gh-Ha111T1Gh-Hi121T6Gh-Ht141T9Gh-Ht191T7Gh-Ht181T2Gh-Ht101T2Gh-Ha141T3Gh-Hi101T7Gh-Hi101T2Gh-Ha


Si un pro du php peut m'aider, je lui en suis reconnaissant. Smiley lol
Modifié par DR I (07 Apr 2011 - 09:27)
vu que chaque élément est séparé du reste par un espace, pourquoi ne pas utiliser la fonction explode() à la place de preg_split() ?

ca donnerai :

$linesplit = explode(' ',$lineread);


Juste une piste...
Salut Nukleo,

Merci de ton aide tout d'abord.

Je n'utilise pas explode en effet, mais ces deux fonctions font casiment la meme chose.
A savoir que j'utilise preg_split afin de faire en sorte que mon tableau résultant ai au maximum 10 entrée.

Mais mon souci ne viens pas tellement de l'utilisation de la fonction de parsing, j'ai l'impression que j'utilise mal la fonction list() ou une fonction plus basse dans le code car si je fait:

print_r($linesplit);


j'ai bien le résultat attendu à savoir:

array(
[0]=>1300809100.513
[1]=>1057
...
[9]=>image/jpeg
)

array(
[0]=>1300809106.445
[1]=>243
...
[9]=>image/jpeg
)

etc Jusqu'à arriver à la fin du fichier.

Maintenant, c'est l'exploitation de ces tableaux qui me pose problème Smiley langue
Ok je viens de relire la definition de list() et en effet il y a un problème car tu extrait les elements de l'array linesplit avant de les envoyer à list().

Au lien de faire le list() dans un foreach() essaye de le faire directement après le preg_split()


$linesplit = preg_split($pattern,$lineread,10,PREG_SPLIT_NO_EMPTY);
list($timestamp,$duration,$client,...,$type) = $linesplit;
Bon bah c'est encore pire sans la boucle foreach, j'ai carrément rien qui s'affiche avec aucune fonction d'affichage (echo(),sprintf() ou print_r etc).

Je sais que je suis pas loin du résultat recherché, c'est rageant.
J'ai fait un petit test (avec et sans foreach) dont le résultat m'a surpris :

$lineread = 'langage hypertexte programmation';
$pattern = "/\s+/";
$linesplit = preg_split($pattern,$lineread,10,PREG_SPLIT_NO_EMPTY);

var_dump($linesplit);
echo'<hr/>';

foreach($linesplit as $index) {
	list($timestamp,$duration,$client) = $index;
	var_dump($timestamp);
	var_dump($duration);
	var_dump($client);
}
echo'<hr/>';

list($timestamp,$duration,$client) = $linesplit;
var_dump($timestamp);
var_dump($duration);
var_dump($client);


sortie :

array
0 => string 'langage' (length=7)
1 => string 'hypertexte' (length=10)
2 => string 'programmation' (length=13)

string 'l' (length=1)

string 'a' (length=1)

string 'n' (length=1)

string 'h' (length=1)

string 'y' (length=1)

string 'p' (length=1)

string 'p' (length=1)

string 'r' (length=1)

string 'o' (length=1)

string 'langage' (length=7)

string 'hypertexte' (length=10)

string 'programmation' (length=13)

--
clairement le foreach pose un problème
Modifié par Nukleo (06 Apr 2011 - 07:58)
Ouep, je viens de faire des tests avec des vardump, et en fait, je crois que le fait d'avoir un while et un foreach c'est pas bon du tout, je vais supprimer le foreach comme ça je sort bien mon tableau correct, mais aprés vas falloir que je fasse une boucle for du style:

$count = count($linesplit) // Compte le nombres d'index dans le tableau.
for ($i=0; $i<=$count; $i++) {
echo $linesplit['$i'];
}


Normalement avec ça je devrait avoir une sortie correct.

Merci de ton aide, je te tiens au courant Smiley cligne
OK ALLELUIA, c’était bien ça Smiley lol

En fait, le foreach est de trop, en effet, le while traite déjà ligne par ligne et genere un tableau de type:

Array(
[0]=>VALUE
)


C'est donc sur ce tableau que je doit traiter les index, et comme je suis déjà dans une boucle, le foreach est inutile car sinon il index l'index du premier tableau d'ou les sortie uniquement sur les premières string de chaque partie.

Je sais pas si je suis trés clair sur l'explication XD

Donc maintenant j'ai un code bien plus propre:


			$parsedfile = new SplFileObject("$squidlogfile","r");
				while(!$parsedfile->eof()){
					$lineread = $parsedfile->fgets();
					$linesplit = preg_split($pattern,$lineread,10,PREG_SPLIT_NO_EMPTY); //Est-un tableau contenant le fichier parsé ex [0]=>1353315988.513 & [1]=>1057 etc.
					list($timestamp,$duration,$client_address,$result_codes,$size,$request_method,$url,$ident_lookup,$hierarchy_code,$type) = $linesplit;
				}


Et là, j'ai bien les valeurs attendue correct dans chaque variables de List().

Maintenant, je m'attaque à la partie, envoie en BDD, je ne clôt donc pas tout de suite le sujet.

Je clôturerais dés que j'aurais fini complètement, ça donnera un exemple de parsing et envoie des données.
DR I a écrit :
OK ALLELUIA, c’était bien ça Smiley lol

hehe Smiley smile

J'ai fait joujou avec ton code pour l'insertion :

function logparse() {

	// - LOGFILE PARSING AND PROCESSING - //

	$squidlogfile = "/srv/www/squid/content/access.log";

	$pattern = "/\s+/";

	switch (is_readable($squidlogfile)) {

		case true:
		$stmt = $db_object->prepare('$db_insert');
		$res = array();
		$lines_to_insert = array();
		$parsedfile = new SplFileObject("$squidlogfile","r");
		
			while(!$parsedfile->eof()){
				$lineread = $parsedfile->fgets();
				$linesplit = preg_split($pattern,$lineread,10,PREG_SPLIT_NO_EMPTY);
				//list($timestamp,$duration,$client,...,$type) = $linesplit;
			
				// on reconstruit la chaine pour insertion en bdd
				$lines_to_insert[] = '(' . implode(','$linesplit) . ')';
			}
			break;

		case false:	echo "the file: $squidlogfile is not readable:"."<br>";
		break;

	}

		// - DATABASE CONNECTION AND PROVISIONING - //

	$lisquiddbconf="/srv/www/squid/config/squidconf.ini";
	$db_conf = parse_ini_file($squiddbconf);
	$db_driver = $db_conf['db_driver'];
	$db_host = $db_conf['db_host'];
	$db_port = $db_conf['db_port'];
	$db_name = $db_conf['db_name'];
	$db_user = $db_conf['db_user'];
	$db_password = $db_conf['db_password'];
	$db_source = "$db_driver".":"."$db_host".";"."$db_name";
	$db_table = 'access_log';

	// concatenation des valeurs a inserer en bdd
	$values_to_insert = implode(',', $lines_to_insert);

	$db_insert = "INSERT INTO $db_table (timestamp,elapsed,client,action,code,size,method,url,ident,hierarchy,source,content) VALUES" . $values_to_insert;

	//$db_object = new PDO($db_source, $db_user, $db_password);

	switch (is_readable($squiddbconf)) {

		case true:
			echo "This file is readable"."<br>";
			echo "$db_source";
			break;

		case false:
			echo "this file is not readable:"."<br>";
			break;
	}
} // fin function logparse()


A moins que tu n'ai absolument besoin de récupérer les données sous forme de variables pour chaque item de ton array $linesplit, même pas besoin de list()
Alors oui, j'ai besoin des variables dans la mesure ou chaque variable correspond à une valeur à mettre dans un champ de la BDD.

Pour ce qui est de la mise en BDD, je galère aussi (décidément, l'objet c'est pas mon pote).

Ce que je fait c'est:

0°/- Je test mon fichier de conf, si OK -> goto 1°/- SINON error.
1°/- Je créer un nouvel objet PDOobject
2°/- Je prépare la requête.
3°/- Je lis chaque ligne du fichier à analyser.
4°/- pour chaque ligne lue j’éclate ces lignes en suppriment les espaces.
5°/- j'affecte une variable à chaque entrée éclatée.
6°/- j'insert en BDD chaque variable dans la même ligne.

le hic, c'est que mon script déconne sur l'entrée en BDD, j'ai le message suivant:

Fatal error: Call to undefined method PDO::execute() in /srv/www/squid/cli/LOGParse.php on line 45


et voici donc le code:

$db_insert = "INSERT INTO $db_table (timestamp,elapsed,client,action,size,method,url,ident,hierarchy,content) VALUES (:timestamp,:duration,:client_address,:result_code,:size,:request_method,:url,:ident_lookup,:hierarchy_code,:type)";

switch (is_readable($squidlogfile)) {
	
case true:
    	$db_object = new PDO($db_source, $db_user, $db_password);
	$db_object->prepare($db_insert);

	$parsedfile = new SplFileObject("$squidlogfile","r");
				
	    while(!$parsedfile->eof()){
		$lineread = $parsedfile->fgets();
		$linesplit = preg_split($pattern,$lineread,10,PREG_SPLIT_NO_EMPTY);

                list($timestamp,$duration,$client_address,$result_codes,$size,$request_method,$url,$ident_lookup,$hierarchy_code,$type) = $linesplit;
		$db_object->execute(array(':timestamp'=>$timestamp,':duration'=>$duration,':client_address'=>$client_address,':result_code'=>$result_code,':size'=>$size,':request_method'=>$request_method,':url'=>$url,':ident_lookup'=>$ident_lookup,':hierarchy_code'=>$hierarchy_code,':type'=>$type));
	    }
			break;
			
	case false:
			echo "the file $squidlogfile is not readable:"."<br>";
			break;
}


Voila, je ne comprend pas trop pourquoi il rale, PDOStatement->Execute existe bien, qu'est ce qu'il me dit le monsieur Smiley eek
Modifié par DR I (06 Apr 2011 - 12:02)
Et voila, j'ai fini mon script, et celui-ci fonctionne correctement Smiley cligne

Merci à Nukleo pour son aide, je vous poste un exemple dés que j'ai un peu de temps.
Il me manque juste à récupérer le dernier enregistrement émis dans la base afin de ne pas réinsérer des données déjà existantes, mais ça, c'est pour plus tard Smiley cligne

Encore merci Smiley cligne