Batch script to replace PHP short open tags with <?php

前端 未结 13 1740
轻奢々
轻奢々 2020-11-30 01:49

I have a large collection of php files written over the years and I need to properly replace all the short open tags into proper explicit open tags.

change \         


        
相关标签:
13条回答
  • 2020-11-30 02:45

    I've had to go through this before and I found it best to do it in stages. A bad script trying to catch it all can mess up a LOT of files.

    I used Coda (or any other web editor) to do a simple find and replace on very specific strings.

    For example starting with "

    It may seem a little more tedious but I was confident that something wasn't getting messed up somewhere that I didn't know about. Going back is a real pain.

    0 讨论(0)
  • 2020-11-30 02:47

    My previous answer I just overwrote with sed wont work, sed is too weak for this sort of thing IMO.

    So I've whipped up a perl-script that should do the trick, its hopefully very user-editable.

    #!/usr/bin/perl 
    
    use strict;
    use warnings;
    
    use File::Find::Rule;
    use Carp;
    
    my @files = File::Find::Rule->file()->name('*.php')->in('/tmp/foo/bar');
    
    for my $file (@files) {
        rename $file, $file . '.orig';
        open my $output, '>', $file or Carp::croak("Write Error with $file $! $@ ");
        open my $input, '<', $file . '.orig'
          or Carp::croak("Read error with $file.orig $! $@");
    
        while ( my $line = <$input> ) {
            # Replace <?= with <?php echo 
            $line =~ s/<\?=/<?php echo /g;
    
            # Replace <? ashded  with <?php ashed
    
            $line =~ s/<\?(?!php|xml)/<?php /g;
            print $output $line;
        }
    
        close $input  or Carp::carp(" Close error with $file.orig, $! $@");
        close $output or Carp::carp(" Close error with $file  , $! $@");
    
        unlink $file . '.orig';
    }
    

    But note, I haven't tested this on any real code, so It could go "Bang" .

    I would recommend you have your code revisioned ( wait, its already revisioned, right? .. right? ) and run your test-suite ( Don't tell me you don't have tests ! ) on the modified code, because you can't be certain its doing the right thing without a fully fledged FSM parser.

    0 讨论(0)
  • 2020-11-30 02:48

    I'm going to streamline your regex for the purposes of this into what may work better, but I may be wrong since I haven't tested it on any real code.

    Let's say you're sitting in the base directory of your code, you could start with:

    find . -iname "*.php" -print0
    

    That will get you all .php files, separated by NULL characters, which is necessary in case any of them have spaces.

    find . -iname "*.php" -print0 | xargs -0 -I{} sed -n 's/\(<\?\)\([^a-zA-Z]\)/\1php\2/gp' '{}'
    

    This should get you most of the way there. It will find all the files, then for each one, run sed to replace the code. However, without the -i tag (used below), this won't actually touch your files, it will just send your code to your terminal. The -n suppresses normal output, and the p after the regex part tells it to print only lines that changed.

    Okay, if your results look correct, then you take the big step, which is replacing the files in-place. You should definitely back up all your files before attempting this!!!

    find . -iname "*.php" -print0 | xargs -0 -I{} sed -i 's/\(<\?\)\([^a-zA-Z]\)/\1php\2/g' '{}'
    

    That should about get the job done. Unfortunately, I have no PHP files lying around that use that syntax, so you're on your own to figure it out from here, but hopefully the mechanics of getting things done are a bit clearer now:

    1. Grab all the files with "find"
    2. Send that list of files to "xargs" (which does some command on the files one at a time
    3. Use "sed" and the syntax 's/to-change/changed/' to put your regex magic to work!
    0 讨论(0)
  • 2020-11-30 02:50

    It's typical for XML/XHTML pages to include following code:

    <?php echo '<?xml version="1.0" encoding="UTF-8" ?>'; ?>
    

    Of course that should not be changed neither to:

    <?phpphp echo '<?phpxml version="1.0" encoding="UTF-8" ?>'; ?>
    

    nor:

    <?php echo '<?phpxml version="1.0" encoding="UTF-8" ?>'; ?>
    
    0 讨论(0)
  • 2020-11-30 02:54

    This is a utility I wrote that converts PHP source that contains short open tags and replaces them with long tags.

    • https://github.com/danorton/php_replace_short_tags

    i.e. it converts code like this:

      <?= $var1 ?>
      <? printf("%u changes\n",$changes) ?>
    

    To this

      <?php echo $var1 ?>
      <?php printf("%u changes\n",$changes) ?>
    

    The --skip-echo-tags option will cause it to skip <?= tags and only replace <? tags.

    It’s written as a PHP-CLI script and needs the CLI php.ini file to be set to permit short short open tags. That’s the default setting for PHP 5.3.0 and earlier, but it might not always remain so. (The script simply won’t change anything if the setting isn’t enabled.)

    0 讨论(0)
  • 2020-11-30 02:55

    Unfortunately, automated solutions may not work. My recommendation:

    1) Use grep to find all short tags:

    grep -rn "<?[^p]" *
    

    2) Go through each file and line and fix manually

    I understand that this might not be a viable solution if you have a huge project, but for me it worked well.

    0 讨论(0)
提交回复
热议问题