I've got some really old code (php 5.1) that needs to run on a newer server.
New server has PHP 5.6, so any areas where
<?
is used to open the PHP context, those are not being interpreted correctly. I need to replace all instances of
<?
with
<?php
except where
<?
is already part of
<?php
My inital effort was to use backreferences and sed:
cat file.php | sed -i 's/<?([^php])/<?php\$1/g'
However, the () seems to break the match, and without it, I cannot have a proper back reference.
I was trying to get whatever was after PHP opening tag into the backreference, so I could turn lines like:
<?=$_COOKIE...
into
<?php=$_COOKIE...
And, please don't point me to: Using sed to replace <? with <?php. I already saw it, and it does not address the fact that I already have the new opening tag in some places and the old one in others. (One of the answers kind of does, but I would prefer not to create "phpphphphpphp" and have to search for that over and over to reduce it to "php"
Lastly, please forgive the weirdly spaced open and closing tags. SO cannot display them in line with the text, only if they are in a code block.
You can do:
sed 's/<?\(php\)*/<?php/g' file
In this case "php" is optional but is systematically overwritten if it's already here.
Or using a white-space character as suggests AbraCadaver since it seems to be mandatory after a short tag:
sed 's/<?\([[:space:]]\)/<?php\1/g' file
Limitation: this pattern can't know if <? or <?php is inside a string. Example:
echo 'abc <? def';
becomes:
echo 'abc <?php def';
A better way is to use PHP itself with the tokenizer.
example:
$str = 'echo "blah"; <? echo "sblub"; ?> bluh';
$result = '';
foreach(token_get_all($str) as $tok) {
$result .= ($tok[0] == 376) ? '<?php' : $tok[1];
}
echo $result;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With