Лучший способ автоматического удаления комментариев из PHP-кода
Каков наилучший способ удалить комментарии из файла PHP?
Я хочу сделать что-то похожее на strip-whitespace() - но он также не должен удалять разрывы строк.
EG:
Я хочу это:
<?PHP
// something
if ($whatsit) {
do_something(); # we do something here
echo '<html>Some embedded HTML</html>';
}
/* another long
comment
*/
some_more_code();
?>
чтобы стать:
<?PHP
if ($whatsit) {
do_something();
echo '<html>Some embedded HTML</html>';
}
some_more_code();
?>
(Хотя, если пустые строки остаются там, где комментарии удалены, это не будет нормально).
Это может быть невозможно, из-за требования сохранить встроенный html - вот что сработало, что появилось в Google.
Ответы
Ответ 1
Я бы использовал tokenizer. Вот мое решение. Он должен работать как на 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;
Ответ 2
Как насчет использования php -w для создания файла, лишенного комментариев и пробелов, а затем с помощью декоратора, такого как PHP_Beautifier, чтобы переформатировать для удобочитаемости
Ответ 3
$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 уже предложил это, но я оставлю здесь пример
Ответ 4
Здесь функция, опубликованная выше, изменена, чтобы рекурсивно удалить все комментарии из всех 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");
Ответ 5
версия более мощная: удалите все комментарии в папке
<?php
$di = new RecursiveDirectoryIterator(__DIR__,RecursiveDirectoryIterator::SKIP_DOTS);
$it = new RecursiveIteratorIterator($di);
$fileArr = [];
foreach($it as $file){
if(pathinfo($file,PATHINFO_EXTENSION) == "php"){
ob_start();
echo $file;
$file = ob_get_clean();
$fileArr[] = $file;
}
}
$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);
}
Ответ 6
Если вы уже используете такой редактор, как UltraEdit, вы можете открыть один или несколько файлов PHP, а затем использовать простой поиск и замену (CTRL + R) следующий Perl regexp
(?s)/\*.*\*/
Остерегайтесь вышеуказанного regexp удаляет также комментарии внутри sring, т.е. в echo "hello/*babe*/";
тоже будет удалено /*babe*/
. Следовательно, это может быть решением, если у вас мало файлов для удаления комментариев, чтобы быть абсолютно уверенным, что он не ошибочно заменяет что-то, что не является комментарием, который вам нужно будет запустить командой Find & Replace и каждый раз утверждать, что происходит заменить.
Ответ 7
/*
* 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) {
remove_comment($file);
}
Ответ 8
Для ответов ajax/json я использую следующий код PHP, чтобы удалить комментарии из кода HTML/JavaScript, поэтому он будет меньше (примерно 15% для моего кода).
// Replace doubled spaces with single ones (ignored in HTML any way)
$html = preg_replace('@(\s){2,}@', '\1', $html);
// Remove single and multiline comments, tabs and newline chars
$html = preg_replace(
'@(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|((?<!:)//.*)|[\t\r\n]@i',
'',
$html
);
Короткий и эффективный, но может привести к неожиданным результатам, если ваш код имеет синтаксис $itty.
Ответ 9
Bash Решение. Если вы хотите удалить рекурсивные комментарии из всех файлов PHP, начиная с текущего каталога, вы можете записать в терминал этот однострочный. (он использует файл temp1
для хранения содержимого PHP для обработки)
Обратите внимание, что это разделит все пробелы с комментариями.
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
)
Ответ 10
Запустите команду php --strip file.php
в командной строке (например, cmd.exe), затем перейдите к http://www.writephponline.com/phpbeautifier.
Здесь файл .php - это ваш собственный файл.
![1]()
Ответ 11
Ловушка заключается в том, что менее надежный алгоритм совпадения (например, простого регулярного выражения) начнет снимать здесь, когда он явно не должен:
if (preg_match('#^/*' . $this->index . '#', $this->permalink_structure)) {
Это может не повлиять на ваш код, но в конечном итоге кто-то получит ваш script. Таким образом, вам придется использовать утилиту, которая понимает больше языка, чем вы могли бы ожидать.
-Adam
Ответ 12
в 2019 году может работать так
<?php
/* hi there !!!
here are the comments */
//another try
echo removecomments('index.php');
/* hi there !!!
here are the comments */
//another try
function removecomments($f){
$w=Array(';','{','}');
$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, затем вы получите пустую страницу, но если вы щелкнете правой кнопкой мыши и нажмете на просмотр исходного кода, вы получите скрипт php.. он загружается сам и удаляет все комментарии, а также вкладки. Я тоже предпочитаю это решение, потому что я использую его, чтобы ускорить мой фреймворк с одним файловым движком "m.php", и после php_strip_whitespace весь исходный код без этого скрипта, который я наблюдаю, работает медленнее: я сделал 10 тестов, а затем вычислил математическое среднее (я думаю, что php 7 восстанавливает пропущенные данные cr_lf, когда выполняется синтаксический анализ или занимает некоторое время, когда они отсутствуют)
Ответ 13
php -w
или php_strip_whitespace($filename);
документация