diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/README.md b/README.md index fb6b73c..993af63 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,14 @@ Command-line script to convert PHP's `array()` syntax to PHP 5.4's short array s By relying on the PHP tokenizer, nothing but the array syntax itself will be altered. The script was successfully tested against code bases with more than 5.000 PHP files. +Installation via Composer +=========== +Just add `"thomasbachem/php-short-array-syntax-converter": "dev-master"` to your require(-dev) section and run update command on Composer. Usage ================================ - Usage: php convert.php [-w] + Usage: php array-converter.php [-w] Run the script with the path of the PHP file you wish to convert as argument. This will print the converted source code to STDOUT. @@ -19,7 +22,7 @@ In case of any error, an error message is written to STDERR and the script exits Use `find` to convert a whole directory recursively: - find -name "*.php" -exec php "convert.php" -w "{}" \; + find -name "*.php" -exec php "array-converter.php" -w "{}" \; In case you don't trust the script yet, you can even perform a syntax check after conversion: diff --git a/array-converter.php b/array-converter.php new file mode 100644 index 0000000..7882c84 --- /dev/null +++ b/array-converter.php @@ -0,0 +1,147 @@ + + */ + + +// - - - - - HANDLE COMMAND LINE ARGUMENTS - - - - - + +$filePath = null; +$saveFile = false; + +if ($argc > 3) { + file_put_contents('php://stderr', 'Usage: php convert.php [-w] ' . "\n"); + exit(1); +} +for ($i = 1; $i < $argc; ++$i) { + if ($argv[$i] && $argv[$i][0] == '-') { + $saveFile = ($argv[$i] == '-w'); + } else { + $filePath = $argv[$i]; + } +} + +if (!$filePath) { + file_put_contents('php://stderr', 'Usage: php array-converter.php [-w] ' . "\n"); + exit(1); +} elseif (!file_exists($filePath)) { + file_put_contents('php://stderr', 'File "' . $filePath . '" not found.' . "\n"); + exit(1); +} + + +// - - - - - READ ORIGINAL CODE - - - - - + +$code = file_get_contents($filePath); +$tokens = token_get_all($code); + + +// - - - - - PARSE CODE - - - - - + +$replacements = array(); +$offset = 0; +for ($i = 0; $i < count($tokens); ++$i) { + // Keep track of the current byte offset in the source code + $offset += strlen(is_array($tokens[$i]) ? $tokens[$i][1] : $tokens[$i]); + + // T_ARRAY could either mean the "array(...)" syntax we're looking for + // or a type hinting statement ("function(array $foo) { ... }") + if (is_array($tokens[$i]) && $tokens[$i][0] === T_ARRAY) { + // Look for a subsequent opening bracket ("(") to be sure we're actually + // looking at an "array(...)" statement + $isArraySyntax = false; + $subOffset = $offset; + for ($j = $i + 1; $j < count($tokens); ++$j) { + $subOffset += strlen(is_array($tokens[$j]) ? $tokens[$j][1] : $tokens[$j]); + + if (is_string($tokens[$j]) && $tokens[$j] == '(') { + $isArraySyntax = true; + break; + } elseif (!is_array($tokens[$j]) || $tokens[$j][0] !== T_WHITESPACE) { + $isArraySyntax = false; + break; + } + } + + if ($isArraySyntax) { + // Replace "array" and the opening bracket (including preceeding whitespace) with "[" + $replacements[] = array( + 'start' => $offset - strlen($tokens[$i][1]), + 'end' => $subOffset, + 'string' => '[', + ); + + // Look for matching closing bracket (")") + $subOffset = $offset; + $openBracketsCount = 0; + for ($j = $i + 1; $j < count($tokens); ++$j) { + $subOffset += strlen(is_array($tokens[$j]) ? $tokens[$j][1] : $tokens[$j]); + + if (is_string($tokens[$j]) && $tokens[$j] == '(') { + ++$openBracketsCount; + } elseif (is_string($tokens[$j]) && $tokens[$j] == ')') { + --$openBracketsCount; + + if ($openBracketsCount == 0) { + // Replace ")" with "]" + $replacements[] = array( + 'start' => $subOffset - 1, + 'end' => $subOffset, + 'string' => ']', + ); + break; + } + } + } + } + } +} + + +// - - - - - UPDATE CODE - - - - - + +// Apply the replacements to the source code +$offsetChange = 0; +foreach ($replacements as $replacement) { + $code = substr_replace( + $code, + $replacement['string'], + $replacement['start'] + $offsetChange, + $replacement['end'] - $replacement['start'] + ); + $offsetChange += strlen($replacement['string']) - ($replacement['end'] - $replacement['start']); +} + + +// - - - - - OUTPUT/WRITE NEW CODE - - - - - + +if ($saveFile) { + file_put_contents($filePath, $code); +} else { + print $code; +} \ No newline at end of file diff --git a/bin/array-converter b/bin/array-converter new file mode 100755 index 0000000..4d66a68 --- /dev/null +++ b/bin/array-converter @@ -0,0 +1,4 @@ +#!/usr/bin/env php +=5.4" + }, + "bin": [ + "bin/array-converter" + ] +} diff --git a/convert.php b/convert.php deleted file mode 100644 index be299d5..0000000 --- a/convert.php +++ /dev/null @@ -1,144 +0,0 @@ - - */ - - -// - - - - - HANDLE COMMAND LINE ARGUMENTS - - - - - - -$filePath = null; -$saveFile = false; - -if($argc > 3) { - file_put_contents('php://stderr', 'Usage: php convert.php [-w] ' . "\n"); - exit(1); -} -for($i = 1; $i < $argc; ++$i) { - if($argv[$i] && $argv[$i][0] == '-') { - $saveFile = ($argv[$i] == '-w'); - } else { - $filePath = $argv[$i]; - } -} - -if(!$filePath) { - file_put_contents('php://stderr', 'Usage: php convert.php [-w] ' . "\n"); - exit(1); -} elseif(!file_exists($filePath)) { - file_put_contents('php://stderr', 'File "' . $filePath . '" not found.' . "\n"); - exit(1); -} - - -// - - - - - READ ORIGINAL CODE - - - - - - -$code = file_get_contents($filePath); -$tokens = token_get_all($code); - - -// - - - - - PARSE CODE - - - - - - -$replacements = array(); -$offset = 0; -for($i = 0; $i < count($tokens); ++$i) { - // Keep track of the current byte offset in the source code - $offset += strlen(is_array($tokens[$i]) ? $tokens[$i][1] : $tokens[$i]); - - // T_ARRAY could either mean the "array(...)" syntax we're looking for - // or a type hinting statement ("function(array $foo) { ... }") - if(is_array($tokens[$i]) && $tokens[$i][0] === T_ARRAY) { - // Look for a subsequent opening bracket ("(") to be sure we're actually - // looking at an "array(...)" statement - $isArraySyntax = false; - $subOffset = $offset; - for($j = $i + 1; $j < count($tokens); ++$j) { - $subOffset += strlen(is_array($tokens[$j]) ? $tokens[$j][1] : $tokens[$j]); - - if(is_string($tokens[$j]) && $tokens[$j] == '(') { - $isArraySyntax = true; - break; - } elseif(!is_array($tokens[$j]) || $tokens[$j][0] !== T_WHITESPACE) { - $isArraySyntax = false; - break; - } - } - - if($isArraySyntax) { - // Replace "array" and the opening bracket (including preceeding whitespace) with "[" - $replacements[] = array( - 'start' => $offset - strlen($tokens[$i][1]), - 'end' => $subOffset, - 'string' => '[', - ); - - // Look for matching closing bracket (")") - $subOffset = $offset; - $openBracketsCount = 0; - for($j = $i + 1; $j < count($tokens); ++$j) { - $subOffset += strlen(is_array($tokens[$j]) ? $tokens[$j][1] : $tokens[$j]); - - if(is_string($tokens[$j]) && $tokens[$j] == '(') { - ++$openBracketsCount; - } elseif(is_string($tokens[$j]) && $tokens[$j] == ')') { - --$openBracketsCount; - - if($openBracketsCount == 0) { - // Replace ")" with "]" - $replacements[] = array( - 'start' => $subOffset - 1, - 'end' => $subOffset, - 'string' => ']', - ); - break; - } - } - } - } - } -} - - -// - - - - - UPDATE CODE - - - - - - -// Apply the replacements to the source code -$offsetChange = 0; -foreach($replacements as $replacement) { - $code = substr_replace($code, $replacement['string'], $replacement['start'] + $offsetChange, $replacement['end'] - $replacement['start']); - $offsetChange += strlen($replacement['string']) - ($replacement['end'] - $replacement['start']); -} - - -// - - - - - OUTPUT/WRITE NEW CODE - - - - - - -if($saveFile) { - file_put_contents($filePath, $code); -} else { - print $code; -} - -?> \ No newline at end of file