2010-08-27 4 views
2

J'essaie de retravailler de nombreuses pages sur de nombreux sites. Les pages peuvent contenir du code JavaScript, PHP ou ASP en plus du code HTML. Le problème que je rencontre est que le module réécrit des choses que je ne veux pas réécrire. J'ai réussi à gérer la plupart des symboles (par exemple, ", >) dans des balises HTML comme script, mais ils sont changés en entités (par exemple, ", >) dans les sections php. De plus, les balises php sont supprimées en même temps.Modification de fichiers PHP à l'aide de Perl (éventuellement en utilisant HTML :: TreeBuilder)

Si j'ai un fichier PHP qui ressemble à ceci:

<html> 
    <head><title>My Page</title></head> 
    <body> 
    <p>Some cruft &nbsp; which I want to repeat</p> 
    <form name="foo"> (form content to be replaced) 
    </form> 
    <script type="JavaScript"> 
     <!-- 
     Some javaScript to be left alone 
     --> 
    </script> 
    <a href="somepage.php">Link to be removed</a> 
    <?php 
     if (strlen($txtKeyword) > 2) 
     { 
      echo " or <a href=\"database_search_keyword.htm\">Search again?</a></p>"; 
      if(isset($_REQUEST['nr'])) 
     { 
      $numRows = $_REQUEST['nr']; 
      .... 
    ?> 
    </body> 
</html> 

Je veux que le résultat final ressemble:

<html> 
    <head><title>My Page</title></head> 
    <body> 
    <p>Some cruft &nbsp; which I want to repeat</p> 
    <ul><li>List replacing form</li> 
    </ul> 
    <script type="JavaScript"> 
     <!-- 
     Some javaScript to be left alone 
     --> 
    </script> 
    <?php 
     if (strlen($txtKeyword) > 2) 
     { 
      echo " or <a href=\"database_search_keyword.htm\">Search again?</a></p>"; 
      if(isset($_REQUEST['nr'])) 
     { 
      $numRows = $_REQUEST['nr']; 
      .... 
    ?> 
    </body> 
</html> 

Comme je l'ai dit, je suis en mesure d'obtenir tout ce travail sauf le php. Il se managled, donc le résultat

<html> 
    <head><title>My Page</title></head> 
    <body> 
    <p>Some cruft &nbsp; which I want to repeat</p> 
    <ul><li>List replacing form</li> 
    </ul> 
    <script type="JavaScript"> 
     <!-- 
     Some javaScript to be left alone 
     --> 
    </script> 
    <?php 
     if (strlen($txtKeyword) &gt; 2) 
     { 
      echo &quot; or &quot;; 
      if(isset($_REQUEST[&#39;nr&#39;])) 
     { 
      $numRows = $_REQUEST[&#39;nr&#39;]; 
      .... 
    ?> 
    </body> 
</html> 

Je travaille avec HTML :: TreeBuilder 3,23. J'ai essayé la version du développeur 3.23_3, mais elle donne un message d'erreur dû au code php (par exemple, a has an invalid attribute name '"&section_id' ' . $section_id . ').

Exemple de code pour ce que je l'ai fait jusqu'à présent (avec la marche du système de fichiers, etc. émincé out) est

#!/usr/bin/perl -w 

use strict; 

use HTML::TreeBuilder; 

# Set up replacement forms 
my $artistSearch = HTML::Element->new ('~literal', 'text', <<EOF); 
<p>Please select from the list below.</p> 
<ul> 
    <li><a href="http://firstlink.com/">item 1</a></li> 
    <li><a href="http://secondlink.com/">item 1</a></li> 
</ul> 
EOF 

my $filename = "AFA.php"; 
my $file = HTML::TreeBuilder->new(); 
$file->store_comments(1); 
$file->ignore_ignorable_whitespace(1); 
$file->no_space_compacting(1); 
my $tree = $file->parse_file($filename); 


my $form = $tree->find_by_tag_name('form'); 
my $fname = $form->attr('name'); 
if ($fname eq 'mainform') { 
    $form->delete; 
} elsif ($fname eq 'artist_search') { 
    $form->replace_with($artistSearch)->delete; 
} else { 
    # It's a form we're not changing 
} 

my $printout = $file->as_HTML("", " ", {}); 
open (PAGE, "> $filename"); 
print PAGE $printout; 
close (PAGE); 
$file->delete; 

Je suis ouvert à toutes les suggestions, des exemples, etc. Je ne suis pas nécessairement lié à un module particulier, mais je ne suis pas exactement un programmeur expert.

Merci!

Répondre

3

Le problème ici est évidemment l'étiquette <?php .. ?>. Vous pourriez accomplir ceci avec un préparateur. Je vais utiliser un simple regex pour cela:

use strict; 
use warnings; 
undef $/; 
$_=<>; 
my @phps; 
push @phps, $1 while s/<\?php (.*?) \?>/__PHP_CODE__/; 

use Data::Dumper; 
die Dumper [$_, \@phps]; 

Vous pouvez l'essayer:

echo "foo<?php phpfoo ?> bar <?php phpbar ?> baz" | filter.pl 


$VAR1 = [ 
      'foo__PHP_CODE__ bar __PHP_CODE__ baz', 
      [ 
      'phpfoo', 
      'phpbar' 
      ] 
     ]; 

Maintenant, quand vous avez fini avec elle. Vous pouvez juste faire l'inverse pour obtenir le code PHP sur le tableau @phps et de nouveau dans le bon ordre dans la sortie:

my $count = 0; 
s/__PHP_CODE__/<?php $phps[$count++] ?>/g; 

Ne vous y trompez pas, c'est un hack; mais, il fera votre travail assez efficacement sans trop y penser. C'est assez simple à mettre en œuvre aussi. Je peux penser à une tonne de meilleures façons de le faire - comme l'extension HTML::Element pour inclure un élément pseudo <?php .. ?>. Qu'est-ce que vous ne voulez pas, c'est d'annuler mangling (comme l'encodage de caractères) par HTML::Element en TT - cela ressemble à un loin pire idée pour moi. Vous pouvez même implémenter ce qui va du jeton __PHP_CODE__ au vrai code PHP en utilisant un filtre Template.

Il convient de noter que cela ne s'occupe pas des raccourcis (bien que cela pourrait facilement!) Et, je ne suis pas sûr de la logique qui déclenche l'interpréteur PHP (échapper <?php ou ?> par exemple). Il devrait être évident, bien que je le dise, que ceci ne respecte pas le code PHP comme ceci:

echo '?>'; 
+0

Ceci semble entièrement réalisable ...en supposant que je puisse envelopper ma tête autour de l'obtenir pour travailler avec le reste du code. Merci pour la réponse rapide, et je mettrai à jour après que je l'ai mâché un moment. – tmsilver

+0

Cela semble fonctionner, mais je dois faire beaucoup de lecture/écriture pour le faire fonctionner. Je finis 1) Lecture du fichier, en remplaçant PHP par le jeton; 2) Écrire un fichier avec un jeton; 3) Lecture du fichier pour TreeBuilder; 4) écrire un fichier avec des changements de TB; 5) Lecture du fichier, remplacement du jeton par du code; 6) Écriture du fichier avec les changements complets. Si j'essaie d'ignorer l'un d'entre eux, il omet ou remplace certains de mes changements. Cela pourrait être une chose de débutant ... Merci pour votre aide! – tmsilver

+1

Vous ne devez pas "écrire le fichier" plus d'une fois. Vous pouvez tout faire en mémoire. Vous pouvez (1) * slurp * le fichier, (2) sous les jetons php (3) lancer 'new_from_content' avec TreeBuilder, (4) transformer, (5)' -> as_HTML', (6) exécuter regex pour remplacer php jetons (7) écrire le fichier une fois. C'est encore beaucoup de passes dans la mémoire - beaucoup ne sont pas nécessaires en théorie, mais ce n'est toujours pas le fichier io. –

Questions connexes