Reputation:
How to make a little function that given a directory it returns the number of lines (counts \r\n
) of .php
files between <?php and ?>
?
Usage:
echo countsLineOfCode('D:/dir/code/');
// returns 323;
Upvotes: 1
Views: 411
Reputation: 212412
PHPLOC
A tool for quickly measuring the size and analyzing the structure of a PHP project.
Upvotes: 1
Reputation: 26065
I made it work based on this Answer and the documentation for RecursiveDirectoryIterator.
$path = realpath( '/path/to/directory' );
$lines = $files = 0;
$objects = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator( $path ),
RecursiveIteratorIterator::SELF_FIRST
);
foreach( $objects as $name => $fileinfo )
{
if ( !$fileinfo->isFile() )
continue;
if( false === strpos( $name,'.php' ) )
continue;
$files++;
$read = $fileinfo->openFile();
$read->setFlags( SplFileObject::READ_AHEAD );
$lines += iterator_count( $read ) - 1; // -1 gives the same number as "wc -l"
}
printf( "Found %d lines in %d files.", $lines, $files );
Upvotes: 0
Reputation: 490283
function countLinesOfCode($path) {
$lines = 0;
$items = glob(rtrim($path, '/') . '/*');
foreach($items as $item) {
if (is_file($item) AND pathinfo($item, PATHINFO_EXTENSION) == 'php') {
$fileContents = file_get_contents($item);
preg_match_all('/<\?(?:php)?(.*?)($|\?>)/s', $fileContents, $matches);
foreach($matches[1] as $match) {
$lines += substr_count($match, PHP_EOL);
}
} else if (is_dir($item)) {
$lines += countLinesOfCode($item);
continue;
}
}
return $lines;
}
var_dump(countLinesOfCode(dirname(__FILE__))); // int(31) (works for me)
Keep in mine this is counting newlines, not end of line character ;
. For example, the line below will be considered one line...
var_dump($files); echo 'something'; exit;
It also counts lines without any PHP code, e.g. the below code will be 4 lines...
<?php
$a = 3;
It also doesn't count the <?php
or closing (if present).
Let me know if it (a) shouldn't match empty lines, (b) should match semi colons instead (will need to ensure they are not appearing within a string) and/or (c) it should match the opening and closing tag (will be easy as changing $matches[1]
in the foreach
to $matches[0]
).
Upvotes: 3
Reputation: 48111
recursive version of alex function
function countLinesOfCode($path) {
$lines = 0;
$files = glob(rtrim($path, '/') . '/*');
foreach($files as $file) {
if (is_dir($file)){
if ($file=='.' || $file=='..')
continue;
$lines+=countLinesOfCode($file);
} else if (substr($file,-4)!='.php')
continue;
echo 'Counting on ' . $file .'<br>';
$fileContents = file_get_contents($file);
preg_match_all('/<\?(?:php)?(.*?)(?:$|\?>)/s', $fileContents, $matches);
foreach($matches[1] as $match) {
$lines += substr_count($match, PHP_EOL);
}
}
return $lines;
}
Upvotes: 0