61

Do you know any tool which can count all the code lines from a PHP project?

user2284570
  • 2,891
  • 3
  • 26
  • 74
Duncan Benoit
  • 3,297
  • 8
  • 29
  • 26

7 Answers7

106

On a POSIX operating system (e.g. Linux or OS X) you can write the following into your Bash shell:

wc -l `find . -iname "*.php"`

This will count the lines in all php-files in the current directory and also subdirectories. (Note that those single 'quotes' are backticks, not actual single quotes)

Henrik Paul
  • 66,919
  • 31
  • 85
  • 96
  • 2
    And if you are on Windows, you can download and install Cygwin, and do likewise. Since Mac runs on top of a BSD OS now as well, I consider this the definitive answer. – Dexygen Apr 26 '09 at 14:47
  • 1
    Keep in mind if you've got a lot of PHP template files and/or other PHP files with mixed PHP/HTML code, this isn't going to exclude HTML only lines. – Alana Storm Apr 26 '09 at 15:17
  • 1
    There is a limit to the command length in the shell; large codebases will exceed this. – eukras Oct 18 '12 at 07:53
  • Unfortunately this doesn't work for Drupal and other projects that use different extensions for PHP code such as .module, .inc, and more – the Jun 14 '13 at 08:43
  • loged in to like this) – Altenrion Jul 07 '16 at 14:30
20

I made myself a small script to do that in one of my projects. Simply use the following code on a php page in the root of your project. The script will do recursive check on sub folders.

<?php
/**
 * A very simple stats counter for all kind of stats about a development folder
 * 
 * @author Joel Lord
 * @copyright Engrenage (www.engrenage.biz)
 * 
 * For more information: joel@engrenage.biz

 */


$fileCounter = array();
$totalLines = countLines('.', $fileCounter); 
echo $totalLines." lines in the current folder<br>";
echo $totalLines - $fileCounter['gen']['commentedLines'] - $fileCounter['gen']['blankLines'] ." actual lines of code (not a comment or blank line)<br><br>";

foreach($fileCounter['gen'] as $key=>$val) {
    echo ucfirst($key).":".$val."<br>";
}

echo "<br>";

foreach($fileCounter as $key=>$val) {
    if(!is_array($val)) echo strtoupper($key).":".$val." file(s)<br>";
}




function countLines($dir, &$fileCounter) {
    $_allowedFileTypes = "(html|htm|phtml|php|js|css|ini)";
    $lineCounter = 0;
    $dirHandle = opendir($dir);
    $path = realpath($dir);
    $nextLineIsComment = false;

    if($dirHandle) {
        while(false !== ($file = readdir($dirHandle))) {
            if(is_dir($path."/".$file) && ($file !== '.' && $file !== '..')) {
                $lineCounter += countLines($path."/".$file, $fileCounter);
            } elseif($file !== '.' && $file !== '..') {
                //Check if we have a valid file 
                $ext = _findExtension($file);
                if(preg_match("/".$_allowedFileTypes."$/i", $ext)) {
                    $realFile = realpath($path)."/".$file;
                    $fileHandle = fopen($realFile, 'r');
                    $fileArray = file($realFile);
                    //Check content of file:
                    for($i=0; $i<count($fileArray); $i++) {
                        if($nextLineIsComment) {
                            $fileCounter['gen']['commentedLines']++;
                            //Look for the end of the comment block
                            if(strpos($fileArray[$i], '*/')) {
                                $nextLineIsComment = false;
                            }
                        } else {
                            //Look for a function
                            if(strpos($fileArray[$i], 'function')) {
                                $fileCounter['gen']['functions']++;
                            }
                            //Look for a commented line
                            if(strpos($fileArray[$i], '//')) {
                                $fileCounter['gen']['commentedLines']++;
                            }
                            //Look for a class
                            if(substr(trim($fileArray[$i]), 0, 5) == 'class') {
                                $fileCounter['gen']['classes']++;
                            }
                            //Look for a comment block
                            if(strpos($fileArray[$i], '/*')) {
                                $nextLineIsComment = true;
                                $fileCounter['gen']['commentedLines']++;
                                $fileCounter['gen']['commentBlocks']++;
                            }
                            //Look for a blank line
                            if(trim($fileArray[$i]) == '') {
                                $fileCounter['gen']['blankLines']++;
                            }
                        }

                    }
                    $lineCounter += count($fileArray);
                }
                //Add to the files counter
                $fileCounter['gen']['totalFiles']++;
                $fileCounter[strtolower($ext)]++;
            }
        }
    } else echo 'Could not enter folder';

    return $lineCounter;
}

function _findExtension($filename) {
    $filename = strtolower($filename) ; 
    $exts = split("[/\\.]", $filename) ; 
    $n = count($exts)-1; 
    $exts = $exts[$n]; 
    return $exts;  
}
Joel Lord
  • 2,175
  • 1
  • 18
  • 25
  • Wow, what a perfect code for any programmer. Does it calculates its own lines? – quantme Nov 24 '12 at 15:37
  • Produces a lot of noise... Arrays and other values are uninitialized when used. – Nux Sep 28 '14 at 00:13
  • 4
    I did a heavy edit to this code snippet and posted it to github. It fixes all the warnings and allows directories to be excluded during the count. https://raw.githubusercontent.com/danielson317/php-code-stats/master/code_stats.php – danielson317 May 08 '15 at 18:01
15

SLOCCount is an awesome tool that produces a line-count report for a large number of languages. It also goes further by producing other, related statistics such as expected developer cost.

Here's an example:

$ sloccount .
Creating filelist for experimental
Creating filelist for prototype
Categorizing files.
Finding a working MD5 command....
Found a working MD5 command.
Computing results.


SLOC    Directory   SLOC-by-Language (Sorted)
10965   experimental    cpp=5116,ansic=4976,python=873
832     prototype       cpp=518,tcl=314


Totals grouped by language (dominant language first):
cpp:           5634 (47.76%)
ansic:         4976 (42.18%)
python:         873 (7.40%)
tcl:            314 (2.66%)




Total Physical Source Lines of Code (SLOC)                = 11,797
Development Effort Estimate, Person-Years (Person-Months) = 2.67 (32.03)
 (Basic COCOMO model, Person-Months = 2.4 * (KSLOC**1.05))
Schedule Estimate, Years (Months)                         = 0.78 (9.33)
 (Basic COCOMO model, Months = 2.5 * (person-months**0.38))
Estimated Average Number of Developers (Effort/Schedule)  = 3.43
Total Estimated Cost to Develop                           = $ 360,580
 (average salary = $56,286/year, overhead = 2.40).
SLOCCount, Copyright (C) 2001-2004 David A. Wheeler
SLOCCount is Open Source Software/Free Software, licensed under the GNU GPL.
SLOCCount comes with ABSOLUTELY NO WARRANTY, and you are welcome to
redistribute it under certain conditions as specified by the GNU GPL license;
see the documentation for details.
Please credit this data as "generated using David A. Wheeler's 'SLOCCount'."
moinudin
  • 134,091
  • 45
  • 190
  • 216
  • https://github.com/boyter/scc is an alternative that is actively maintained as SLOCCount was last updated in 2004. – 8ctopus Mar 02 '23 at 11:14
11

Unfortunately, SLOCCount is a bit long in the tooth and a pain in the neck for PHP projects, particularly ones that have a nested vendor directory you don't want counted. Also, it emits a warning for every PHP file that doesn't have a closing tag (which should be all of them if you aren't mixing HTML and PHP).

CLOC is a more modern alternative that does everything (edit: nearly everything) SLOCCount does, but also supports an --exclude-dir option and it doesn't suffer from the aforementioned close tag problem. It also emits a SQLite database that you can extract some pretty advanced metrics from.

Shabbyrobe
  • 12,298
  • 15
  • 60
  • 87
6

On windows from a command line:

findstr /R /N "^" *.php | find /C ":"

Thanks to this article.

To include sub directories, use \s :

findstr /s /R /N "^" *.php | find /C ":"
weston
  • 54,145
  • 21
  • 145
  • 203
4

The SLOCs of a PHP-project can counted with sloccount using something like this:

find . -not -wholename '*/libraries/*' -not -wholename '*/lib/*' -not -wholename '*/vendor/*' -type f xargs sloccount

Sample output for a sizey drupal project:

[...]
SLOC    Directory   SLOC-by-Language (Sorted)
44892   top_dir         pascal=33176,php=10293,sh=1423


Totals grouped by language (dominant language first):
pascal:       33176 (73.90%)
php:          10293 (22.93%)
sh:            1423 (3.17%)

Total Physical Source Lines of Code (SLOC)                = 44,892
Development Effort Estimate, Person-Years (Person-Months) = 10.86 (130.31)
 (Basic COCOMO model, Person-Months = 2.4 * (KSLOC**1.05))
Schedule Estimate, Years (Months)                         = 1.33 (15.91)
 (Basic COCOMO model, Months = 2.5 * (person-months**0.38))
Estimated Average Number of Developers (Effort/Schedule)  = 8.19
Total Estimated Cost to Develop                           = $ 1,466,963
 (average salary = $56,286/year, overhead = 2.40).
SLOCCount, Copyright (C) 2001-2004 David A. Wheeler
SLOCCount is Open Source Software/Free Software, licensed under the GNU GPL.
SLOCCount comes with ABSOLUTELY NO WARRANTY, and you are welcome to
redistribute it under certain conditions as specified by the GNU GPL license;
see the documentation for details.
Please credit this data as "generated using David A. Wheeler's 'SLOCCount'."
Bengt
  • 14,011
  • 7
  • 48
  • 66
  • Missing pipe: `find . -not -wholename '*/libraries/*' -not -wholename '*/lib/*' -not -wholename '*/vendor/*' -type f | xargs sloccount` – marcguyer Aug 06 '20 at 15:34
1
<?php
passthru('wc -l `find . -iname "*.php"`');
?>

Just run this on your current directory where all the php files are placed, it will display count lines on browser.

Shahbaz
  • 326
  • 5
  • 18