36

乱雑な php コードを適切にフォーマットするための優れたツールを知っていますか? できれば Aptana/Eclipse 用のスクリプトですが、スタンドアロン ツールでも十分です。

4

14 に答える 14

44

さて、ここに私の非常に基本的で大まかなスクリプトがあります:

#!/usr/bin/php
<?php
class Token {
    public $type;
    public $contents;

    public function __construct($rawToken) {
        if (is_array($rawToken)) {
            $this->type = $rawToken[0];
            $this->contents = $rawToken[1];
        } else {
            $this->type = -1;
            $this->contents = $rawToken;
        }
    }
}

$file = $argv[1];
$code = file_get_contents($file);

$rawTokens = token_get_all($code);
$tokens = array();
foreach ($rawTokens as $rawToken) {
    $tokens[] = new Token($rawToken);
}

function skipWhitespace(&$tokens, &$i) {
    global $lineNo;
    $i++;
    $token = $tokens[$i];
    while ($token->type == T_WHITESPACE) {
        $lineNo += substr($token->contents, "\n");
        $i++;
        $token = $tokens[$i];
    }
}

function nextToken(&$j) {
    global $tokens, $i;
    $j = $i;
    do {
        $j++;
        $token = $tokens[$j];
    } while ($token->type == T_WHITESPACE);
    return $token;
}

$OPERATORS = array('=', '.', '+', '-', '*', '/', '%', '||', '&&', '+=', '-=', '*=', '/=', '.=', '%=', '==', '!=', '<=', '>=', '<', '>', '===', '!==');

$IMPORT_STATEMENTS = array(T_REQUIRE, T_REQUIRE_ONCE, T_INCLUDE, T_INCLUDE_ONCE);

$CONTROL_STRUCTURES = array(T_IF, T_ELSEIF, T_FOREACH, T_FOR, T_WHILE, T_SWITCH, T_ELSE);
$WHITESPACE_BEFORE = array('?', '{', '=>');
$WHITESPACE_AFTER = array(',', '?', '=>');

foreach ($OPERATORS as $op) {
    $WHITESPACE_BEFORE[] = $op;
    $WHITESPACE_AFTER[] = $op;
}

$matchingTernary = false;

// First pass - filter out unwanted tokens
$filteredTokens = array();
for ($i = 0, $n = count($tokens); $i < $n; $i++) {
    $token = $tokens[$i];
    if ($token->contents == '?') {
        $matchingTernary = true;
    }
    if (in_array($token->type, $IMPORT_STATEMENTS) && nextToken($j)->contents == '(') {
        $filteredTokens[] = $token;
        if ($tokens[$i + 1]->type != T_WHITESPACE) {
            $filteredTokens[] = new Token(array(T_WHITESPACE, ' '));
        }
        $i = $j;
        do {
            $i++;
            $token = $tokens[$i];
            if ($token->contents != ')') {
                $filteredTokens[] = $token;
            }
        } while ($token->contents != ')');
    } elseif ($token->type == T_ELSE && nextToken($j)->type == T_IF) {
        $i = $j;
        $filteredTokens[] = new Token(array(T_ELSEIF, 'elseif'));
    } elseif ($token->contents == ':') {
        if ($matchingTernary) {
            $matchingTernary = false;
        } elseif ($tokens[$i - 1]->type == T_WHITESPACE) {
            array_pop($filteredTokens); // Remove whitespace before
        }
        $filteredTokens[] = $token;
    } else {
        $filteredTokens[] = $token;
    }
}
$tokens = $filteredTokens;

function isAssocArrayVariable($offset = 0) {
    global $tokens, $i;
    $j = $i + $offset;
    return $tokens[$j]->type == T_VARIABLE &&
        $tokens[$j + 1]->contents == '[' &&
        $tokens[$j + 2]->type == T_STRING &&
        preg_match('/[a-z_]+/', $tokens[$j + 2]->contents) &&
        $tokens[$j + 3]->contents == ']';
}

// Second pass - add whitespace
$matchingTernary = false;
$doubleQuote = false;
for ($i = 0, $n = count($tokens); $i < $n; $i++) {
    $token = $tokens[$i];
    if ($token->contents == '?') {
        $matchingTernary = true;
    }
    if ($token->contents == '"' && isAssocArrayVariable(1) && $tokens[$i + 5]->contents == '"') {
        /*
         * Handle case where the only thing quoted is the assoc array variable.
         * Eg. "$value[key]"
         */
        $quote = $tokens[$i++]->contents;
        $var = $tokens[$i++]->contents;
        $openSquareBracket = $tokens[$i++]->contents;
        $str = $tokens[$i++]->contents;
        $closeSquareBracket = $tokens[$i++]->contents;
        $quote = $tokens[$i]->contents;        
        echo $var . "['" . $str . "']";
        $doubleQuote = false;
        continue;
    }
    if ($token->contents == '"') {
        $doubleQuote = !$doubleQuote;
    }
    if ($doubleQuote && $token->contents == '"' && isAssocArrayVariable(1)) {
        // don't echo "
    } elseif ($doubleQuote && isAssocArrayVariable()) {
        if ($tokens[$i - 1]->contents != '"') {
            echo '" . ';
        }
        $var = $token->contents;
        $openSquareBracket = $tokens[++$i]->contents;
        $str = $tokens[++$i]->contents;
        $closeSquareBracket = $tokens[++$i]->contents;
        echo $var . "['" . $str . "']";
        if ($tokens[$i + 1]->contents != '"') {
            echo ' . "';
        } else {
            $i++; // process "
            $doubleQuote = false;
        }
    } elseif ($token->type == T_STRING && $tokens[$i - 1]->contents == '[' && $tokens[$i + 1]->contents == ']') {
        if (preg_match('/[a-z_]+/', $token->contents)) {
            echo "'" . $token->contents . "'";
        } else {
            echo $token->contents;
        }
    } elseif ($token->type == T_ENCAPSED_AND_WHITESPACE || $token->type == T_STRING) {
        echo $token->contents;
    } elseif ($token->contents == '-' && in_array($tokens[$i + 1]->type, array(T_LNUMBER, T_DNUMBER))) {
        echo '-';
    } elseif (in_array($token->type, $CONTROL_STRUCTURES)) {
        echo $token->contents;
        if ($tokens[$i + 1]->type != T_WHITESPACE) {
            echo ' ';
        }
    } elseif ($token->contents == '}' && in_array($tokens[$i + 1]->type, $CONTROL_STRUCTURES)) {
        echo '} ';
    } elseif ($token->contents == '=' && $tokens[$i + 1]->contents == '&') {
        if ($tokens[$i - 1]->type != T_WHITESPACE) {
            echo ' ';
        }
        $i++; // match &
        echo '=&';
        if ($tokens[$i + 1]->type != T_WHITESPACE) {
            echo ' ';          
        }
    } elseif ($token->contents == ':' && $matchingTernary) {
        $matchingTernary = false;
        if ($tokens[$i - 1]->type != T_WHITESPACE) {
            echo ' ';
        }
        echo ':';
        if ($tokens[$i + 1]->type != T_WHITESPACE) {
            echo ' ';
        }
    } elseif (in_array($token->contents, $WHITESPACE_BEFORE) && $tokens[$i - 1]->type != T_WHITESPACE &&
        in_array($token->contents, $WHITESPACE_AFTER) && $tokens[$i + 1]->type != T_WHITESPACE) {
        echo ' ' . $token->contents . ' ';
    } elseif (in_array($token->contents, $WHITESPACE_BEFORE) && $tokens[$i - 1]->type != T_WHITESPACE) {
        echo ' ' . $token->contents;
    } elseif (in_array($token->contents, $WHITESPACE_AFTER) && $tokens[$i + 1]->type != T_WHITESPACE) {
        echo $token->contents . ' ';
    } else {
        echo $token->contents;
    }
}
于 2009-01-30T02:28:14.917 に答える
15

http://ja.sourceforge.jp/projects/pdt-tools/

^^^ Java のような適切な CTRL+SHIFT+F Eclipse/Aptana PHP フォーマッターを提供します。

インストールのヘルプについては、こちらを参照してください。

Eclipse php コードフォーマッター

于 2010-08-19T00:14:00.937 に答える
13

PHP Code Beautifierは便利な無料ツールですが、ダウンロード ページではアカウントを作成する必要があります。

ツールは 3 つのバージョンに拒否されました。

  • ファイルを視覚的に処理できるGUIバージョン。
  • 他のツール (CVS、SubVersion、IDE ...) とのバッチ処理または統合が可能なコマンド ライン バージョン。
  • PHPEdit の統合ツールとして。

基本的には、次のようになります。

if($code == BAD){$action = REWRITE;}else{$action = KEEP;}
for($i=0; $i<10;$i++){while($j>0){$j++;doCall($i+$j);if($k){$k/=10;}}}

の中へ

if ($code == BAD) {
    $action = REWRITE;
} else {
    $action = KEEP;
}
for($i = 0; $i < 10;$i++) {
    while ($j > 0) {
        $j++;
        doCall($i + $j);
        if ($k) {
            $k /= 10;
        }
    }
}
于 2008-09-29T18:36:01.800 に答える
6

コードをフォーマットする pear モジュールがあります。PHP 美化ツール

于 2010-08-06T21:10:03.420 に答える
5

Zend 開発環境を使用している場合は、コードのインデント機能 (Ctrl+Shift+F) を使用できます。

于 2008-09-29T16:55:52.057 に答える
4

これがphpコードビューティファイア(もちろんPHP)クラスです:http:
//www.codeassembly.com/A-php-code-beautifier-that-works/

オンラインデモ:

http://www.codeassembly.com/examples/beautifier.php

于 2008-09-29T17:52:51.950 に答える
3

Zend 開発環境は Eclipse プラグインになりました。Aptana と一緒に実行して、コードのインデント機能を使用することができます。

ゼンド スタジオ

私はまだ Eclipse プラグインにアップグレードしていません。以前の ZDE が大好きです。実際に他の言語で Eclipse を使い始めた今では、飛躍する準備がほぼ整っています。

于 2008-09-29T17:01:12.637 に答える
2

最も簡単な解決策は、これが組み込まれている IDE を使用することです。定期的に PHP でコードを記述する場合は、PHPStorm の $60 を落としてください。後悔することはありません。

http://www.jetbrains.com/phpstorm/

ファイルまたはディレクトリ レベルで簡単なキーボード ショートカットを使用して、コードを好きなようにフォーマットでき、他にも無数の優れた機能があります。

于 2012-04-17T20:36:19.557 に答える
1

当社のPHP フォーマッターは、コードを確実にフォーマットします。コンパイラ ベースのフロント エンドを使用してコードを解析するため、コードを誤って解釈して破損することはありません。したがって、フォーマットされた出力は常に機能します。

于 2010-05-18T04:41:08.120 に答える
0

これは素晴らしい質問です。json を読み取り、php、html、css を出力するアプリケーションがあります。プログラムを実行して、数十 (数百?) のファイルを生成します。ここでの回答がお役に立てば幸いです。

ヒアドキュメント、特別なインクルード ファイル、メタ文字などを使用してプロジェクトを開始しましたが、すぐに混乱してしまいました。フレームワークや IDE を必要としないスタンドアロン ソリューションが必要でした。そこで、ヒアドキュメントやその他のジャンクをすべて削除し、書式設定を考慮しない汎用テキスト バッファリング クラスを作成しました。それはすべて、私が気にかけているすべてのことを 1 行で表すことができます。html の場合、tidy() 組み込みを行います。PHP の場合、 phpstylistを使用します。phpstylist は古いですが、php 形式でも問題なく動作します。

phpstylist オプションを設定するために、Windows GUI でUniversalIndent (2012 年 1 月更新) を使用しました。

UniversalStylist には、24 (!) のフォーマッタ プログラム (c、php、ruby、html など) がリストされています。特に phpstylist のオプションを認識しており、オプションをオンまたはオフにすると、ファイルをライブで更新できます。すごくいい。次に、スタイルを作成すると、コマンド ライン オプションを保存してスクリプトを生成するオプションが表示されます。一部の書式設定オプションでは、perl、python などへのパスを追加する必要があります。

Windows を使用していて、UniversalIndent で phpstylist を試したい場合は、php.exe のディレクトリを環境パスに追加するだけです。私はamppsを使用しているので、c:\ampps\php に設定されています。

適切な解決策を見つけるのは簡単ではありませんでした。また、コード レビューとアーカイブの目的で、自動生成された php/html ファイルのバッチ フォーマットを可能な限り単純にするために、他の人が何をしているのかを聞くことにも興味があります。

于 2012-07-22T05:26:42.300 に答える
0

phpformatter.comが最適です

「この無料のオンライン PHP フォーマッターは、すべての PHP スクリプトを好みのスタイルで美しくすることができるように設計されています。」

于 2012-05-12T02:19:40.290 に答える
-1

PHP 用のまともな無料のフォーマッタを見つけるのにも苦労しました。多くのオンラインおよびコマンドライン ツールがありますが、何らかの理由で機能しないようです。結果はまだ悪いインデントでいっぱいです。タブとスペースの組み合わせで、中括弧を希望どおりに取得することはできません!

上記のスニペットを試してみましたが、それでもうまくいきませんでした。インデントはまだスペースとタブでいっぱいで、すべてが混同されていました。

だから私も簡単なものを書いてみました.これはすべての正規表現を使用しているだけで、派手なコンパイラの魔法はありません. インターフェイスも現時点では非常に基本的なものですが、今後数日で改善されるはずです。

これは MediaWiki の規約に合わせて組み込まれていますが、かなり簡単に変更できます (後でオプションを追加する可能性があります)。

https://www.organicdesign.co.nz/Special:CodeTidy

于 2015-05-21T19:58:51.863 に答える