Monday, March 30, 2020

Replace PHP short-hand tags and normalize usage

What are PHP tags?

When PHP parses a file, it looks for opening and closing tags, which are <?php and ?> which tell PHP to start and stop interpreting the code between them. Parsing in this manner allows PHP to be embedded in all sorts of different documents, as everything outside of a pair of opening and closing tags is ignored by the PHP parser.

PHP includes a short echo tag <?= which is a short-hand to the more verbose <?php echo.

PHP also allows for short open tag <? (which is discouraged since it is only available if enabled using the short_open_tag php.ini configuration file directive, or if PHP was configured with the --enable-short-tags option).

If a file contains only PHP code, it is preferable to omit the PHP closing tag at the end of the file. This prevents accidental whitespace or new lines being added after the PHP closing tag, which may cause unwanted effects because PHP will start output buffering when there is no intention from the programmer to send any output at that point in the script.
Source: php.net

With PHP 7.4, per the PHP RFC: Deprecate PHP Short open tags, a deprecation noticed is issued for usage of the short-hand tag, and in PHP 8.0, the short-hand tag will be removed.
While the <?= short tag is unaffected, for completeness, using the full PHP tag should be preferred.
And using the short-hand tags generally make code less portable as it requires a non common ini change.

Ok, so for new projects you can start using <?php ?>.
But, maybe you inherited an old project which uses the short-hand tags, which was more common in the earlier pre PHP 7 days.  And you don't want to manually replace all the tags in 100s of files.

The following are some command line find + sed calls to replace PHP short-hand and normalize PHP tags across multiple files:

What is going to be replaced and the sed command used:
DescriptionFromTosed
new line; start of file'<?\n''<?php\n'-e 's/^<?\n/<?php\n/'
block'<?\n''<?php\n'-e 's/<?\n/<?php\n/g'
inline'<? ''<?php '-e 's/<? /<?php /g'
echo shorthand'<?=''<?php echo '-e 's/<?\=/<?php echo /g'
lowercase'<?PHP''<?php'-e 's/<?PHP/<?php/g'
no closing tag'?>''\n'-e 's/^?>/\n/'

Note: lowercase: PHP functions are case insensitive. Why? Just how PHP evolved.  "all the functions introduced essentially felt like tags in an HTML document and since HTML tags were case insensitive, he chose function names in PHP to be case insensitive."
Source: stackoverflow
But keeping everything lowercase is more normal, compared to other languages.

Note: no closing tag: If your code or templates have mixed PHP/HTML content, then you do not want to remove the closing tags.  The intent is for files which are only PHP, you can and should remove the closing tag.

Make sure to make a backup, or using version control such as git or svn.

OK, now on to the actual commands:

First, optionally, convert window new lines to unix new lines, so the patterns in sed can match
> find . -iname '*.php' -type f -print0 |xargs -0 -I file dos2unix file

Details: Finds and print all php files in the current ie . and sub directories
find . -iname '*.php' -type f -print0 

Details: Takes the first result and stores to 'file'
xargs -0 -I file

Then, test the sed replacement
> find app/ -iname '*.php' -type f -print0 |xargs -0 sed -n -e 's/^<?\n/<?php\n/p' -e 's/<?\n/<?php\n/g' -e 's/<? /<?php /gp' -e 's/<?\=/<?php echo /gp' -e 's/<?PHP/<?php/gp' -e 's/^?>/\n/p';

Note: sed options:
-e = pattern
-i = inplace
-n = --quite
p = print current pattern

Run the replacements:

Removing closing tag:
> find app_src/ -iname '*.php' -type f -print0 |xargs -0 sed -i -e 's/^<?\n/<?php\n/' -e 's/<?\n/<?php\n/g' -e 's/<? /<?php /g' -e 's/<?\=/<?php echo /g' -e 's/<?PHP/<?php/g' -e 's/^?>/\n/';

Keeping closing tag due to mixed PHP/HTML:
> find html_templates/ -iname '*.php' -type f -print0 |xargs -0 sed -i -e 's/^<?\n/<?php\n/' -e 's/<?\n/<?php\n/g' -e 's/<? /<?php /g' -e 's/<?\=/<?php echo /g' -e 's/<?PHP/<?php/g';


Now all your PHP short-hand tags should be replaced and normalized.
Of course, verify using version control diffs and test your code.


-End of Document-
Thanks for reading

No comments:

Post a Comment