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 \
I used danorton script on almost 2000 files and it worked like a charm
I put his script into a file named "fixtags.php" and used the following linux 1 liner to solve the problem:
find . -iname "*.php" | xargs php fixtags.php --overwrite
the only problem I had is when it encountered a file that was zero bytes in size.
The problem has been solved as a fixer in the php-cs-fixer
tool which can be easily installed and which is tested and maintained.
Fixing then is easy:
$ php-cs-fixer fix <path> --rules=full_opening_tag,no_short_echo_tag --diff --dry-run
Just replace <path>
with the path to the directory or file you'd like to change. The command as given is to review first (--dry-run
and --diff
parameters).
Installing php-cs-fixer is as easy as
$ composer global require friendsofphp/php-cs-fixer
if you've got composer installed with global composer bin directory in your path (recommended).
That's my version of the RegExp:
<\?(?!(php|=|xml))(\s|\t|\n)
I had the same problem when I update php version.
Use this:
find . -iname "\*.ph\*" -type f -print0 |xargs -0 sed -i -e 's/<? /<?php /g' -e 's/<?\/\//<?php \/\//g' -e 's/<?\/\*/<?php \/\*/g' -e 's/<?\=/<?php echo/g'
This will convert "<?" to "<?php", "<?//" to "<?php //", "<?/" to "<?php /"
for any kind of file .php or .phtml
Credits: https://coderwall.com/p/cnm0_w/replace-php-short-open-tags-with-full-form-in-all-php-files-using-one-command
don't use regexps for parsing formal languages - you'll always run into haystacks you did not anticipate. like:
<?
$bla = '?> now what? <?';
it's safer to use a processor that knows about the structure of the language. for html, that would be a xml processor; for php, the built-in tokenizer extension. it has the T_OPEN_TAG parser token, which matches <?php
, <?
or <%
, and T_OPEN_TAG_WITH_ECHO, which matches <?=
or <%=
. to replace all short open tags, you find all these tokens and replace T_OPEN_TAG
with <?php
and T_OPEN_TAG_WITH_ECHO
with <?php echo
.
the implementation is left as an exercise for the reader :)
EDIT 1: ringmaster was so kind to provide one.
EDIT 2: on systems with short_open_tag turned off in php.ini
, <?
, <%
, and <?=
won't be recognized by a replacement script. to make the script work on such systems, enable short_open_tag
via command line option:
php -d short_open_tag=On short_open_tag_replacement_script.php
p.s. the man page for token_get_all() and googleing for creative combinations of tokenizer, token_get_all, and the parser token names might help.
p.p.s. see also Regex to parse define() contents, possible? here on SO
If you're using the tokenizer option, this might be helpful:
$content = file_get_contents($file);
$tokens = token_get_all($content);
$output = '';
foreach($tokens as $token) {
if(is_array($token)) {
list($index, $code, $line) = $token;
switch($index) {
case T_OPEN_TAG_WITH_ECHO:
$output .= '<?php echo ';
break;
case T_OPEN_TAG:
$output .= '<?php ';
break;
default:
$output .= $code;
break;
}
}
else {
$output .= $token;
}
}
return $output;
Note that the tokenizer will not properly tokenize short tags if short tags aren't enabled. That is, you can't run this code on the system where short tags aren't working. You must run it elsewhere to convert the code.