Do you know any good tools for nicely formatting messy php code? Preferably a script for Aptana/Eclipse, but a standalone tool will do too.
-
Of all I have tried, this is the best you get online: http://www.cleancss.com/php-beautify. Caveat: avoid the starting – nawfal Nov 17 '15 at 15:25
14 Answers
Well here is my very basic and rough script:
#!/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;
}
}

- 15,842
- 19
- 64
- 67
-
30Why use an existing, tested tool when you can write your own? +1 for writing it in php. – postfuturist Jan 31 '09 at 00:26
-
2
-
6Yes I wrote my own cause I couldn't find any existing one that I was happy with. – grom May 20 '10 at 00:11
-
-
3
-
how can i execute this? i cant run this script.. it said filename cannot be empty... =/ i hope give us instruction step by step. thanks. – user453089 Nov 04 '11 at 16:28
-
I just tried this from Cygwin. Doesn't seem to work anymore. It basically printed out my original source code. Is this because Stack Overflow changed your script, for example, tab turned into space, or vice versa? – oldpride Sep 17 '20 at 01:11
http://en.sourceforge.jp/projects/pdt-tools/
^^^ will give you a proper CTRL+SHIFT+F Eclipse/Aptana PHP formatter like Java.
See here for installation help.

- 1,419
- 14
- 17
-
1
-
Just loaded fine for me. Page title is, "Aptana and Eclispe - Code Formatter for PHP Development Tools for Eclipse". – Chris Jun 01 '11 at 18:14
-
The project seems to be dead on sourceforge. Di you know where I can it now ? – deadalnix Oct 12 '11 at 14:31
PHP Code Beautifier is a useful free tool that should do what you're after, although their download page does require an account to be created.
The tool has been declined into 3 versions:
- A GUI version which allow to process file visually.
- A command line version which allow to be batched or integrated with other tools (CVS, SubVersion, IDE ...).
- As an integrated tool of PHPEdit.
Basically, it'll turn:
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;}}}
into
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;
}
}
}

- 40,958
- 16
- 80
- 86
-
5FWIW, this appears to be a closed-source app and is not available for Mac OS X. – nohat Oct 06 '09 at 17:45
-
2Did this actually work for anyone? I tried the example command-line on a well-formatted script and it produced a very uneven indentation: 8 spaces for the first line of each function but 8 or 9 for the remaining lines (seemed random). Plus the closing brace for functions was always indented to 9 spaces. – David Harkness Jun 10 '11 at 18:11
-
2I can confirm. It creates code which needs to be formatted one more time with another tool :| – Pawka Sep 06 '11 at 23:02
-
6**Be aware: This "tool" is outdated, unsupported and not open source!** – mate64 Feb 14 '15 at 00:51
-
2
-
How are you supposed to use that if you need format on each... save? – pronebird Jun 10 '18 at 11:28
There's a pear module that formats your code. PHP Beautifier

- 1,192
- 1
- 9
- 11
-
This looks to have promise, but I couldn't get most of the options to work (e.g. class/function brace position and newlines before else). Plus it removes *all* blank lines, even between functions and class properties, and I couldn't see a list of tokens for the NewLines filter. Is there a mailing list for this project? – David Harkness Jun 10 '11 at 18:15
-
-
Well, the good thing is: It is FOSS, so can you extend it to your liking. – Deckard May 20 '12 at 20:14
If you use Zend Development Environment, you can use the Indent Code feature (Ctrl+Shift+F).

- 12,840
- 6
- 48
- 70
Here's a php code beautifier (PHP of course) class:
http://www.codeassembly.com/A-php-code-beautifier-that-works/
and
online demo:

- 12,356
- 2
- 32
- 37
-
Indeed, the example is gone. Here's another beautify library: https://github.com/clbustos/PHP_Beautifier – micahwittman Feb 17 '13 at 17:48
-
2
The Zend Development Environment is now an Eclipse plugin, you may be able to run it alongside Aptana and just use it's Indent Code feature.
I haven't upgraded to the Eclipse plugin yet myself, I love the previous ZDE so much. Though now that I've started actually using Eclipse for other languages, I'm almost ready to make the leap.

- 7,800
- 2
- 25
- 24
The simplest solution is to just use an IDE that has this built in. If you're going to be writing code in PHP on a regular a regular basis, just drop the $60 for PHPStorm. You won't regret it.
http://www.jetbrains.com/phpstorm/
It lets you format your code however you like using a simple keyboard shortcut at the file or directory level, and has a zillion other great features.

- 29
- 1
-
2oh, also NetBeans AND Eclipse have one built in too and they are both free so I really don't understand the point of this question... – Aaron Apr 17 '12 at 21:35
What about this one:
http://universalindent.sourceforge.net/
It combines a bunch of formatters out there, and will generate the scripts you need so you can pass them out and get your team members to use them before committing next time... Though... formatters might mess up your code and render it unusable...

- 10,234
- 5
- 32
- 42
-
2
-
Any formatter that runs automatically will have this risk, so it is worth noting – SeanJA Apr 27 '10 at 14:02
-
Formatters don't have to break your code. They have to parse it accurately. Those that "parse" using regexes usually fail to do so, thus... breakage. – Ira Baxter May 18 '10 at 04:39
-
It could also run out of memory or run into an exception or you could write some code that the parser does not understand (features that have been added to a more recent version of the language but are not yet supported by your parser). – SeanJA May 18 '10 at 20:17
-
A formatter isn't likely to run out of memory; a gigabyte of RAM is a lot even compare to 100K lines of PHP script. If you can write code that the parser doesn't understand, then the parser is stupidly implemented; good ones are not, and good ones are up-to-date with respect to the PHP langauge facilities. – Ira Baxter May 19 '10 at 16:07
-
Ok... but if *you* do not keep the formatter up to date... then you will screw up your code. – SeanJA May 19 '10 at 20:25
-
Also, since this one includes the formatter that was in the accepted solution, I don't see why you are debating the fact that it can screw up your code. – SeanJA May 19 '10 at 20:26
This is an excellent question. I have an application that reads json and outputs php and html and css. I run a program and generate dozens (hundreds?) of files. I hope the answer here is useful.
I started my project using heredocs, special include files, meta chars, etc but that quickly became a mess. I wanted a stand-alone solution that didn't require framework or ide. So I removed all the heredoc and other junk and created a generic text buffering class with no concern for formatting. It can all be one line for all I care. For html, I do tidy() built-in. For php, I use phpstylist. phpstylist is older but still works well for php format.
To set up the phpstylist options I used UniversalIndent (updated Jan 2012) in windows gui.
UniversalStylist lists 24 (!) formatter programs (c, php, ruby, html,...). It specifically knows the options for phpstylist and gives you a live refresh on a file as you turn options on and off. Very great. Then, when you have your style, it has an option to save the command line options and generates a script. For some formatting options you'll have to add paths to perl, python, etc.
If you are using windows and want to try phpstylist with UniversalIndent, just add directory for php.exe to your env path. I use ampps so mine is set to c:\ampps\php.
It was not very easy to find a good solid solution. I'm also interested in hearing what other people do for simple as possible batch formatting of auto-generated php/html files for code review and archiving purposes.

- 85
- 7
Our PHP Formatter will reliably format your code. It uses a compiler-based front end to parse the code, so it doesn't misinterpret the code and damage it. Consequently its formatted output always works.

- 93,541
- 22
- 172
- 341
-
4
-
-
How does a "compiler based front end" magically save you from bugs in your formatter code? – cweiske Apr 30 '11 at 12:02
-
2@Cweiske: It doesnt. But because it is intended for heavy-duty use, it is built on extremely solid foundations, including machinery to correctly capture lexemes (especially HTML text and string literals with their complex syntax in PHP), and a huge amount of energy invested in careful testing. This is much more reliable than some ad hoc formatter based on regular expressions and string hacking, which often make mistakes when encountering complex syntax such as strings and comments, which can contain things that look like code. – Ira Baxter Apr 30 '11 at 13:31
-
phpformatter.com works best
"This free online PHP Formatter is designed so that you can beautify all your PHP script with the style that you prefer"

- 9,251
- 18
- 72
- 86
I've been having a lot of trouble finding a decent free formatter for PHP as well, there are many online and command-line tools but they just don't seem to work for some reason, the results are all still full of bad indenting with combinations of tabs and spaces, and they never get the braces the way you want them!
I tried the snippet above and that didn't work for me either, indenting still full of spaces and tabs all mixed up.
So I've had a go at writing a simple one too, this one just uses all regex, no fancy compiler magic, so it's possible that it could break things, and is still very beta and being tested on various messy code. The interface is very basic at the moment too, but should improve over the next few days.
It's hardwired for MediaWiki's conventions, but you can modify it pretty easily (I may add options later).

- 81
- 1
- 7