Очистить php код от комментариев

Лучший способ автоматически удалять комментарии из кода PHP

Каков наилучший способ удалить комментарии из файла PHP?

Я хочу сделать что-то похожее на strip-whitespace() — но это также не должно удалять разрывы строк.

Some embedded HTML'; > /* another long comment */ some_more_code(); ?> 
Some embedded HTML'; > some_more_code(); ?> 

(Хотя, если пустые строки остаются там, где удаляются комментарии, это не будет хорошо).

Это может оказаться невозможным из-за необходимости сохранения встроенного HTML — вот что споткнуло то, что появилось в Google.

11 ответов

Я бы использовал токенизатор. Вот мое решение. Он должен работать как на PHP 4, так и на 5:

$fileStr = file_get_contents('path/to/file'); $newStr = ''; $commentTokens = array(T_COMMENT); if (defined('T_DOC_COMMENT')) $commentTokens[] = T_DOC_COMMENT; // PHP 5 if (defined('T_ML_COMMENT')) $commentTokens[] = T_ML_COMMENT; // PHP 4 $tokens = token_get_all($fileStr); foreach ($tokens as $token) < if (is_array($token)) < if (in_array($token[0], $commentTokens)) continue; $token = $token[1]; >$newStr .= $token; > echo $newStr; 

Как насчет использования php -w для генерации файла, лишенного комментариев и пробелов, а затем использования beautifier, такого как PHP_Beautifier, для переформатирования для удобства чтения?

$fileStr = file_get_contents('file.php'); foreach (token_get_all($fileStr) as $token ) < if ($token[0] != T_COMMENT) < continue; >$fileStr = str_replace($token[1], '', $fileStr); > echo $fileStr; 

я понял, что Ionut G. Stan уже предложил это, но я оставлю пример здесь

Вот функция, опубликованная выше, модифицированная для рекурсивного удаления всех комментариев из всех файлов php внутри каталога и всех его подкаталогов:

function rmcomments($id) < if (file_exists($id)) < if (is_dir($id)) < $handle = opendir($id); while($file = readdir($handle)) < if (($file != ".") && ($file != "..")) < rmcomments($id."/".$file); >> closedir($handle); > else if ((is_file($id)) && (end(explode('.', $id)) == "php")) < if (!is_writable($id)) < chmod($id,0777); >if (is_writable($id)) < $fileStr = file_get_contents($id); $newStr = ''; $commentTokens = array(T_COMMENT); if (defined('T_DOC_COMMENT')) < $commentTokens[] = T_DOC_COMMENT; >if (defined('T_ML_COMMENT')) < $commentTokens[] = T_ML_COMMENT; >$tokens = token_get_all($fileStr); foreach ($tokens as $token) < if (is_array($token)) < if (in_array($token[0], $commentTokens)) < continue; >$token = $token[1]; > $newStr .= $token; > if (!file_put_contents($id,$newStr)) < $open = fopen($id,"w"); fwrite($open,$newStr); fclose($open); >>>>> rmcomments("path/to/directory"); 

Версия более мощная: удалите все комментарии в папке

 > $arr = [T_COMMENT,T_DOC_COMMENT]; $count = count($fileArr); for($i=1;$i < $count;$i++)< $fileStr = file_get_contents($fileArr[$i]); foreach(token_get_all($fileStr) as $token)< if(in_array($token[0],$arr))< $fileStr = str_replace($token[1],'',$fileStr); >> file_put_contents($fileArr[$i],$fileStr); > 
/* * T_ML_COMMENT does not exist in PHP 5. * The following three lines define it in order to * preserve backwards compatibility. * * The next two lines define the PHP 5 only T_DOC_COMMENT, * which we will mask as T_ML_COMMENT for PHP 4. */ if (! defined('T_ML_COMMENT')) < define('T_ML_COMMENT', T_COMMENT); >else < define('T_DOC_COMMENT', T_ML_COMMENT); >/* * Remove all comment in $file */ function remove_comment($file) < $comment_token = array(T_COMMENT, T_ML_COMMENT, T_DOC_COMMENT); $input = file_get_contents($file); $tokens = token_get_all($input); $output = ''; foreach ($tokens as $token) < if (is_string($token)) < $output .= $token; >else < list($id, $text) = $token; if (in_array($id, $comment_token)) < $output .= $text; >> > file_put_contents($file, $output); > /* * Glob recursive * @return ['dir/filename', . ] */ function glob_recursive($pattern, $flags = 0) < $file_list = glob($pattern, $flags); $sub_dir = glob(dirname($pattern) . '/*', GLOB_ONLYDIR); // If sub directory exist if (count($sub_dir) >0) < $file_list = array_merge( glob_recursive(dirname($pattern) . '/*/' . basename($pattern), $flags), $file_list ); >return $file_list; > // Remove all comment of '*.php', include sub directory foreach (glob_recursive('*.php') as $file)

Решение Bash: если вы хотите рекурсивно удалять комментарии из всех PHP-файлов, начиная с текущего каталога, вы можете написать в терминале эту однострочную строку. (оно использует temp1 файл для хранения содержимого PHP для обработки)Обратите внимание, что это уберет все пробелы с комментариями.

 find . -type f -name '*.php' | while read VAR; do php -wq $VAR > temp1 ; cat temp1 > $VAR; done 

Тогда вы должны удалить temp1 файл после.

Читайте также:  Сортировка числового массива php

если установлен PHP_BEAUTIFER, вы можете получить красиво отформатированный код без комментариев с

 find . -type f -name '*.php' | while read VAR; do php -wq $VAR > temp1; php_beautifier temp1 > temp2; cat temp2 > $VAR; done; 

затем удалите два файла ( temp1 , temp2 )

Если вы уже используете редактор, такой как UltraEdit, вы можете открыть один или несколько файлов PHP и затем использовать простой метод поиска и замены (CTRL+R) со следующим регулярным выражением Perl

Осторожно, приведенное выше регулярное выражение удаляет также комментарии внутри sring, то есть в echo «hello/*babe*/»; /*babe*/ будет удален тоже. Следовательно, это может быть решением, если у вас мало файлов для удаления комментариев, чтобы быть абсолютно уверенным, что оно не заменит неправильно то, что не является комментарием, вам придется запускать команду «Найти и заменить» и утверждать каждый раз, что заменяется.

Следуя принятому ответу, мне также нужно было сохранить номера строк файла, поэтому вот вариант принятого ответа:

 /** * Removes the php comments from the given valid php string, and returns the result. * * Note: a valid php string must start with $s = ''; foreach ($tokens as $token) < if (is_array($token)) < if (in_array($token[0], $commentTokens)) < if (true === $preserveWhiteSpace) < $comment = $token[1]; $lineNb = $token[2]; $firstLine = $lines[$lineNb - 1]; $p = explode(PHP_EOL, $comment); $nbLineComments = count($p); if ($nbLineComments < 1) < $nbLineComments = 1; >$firstCommentLine = array_shift($p); $isStandAlone = (trim($firstLine) === trim($firstCommentLine)); if (false === $isStandAlone) < if (2 === $nbLineComments) < $s .= PHP_EOL; >continue; // just remove inline comments > // stand alone case $s .= str_repeat(PHP_EOL, $nbLineComments - 1); > continue; > $token = $token[1]; > $s .= $token; > return $s; > 

Примечание: это для php 7+ (меня не заботила обратная совместимость со старыми версиями php).

php -w или php_strip_whitespace($filename);

В 2019 году может работать так

'); $ts = token_get_all(php_strip_whitespace($f)); $s=''; foreach($ts as $t)< if(is_array($t))< $s .=$t[1]; >else < $s .=$t; if( in_array($t,$w) ) $s.=chr(13).chr(10); >> return $s; > ?> 

если вы хотите увидеть результаты, давайте сначала запустим его в xampp, затем вы получите пустую страницу, но если вы щелкнете правой кнопкой мыши и нажмете на view source, вы получите свой php-скрипт. он загружается сам и удаляет все комментарии, а также вкладки. Я тоже предпочитаю это решение, потому что я использую его, чтобы ускорить мой фреймворк с одним файловым движком «m.php», и после php_strip_whitespace весь исходный код без этого скрипта, который я наблюдаю, работает медленнее: я сделал 10 тестов, а затем вычислил математическое среднее (я думаю, что php 7 восстанавливает пропущенные данные cr_lf, когда выполняется синтаксический анализ или занимает некоторое время, когда они отсутствуют)

Читайте также:  Php call user functions

Источник

Лучший способ автоматического удаления комментариев из PHP-кода

Какой лучший способ удалить комментарии из файла PHP?

Я хочу сделать что-то подобное strip-whitespace () – но он также не должен удалять разрывы строк.

Some embedded HTML'; > /* another long comment */ some_more_code(); ?> 
Some embedded HTML'; > some_more_code(); ?> 

(Хотя, если пустые строки остаются там, где комментарии удалены, это не будет нормально).

Это может быть невозможно, из-за требования сохранить встроенный html – вот что расстроило то, что появилось в Google.

Я бы использовал токенизатор . Вот мое решение. Он должен работать как на PHP 4, так и на 5:

$fileStr = file_get_contents('path/to/file'); $newStr = ''; $commentTokens = array(T_COMMENT); if (defined('T_DOC_COMMENT')) $commentTokens[] = T_DOC_COMMENT; // PHP 5 if (defined('T_ML_COMMENT')) $commentTokens[] = T_ML_COMMENT; // PHP 4 $tokens = token_get_all($fileStr); foreach ($tokens as $token) < if (is_array($token)) < if (in_array($token[0], $commentTokens)) continue; $token = $token[1]; >$newStr .= $token; > echo $newStr; 

Как насчет использования php -w для генерации файла, лишенного комментариев и пробелов, а затем с помощью beautifier, такого как PHP_Beautifier, для переформатирования для удобочитаемости?

Вот функция, опубликованная выше, измененная для рекурсивного удаления всех комментариев из всех php-файлов в каталоге и во всех его подкаталогах:

function rmcomments($id) < if (file_exists($id)) < if (is_dir($id)) < $handle = opendir($id); while($file = readdir($handle)) < if (($file != ".") && ($file != "..")) < rmcomments($id."/".$file); >> closedir($handle); > else if ((is_file($id)) && (end(explode('.', $id)) == "php")) < if (!is_writable($id)) < chmod($id,0777); >if (is_writable($id)) < $fileStr = file_get_contents($id); $newStr = ''; $commentTokens = array(T_COMMENT); if (defined('T_DOC_COMMENT')) < $commentTokens[] = T_DOC_COMMENT; >if (defined('T_ML_COMMENT')) < $commentTokens[] = T_ML_COMMENT; >$tokens = token_get_all($fileStr); foreach ($tokens as $token) < if (is_array($token)) < if (in_array($token[0], $commentTokens)) < continue; >$token = $token[1]; > $newStr .= $token; > if (!file_put_contents($id,$newStr)) < $open = fopen($id,"w"); fwrite($open,$newStr); fclose($open); >>>>> rmcomments("path/to/directory"); 
$fileStr = file_get_contents('file.php'); foreach (token_get_all($fileStr) as $token ) < if ($token[0] != T_COMMENT) < continue; >$fileStr = str_replace($token[1], '', $fileStr); > echo $fileStr; 

Я понял, что Ионут Г. Стэн уже предложил это, но я оставлю здесь пример

версия более мощная: удалите все комментарии в папке

 > $arr = [T_COMMENT,T_DOC_COMMENT]; $count = count($fileArr); for($i=1;$i < $count;$i++)< $fileStr = file_get_contents($fileArr[$i]); foreach(token_get_all($fileStr) as $token)< if(in_array($token[0],$arr))< $fileStr = str_replace($token[1],'',$fileStr); >> file_put_contents($fileArr[$i],$fileStr); > 

Если вы уже используете такой редактор, как UltraEdit , вы можете открыть один или несколько файлов PHP, а затем использовать простой Find & Replace (CTRL + R) со следующим Perl regexp

Остерегайтесь вышеуказанного regexp удаляет также комментарии внутри sring, то есть в echo «hello/*babe*/»; /*babe*/ будет удален. Следовательно, это может быть решение, если у вас мало файлов для удаления комментариев, чтобы быть абсолютно уверенным, что он не ошибочно заменяет то, что не является комментарием, который вам нужно будет выполнять командой Find & Replace и каждый раз одобрять замену.

/* * T_ML_COMMENT does not exist in PHP 5. * The following three lines define it in order to * preserve backwards compatibility. * * The next two lines define the PHP 5 only T_DOC_COMMENT, * which we will mask as T_ML_COMMENT for PHP 4. */ if (! defined('T_ML_COMMENT')) < define('T_ML_COMMENT', T_COMMENT); >else < define('T_DOC_COMMENT', T_ML_COMMENT); >/* * Remove all comment in $file */ function remove_comment($file) < $comment_token = array(T_COMMENT, T_ML_COMMENT, T_DOC_COMMENT); $input = file_get_contents($file); $tokens = token_get_all($input); $output = ''; foreach ($tokens as $token) < if (is_string($token)) < $output .= $token; >else < list($id, $text) = $token; if (in_array($id, $comment_token)) < $output .= $text; >> > file_put_contents($file, $output); > /* * Glob recursive * @return ['dir/filename', . ] */ function glob_recursive($pattern, $flags = 0) < $file_list = glob($pattern, $flags); $sub_dir = glob(dirname($pattern) . '/*', GLOB_ONLYDIR); // If sub directory exist if (count($sub_dir) >0) < $file_list = array_merge( glob_recursive(dirname($pattern) . '/*/' . basename($pattern), $flags), $file_list ); >return $file_list; > // Remove all comment of '*.php', include sub directory foreach (glob_recursive('*.php') as $file)

Для ответов ajax / json я использую следующий код PHP, чтобы удалить комментарии из кода HTML / JavaScript, поэтому он будет меньше (примерно 15% для моего кода).

// Replace doubled spaces with single ones (ignored in HTML any way) $html = preg_replace('@(\s)@', '\1', $html); // Remove single and multiline comments, tabs and newline chars $html = preg_replace( '@(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|((? 

Короткий и эффективный, но может привести к неожиданным результатам, если ваш код имеет синтаксис $ itty.

Читайте также:  Executors newcachedthreadpool in java

Запустите команду php --strip file.php в командной строке (например cmd.exe ), затем перейдите на php --strip file.php http://www.writephponline.com/phpbeautifier .

Здесь file.php является вашим собственным файлом.

1

Уловка заключается в том, что менее надежный алгоритм совпадения (например, простого регулярного выражения) начнет зачищать здесь, когда он явно не должен:

if (preg_match('#^/*' . $this->index . '#', $this->permalink_structure)) 

Это может не повлиять на ваш код, но в конце концов кто-то получит ваш скрипт. Поэтому вам придется использовать утилиту, которая понимает больше языка, чем вы могли бы ожидать.

Решение Bash: если вы хотите удалить рекурсивные комментарии из всех файлов PHP, начиная с текущего каталога, вы можете записать в терминал этот однострочный. (он использует файл temp1 для хранения содержимого PHP для обработки). Обратите внимание, что это temp1 все пробелы с комментариями.

 find . -type f -name '*.php' | while read VAR; do php -wq $VAR > temp1 ; cat temp1 > $VAR; done 

Затем вы должны удалить файл temp1 после.

если PHP_BEAUTIFER установлен, то вы можете получить красиво отформатированный код без комментариев с помощью

 find . -type f -name '*.php' | while read VAR; do php -wq $VAR > temp1; php_beautifier temp1 > temp2; cat temp2 > $VAR; done; 

затем удалите два файла ( temp1 , temp2 )

Источник

Оцените статью