IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Analyser un fichier PHP avec token_get_all [PHP 5.3]


Sujet :

Langage PHP

  1. #1
    Membre confirm�
    Inscrit en
    Mai 2007
    Messages
    183
    D�tails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 183
    Par d�faut Analyser un fichier PHP avec token_get_all
    Bonjour � tous.

    Contexte :

    Je souhaite utiliser la fonction token_get_all : Cette fonction �clate un code source php en multiple "jeton" identifiant le type d'�l�ment php utilis�.

    Mon probl�me:

    Mais bien sur cette fonction marche correctement uniquement si on lui passe en param�tre du code php... et uniquement du code php. Or je veux analyser un fichier PHP, m�me lorsque celui-ci contient de l'HTML m�lang� avec des parties en PHP...

    Je souhaite donc parser un fichier PHP, et en extraire les parties uniquement PHP (si possible en identifiant les lignes) pour utiliser token_get_all : grosso modo ce que fait tidy en HTML (nettoyer et manipuler les documents HTML, et les traiter sous forme de balises hi�rarchis�es.)..
    ..mais en PHP (rep�rer les blocs php) !

    Connaissez-vous une fonction ou une extension qui ferait cela ?

    Merci aux experts (et � leur m�moire ).

  2. #2
    Membre �m�rite Avatar de micetf
    Homme Profil pro
    Professeur des Ecoles
    Inscrit en
    Mai 2009
    Messages
    557
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ard�che (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : Professeur des Ecoles
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2009
    Messages : 557
    Par d�faut
    Peut-�tre qu'une fonction de ce type suffirait ?
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function extrairePHP($source,$destination) {
    	$string=file_get_contents($source);
     
    	preg_match_all('/(<\?php)(.*?)(\?>)/s',$string,$result);
     
    	$codePhp='<?php ';
    	foreach ($result[2] as $bloc) {
    		$codePhp .= $bloc."\n";
    	}
    	$codePhp .= ' ?>';
     
    	file_put_contents($destination,$codePhp);
    }
    Fred

  3. #3
    Membre confirm�
    Inscrit en
    Mai 2007
    Messages
    183
    D�tails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 183
    Par d�faut
    Merci,
    mais je cherche une solution plus carr�, qui marcherait � tous les coups.
    Ce que je veux dire c'est que ta solution ne marcherais pas par exemple avec un php qui contiendrait :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type='text/javascript'>
    function mafonctionjavascript()
    {
    // commentaire avec un malencontreux <%
    }
    </script>
    </head>
    <body onload="mafonctionjavascript('un autre malencontreux <%');" >
    <?php
     $message= "un autre malencontreux <%";
     echo $message;
    ?>
    </body>
    </html>
    Bref, au lieu de r�-inventer la poudre (au risque de faire du code foireux), je chercher un outil qui ferais d�j� �a proprement (et ca serait �tonnant que �a n'existe pas).

  4. #4
    Membre �m�rite Avatar de micetf
    Homme Profil pro
    Professeur des Ecoles
    Inscrit en
    Mai 2009
    Messages
    557
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ard�che (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : Professeur des Ecoles
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2009
    Messages : 557
    Par d�faut
    Je ne peux garantir ma solution,
    je l'ai d'ailleurs modifi�e pour le cas d'une derni�re balise non ferm�e.
    N�anmoins,
    pour l'exemple que tu donnes,
    elle fonctionne parfaitement.
    Je donne donc le code modifi� :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function extrairePHP($source,$destination) {
    	$string=file_get_contents($source);
     
    	preg_match_all('/(<\?php)(.*?)(\?>|$)/s',$string,$result);
     
    	$codePhp='<?php ';
    	foreach ($result[2] as $bloc) {
    		$codePhp .= $bloc;
    	}
    	$codePhp .= ' ?>';
     
    	file_put_contents($destination,$codePhp);
    }
    On ne sait jamais,
    je n'ai peut-�tre pas r�invent� la poudre,
    et l'outil que tu cherches n'existe peut-�tre pas.
    Apr�s tout, ce n'est qu'une expression r�guli�re qui fait tout le travail.

    Fred

  5. #5
    Membre confirm�
    Inscrit en
    Mai 2007
    Messages
    183
    D�tails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 183
    Par d�faut
    Merci Fred pour l'attention que tu porte � mon probl�me,

    Quand je parlais de r�-inventer la poudre ou de code foireux, je ne parlais pas de toi mais de moi ("je"). D'autre part, les limites d'une simple expression rationnelle ne me convienne pas, m�me dans ta seconde version modifi�e. Mon exemple �tait a l'�vidence pas assez clair, je te pr�sente (moi aussi ) une seconde version de mon exemple qui montre les limites de l'expression rationnelle:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Document sans nom</title>
    <script type='text/javascript'>
    function mafonctionjavascript()
    {
    //  <% Ceci n'est pas du php %>
    }
    </script>
    </head>
    <body onload="mafonctionjavascript('<% Ceci n'est pas du php %>');" >
    <?php
     $message= "<?php Ceci n'est pas du php ?>";
     echo $message;
    ?>
    </body>
    </html>
    Extraire correctement toute les balises implique de passer par l'equivalent d'un parser (mais � la sauce HTML-PHP.. pas en XML),
    et il me parait �trange qu'il n'existe pas d'outils d�j� fait..
    ..je continue donc de chercher !

  6. #6
    Membre �m�rite Avatar de micetf
    Homme Profil pro
    Professeur des Ecoles
    Inscrit en
    Mai 2009
    Messages
    557
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ard�che (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : Professeur des Ecoles
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2009
    Messages : 557
    Par d�faut
    D'autre part, les limites d'une simple expression rationnelle ne me conviennent pas, m�me dans ta seconde version modifi�e.
    OK !
    Ce n'est pas grave.
    Mais comme je suis t�tu,
    je propose une derni�re mouture
    qui ne se laisse pas pi�ger par ton dernier exemple.
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function extrairePHP($source,$destination) {
    	$string=file_get_contents($source);
     
    	preg_match_all('/(<\?php)(((<\?php.*?\?>)|.)*?)(\?>|$)/s',$string,$result);
     
    	$codePhp='<?php ';
    	foreach ($result[2] as $bloc) {
    		$codePhp .= $bloc;
    	}
    	$codePhp .= ' ?>';
     
    	file_put_contents($destination,$codePhp);
    }
    avant de te souhaiter bonne chance dans ta recherche.
    Fred

  7. #7
    Membre confirm�
    Inscrit en
    Mai 2007
    Messages
    183
    D�tails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 183
    Par d�faut
    Pour le developpement �tre t�tu est une qualit�..
    .. m�me si ton dernier code que j'ai test� retourne ceci :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    <?php 
     $message= "<?php Ceci n'est pas du php  ?>
    Alors que le r�sultat attendu est :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
     
    <?php
     $message= "<?php Ceci n'est pas du php ?>";
     echo $message;
    ?>
    Je sais, je suis perfectionniste..
    ..mais c'est aussi une qualit� dans le developpement .

    Merci Fred.

  8. #8
    Membre �m�rite Avatar de micetf
    Homme Profil pro
    Professeur des Ecoles
    Inscrit en
    Mai 2009
    Messages
    557
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ard�che (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : Professeur des Ecoles
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2009
    Messages : 557
    Par d�faut
    Que neni !
    Refais le test,
    mais ma derni�re (3�me) version renvoie bien :
    <?php
    $message= "<?php Ceci n'est pas du php ?>";
    echo $message;
    ?>
    Fred

  9. #9
    Membre confirm�
    Inscrit en
    Mai 2007
    Messages
    183
    D�tails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 183
    Par d�faut
    Autant pour moi Fred..
    .. par contre cet exemple ne fonctionne pas

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type='text/javascript'>
    function mafonctionjavascript()
    {
    //  <% Ceci n'est pas du php %>
    }
    </script>
    </head>
    <body onload='mafonctionjavascript('<?php Ceci est du php ?>');' >
    <?php
    /*
    Ceci est une fin de balise ?> dans un commentaire
    */
     $message= "<?php Ceci n'est pas du php ?>";
     echo $message;
    ?>
    </body>
    </html>
    car il retourne :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
     
    <?php  Ceci est du php 
    /*
    Ceci est une fin de balise  Ceci n'est pas du php  ?>
    (Je suis aussi un peu joueur )

    A part de la bidouille, personne n'a d'id�e sur l'existence d'une fonction ou d'une extension qui extrairerais la partie PHP (id�alement qui permettrait d'identifier la ligne correspondante du fichier original)?

  10. #10
    Membre confirm�
    Inscrit en
    Mai 2007
    Messages
    183
    D�tails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 183
    Par d�faut
    Attention � l'utilisation de get_token_all () - (Constat� sur WAMP, PHP 5.3.0)

    1: les num�ros de ligne bug

    Depuis PHP 5.2.2 token_get_all () doit retourner le nombre de ligne dans l'�l�ment 2 ..
    .. mais par exemple (5.3.0 sur WAMP), il fonctionne parfaitement avec du code PHP (sans HMTL m�lang�), mais si vous avez des T_INLINE_HTML d�tect� par token_get_all (), parfois, vous trouverez les num�ros de ligne d�cal� (ligne suivante) ...

    2: bug des messages d'alertes qui peuvent avoir un impact sur les boucles

    Attention l'analyse de code PHP non complet (ex: code php ligne par ligne):
    par exemple, si une balise de commentaire n'est pas ferm� token_get_all (), les boucles peuvent �tre impact� par cet avertissement:
    Warning: Unterminated commentaire ligne de d�part

    Ce probl�me ne semble pas se produire dans CLI mod (php en ligne de commande), mais seulement sur le Web mod.

    En attendant plus de stabilit�, utiliser token_get_all () seulement sur du code PHP complet (avec les balise d'ouverture et de fermeture PHP incluse) :
    1. Tout d'abord extraire enti�rement du code PHP (avec php et � proximit� tag),
    2. Utilisation token_get_all () sur le code PHP pur.


    3: Pourquoi n'y at-il pas la fonction d'extraire du code PHP (extrait de HTML, nous avons Tidy ..) ?

    En attendant, je propose donc ma fonction.
    Attention elle prend pas en charge:
    - les anciennes notations : <? ?> Et <% %>
    - Heredoc syntaxe
    - Nowdoc syntaxe (depuis PHP 5.3.0)

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
     
    function extract_php_blocks($arg_path)
    {
    	$dbg=false;
    	if(!is_file($arg_path)) exit ("extract_php_blocks() : ".$arg_path." file not found");
    	$handle = @fopen($arg_path, "r");
    	if ($handle) {
    		$bloc = array();
    		$php_bloc_number=0; //fisrt bloc = 0
    		$line_number=1; // first row number  = 1
    		$multiline_php_code="";
    		$double_increment=false;
    		$in_php_code=false;
    		$in_single_quoted=false;
    		$in_double_quoted=false;
    		$in_comment_multi_line=false;
    		$in_comment_single_line=false;
    		while (!feof($handle)) {
    			$line_mixed_code= fgets($handle, 4096);
    			$nb_char=strlen($line_mixed_code);
    			$i_inline=0;
    			while($i_inline<$nb_char)
    			{// scanning line
    				if(!$in_php_code)
    				{// searching php open tag : with strpos
    					if($dbg) echo "\n".$line_number."---- OUT PHP ----\n".substr($line_mixed_code,$i_inline);
    					$pos_open_tag = strpos(substr($line_mixed_code,$i_inline) ,'<?php');
    					if ($pos_open_tag !== false)
    					{
    						$i_inline+=$pos_open_tag;
    						$bloc[$php_bloc_number]=array("start_line" => $line_number,"start_pos" => $i_inline,"end_line" => null,"end_pos" => null,"code" => null);
    						if($dbg) echo "\n".$line_number."-".$i_inline."\n";
    						$in_php_code=true;
    					}
    				}// end  searching php open tag
    				else
    				{// searching php close tag : char by char
    					$multiline_php_code.=$line_mixed_code[$i_inline];
    					if($double_increment){$i_inline++;$multiline_php_code.=$line_mixed_code[$i_inline];$double_increment=false;	}
    					if($dbg) echo "\n".$line_number."---- IN PHP ----\n".substr($line_mixed_code,$i_inline);
    					if($dbg&&$in_comment_single_line) echo "\n [in_comment_single_line] \n";
    
    					// specification in http://fr.php.net/manual/fr/language.types.string.php
    					if($in_comment_multi_line)
    					{// search ending sequence
    						if($dbg) echo "\n [in_comment_multi_line] \n";
    						if (($line_mixed_code[$i_inline]=='*')&&(($i_inline+1)<$nb_char)&&($line_mixed_code[$i_inline+1]=='/')){$in_comment_multi_line=false;;$double_increment=true;}
    					}
    					elseif($in_single_quoted)
    					{// search ending sequence 
    						if($dbg) echo "\n [in_single_quoted] \n";
    						if (($line_mixed_code[$i_inline]=='\\')&&(($i_inline+1)<$nb_char)&&(
    						($line_mixed_code[($i_inline+1)]=='\'')||($line_mixed_code[$i_inline+1]=='\\')
    						))$double_increment=true;
    						elseif ($line_mixed_code[$i_inline]=='\'') $in_single_quoted=false;
    					}
    					elseif($in_double_quoted)
    					{// search ending sequence
    						if($dbg) echo "\n [in_double_quoted] \n";
    						if (($line_mixed_code[$i_inline]=='\\')&&(($i_inline+1)<$nb_char)&&(
    						($line_mixed_code[($i_inline+1)]=='\'')||($line_mixed_code[$i_inline+1]=='\\')
    						||($line_mixed_code[$i_inline+1]=='n')||($line_mixed_code[$i_inline+1]=='r')
    						||($line_mixed_code[$i_inline+1]=='t')||($line_mixed_code[$i_inline+1]=='v')
    						||($line_mixed_code[$i_inline+1]=='f')||($line_mixed_code[$i_inline+1]=='$')
    						||($line_mixed_code[$i_inline+1]=='"')
    						))$double_increment=true;
    						elseif ($line_mixed_code[$i_inline]=='"') $in_double_quoted=false;					
    					}
    					elseif ((($i_inline+1)<$nb_char)&&($line_mixed_code[$i_inline]=='?')&&($line_mixed_code[($i_inline+1)]=='>')) {
    						$bloc[$php_bloc_number]["end_line"] = $line_number ;
    						$bloc[$php_bloc_number]["end_pos"] = $i_inline+2;
    						$bloc[$php_bloc_number]["code"] = '<'.$multiline_php_code.'>';
    						// reset in_php_code values
    						$multiline_php_code="";
    						$php_bloc_number++;
    						$in_php_code=false;
    						$in_comment_single_line=false;
    						$double_increment=true;
    					}
    					elseif((!$in_comment_multi_line)&&!$in_comment_single_line)
    					{// not in comment
    						if ($line_mixed_code[$i_inline]=='\'') $in_single_quoted=true;
    						elseif ($line_mixed_code[$i_inline]=='"') $in_double_quoted=true;
    						elseif ($line_mixed_code[$i_inline]=='#') $in_comment_single_line=true;
    						elseif (($i_inline+1)<$nb_char)
    						{// next char exist
    							if($dbg) echo "\n [found char+1] \n".substr($line_mixed_code,$i_inline);
    							if (($line_mixed_code[$i_inline]=='/')&&($line_mixed_code[($i_inline+1)]=='*')) {$in_comment_multi_line=true;;$double_increment=true;}
    							elseif (($line_mixed_code[$i_inline]=='/')&&($line_mixed_code[($i_inline+1)]=='/')) {$in_comment_single_line=true;;$double_increment=true;}
    						}// end next char exist
    					}//end :  not in comment
     
    				}// end  searching php close tag
    				$i_inline++;
    			}// end scanning line
    			$line_number++;
    			if($dbg) echo "\n [newline] \n";
    			$in_comment_single_line=false;
    		}
    		fclose($handle);
    	}
    	return $bloc;
    }
     
    function view_php_blocks(&$list_php_bloc)
    {
    	if(!is_array($list_php_bloc)) return false;
    	foreach($list_php_bloc as $key => $value)
    	{
    		$multiline_php_code.="\nBloc ".$key." (line ".$value["start_line"]." at char ".$value["start_pos"]." - line ".$value["end_line"]." at char ".$value["end_pos"].") :\n".$value["code"]."\n";
    	}
    	return $multiline_php_code;
    }

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Appel d'un fichier PHP avec passage de param�tre
    Par Claude_Azoulai dans le forum G�n�ral JavaScript
    R�ponses: 7
    Dernier message: 25/09/2008, 15h27
  2. Ouverture de fichier PHP avec PHPEclipse
    Par youenn dans le forum Eclipse PHP
    R�ponses: 4
    Dernier message: 25/03/2008, 17h59
  3. Lire un fichier PHP avec du code PHP et l'afficher
    Par Prosis dans le forum Langage
    R�ponses: 4
    Dernier message: 10/01/2008, 00h21
  4. [SimpleXML] Analyser un fichier XML avec PHP
    Par Someone86 dans le forum Biblioth�ques et frameworks
    R�ponses: 1
    Dernier message: 10/08/2007, 09h43
  5. R�ponses: 9
    Dernier message: 17/11/2005, 10h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo