Изменение файлов PHP с использованием Perl (возможно, с использованием HTML :: TreeBuilder) - PullRequest
2 голосов
/ 27 августа 2010

Я пытаюсь переделать много страниц на многих сайтах.Страницы могут содержать код JavaScript, PHP или ASP в дополнение к HTML.Проблема, с которой я сталкиваюсь, состоит в том, что модуль переписывает вещи, которые я не хочу переписывать.Мне удалось обработать большинство символов (например, ", >) в HTML-тегах, таких как script, но они превращаются в сущности (например, ", >) в разделах php,Кроме того, теги php удаляются одновременно.

Если у меня есть файл PHP, который выглядит следующим образом:

<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>

Я хочу, чтобы конечный результат выглядел следующим образом:

<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>

Как я уже сказал, я 'Я могу заставить все работать, кроме PHP.Он становится управляемым, поэтому результат

<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>

Я работал с HTML :: TreeBuilder 3.23.Я пробовал версию 3.23_3 для разработчиков, но она выдает сообщение об ошибке из-за кода php (например, a has an invalid attribute name '"&section_id' ' . $section_id . ').

Пример кода для того, что я сделал до сих пор (с обходом файловой системы,и т. д.)

#!/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;

Я открыт для любых предложений, примеров и т. д. Я не обязательно привязан к какому-либо конкретному модулю, но я не совсем опытный программист.

Спасибо!

1 Ответ

3 голосов
/ 27 августа 2010

Проблема здесь, очевидно, в теге <?php .. ?>.Вы можете сделать это с помощью препарсера.Я буду использовать простое регулярное выражение для этого:

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

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

Вы можете попробовать это:

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


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

Теперь, когда вы закончите с этим.Вы можете просто сделать наоборот, чтобы получить PHP-код из массива @phps и вернуться в правильном порядке в выводе:

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

Не делайте ошибку, это взлом;но это сделает вашу работу довольно эффективно, не задумываясь.Это довольно просто реализовать.Я могу придумать множество более эффективных способов сделать это - например, добавить HTML::Element для включения псевдо <?php .. ?> элемента.То, что вы не хотите, это отменить искажение (например, кодирование символов) на HTML::Element в ТТ - это звучит как намного худшая идея для меня.Вы могли бы даже реализовать материал, который идет от токена __PHP_CODE__ до реального кода PHP, используя фильтр Template.

Следует отметить, что это не позаботится о коротких тегах (хотя это может быть легко!) И я не уверен в логике, которая запускает интерпретатор PHP (например, экранирование <?php или ?>).Должно быть очевидно, хотя я и расскажу, что это не учитывает код PHP, подобный этому:

echo '?>';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...