This is another thread from our forums which we are closing down soon.
This script will count the number of lines in all of your source files recursively. Just place it in any folder and point your browser to it and it will count all the lines including sub directories.
It might run out of memory if your application is huge and your PHP memory limit is low. For me, it counted 97,000 lines in our last project with no problems.
You also have an option to exclude file extensions and directories.
The other thing about this script is that it is a great little example of composite design pattern in action; every directory is an object that will count all the lines (in the files) in it and asks it’s sub directories to do the same, then the sub directories also repeat the same process.
<?php /** * Counts the lines of code in this folder and all sub folders * You may not sell this script or remove these header comments * @author Hamid Alipour, http://blog.code-head.com/ **/ define('SHOW_DETAILS', true); class Folder { var $name; var $path; var $folders; var $files; var $exclude_extensions; var $exclude_files; var $exclude_folders; function Folder($path) { $this -> path = $path; $this -> name = array_pop( array_filter( explode(DIRECTORY_SEPARATOR, $path) ) ); $this -> folders = array(); $this -> files = array(); $this -> exclude_extensions = array('gif', 'jpg', 'jpeg', 'png', 'tft', 'bmp', 'rest-of-the-file-extensions-to-exclude'); $this -> exclude_files = array('count_lines.php', 'rest-of-the-files-to-exclude'); $this -> exclude_folders = array('_private', '_vti_bin', '_vti_cnf', '_vti_log', '_vti_pvt', '_vti_txt', 'rest-of-the-folders-to-exclude'); } function count_lines() { if( defined('SHOW_DETAILS') ) echo "/Folder: {$this -> path}...\n"; $total_lines = 0; $this -> get_contents(); foreach($this -> files as $file) { if( in_array($file -> ext, $this -> exclude_extensions) || in_array($file -> name, $this -> exclude_files) ) { if( defined('SHOW_DETAILS') ) echo "#---Skipping File: {$file -> name};\n"; continue; } $total_lines += $file -> get_num_lines(); } foreach($this -> folders as $folder) { if( in_array($folder -> name, $this -> exclude_folders) ) { if( defined('SHOW_DETAILS') ) echo "#Skipping Folder: {$folder -> name};\n"; continue; } $total_lines += $folder -> count_lines(); } if( defined('SHOW_DETAILS') ) echo "\n Total lines in {$this -> name}: $total_lines;\n\n"; return $total_lines; } function get_contents() { $contents = $this -> _get_contents(); foreach($contents as $key => $value) { if( $value['type'] == 'Folder' ) { $this -> folders[] = new Folder($value['item']); } else { $this -> files[] = new File ($value['item']); } } } function _get_contents() { $folder = $this -> path; if( !is_dir($folder) ) { return array(); } $return_array = array(); $count = 0; if( $dh = opendir($folder) ) { while( ($file = readdir($dh)) !== false ) { if( $file == '.' || $file == '..' ) continue; $return_array[$count]['item'] = $folder .$file .(is_dir($folder .$file) ? DIRECTORY_SEPARATOR : ''); $return_array[$count]['type'] = is_dir($folder .$file) ? 'Folder' : 'File'; $count++; } closedir($dh); } return $return_array; } } // Class class File { var $name; var $path; var $ext; function File($path) { $this -> path = $path; $this -> name = basename($path); $this -> ext = array_pop( explode('.', $this -> name) ); } function get_num_lines() { $count_lines = count(file($this -> path)); if( defined('SHOW_DETAILS') ) echo "|---File: {$this -> name}, lines: $count_lines;\n"; return $count_lines; } } // Class $path_to_here = dirname(__FILE__) .DIRECTORY_SEPARATOR; $folder = new Folder($path_to_here); echo 'Total lines of code: ' .$folder -> count_lines() ."\n\n"; ?>
I'm the co-founder of
Hamid,
Nice script, but would be even better if it could separately count commented lines (and blank lines) vs. actual lines of PHP source.
-Dave
Comment
Hi Dave, thanks, and I agree, I might write a new one that works like that, I need the time first
Comment
Thanks for the script.
Really useful
Comment
Thanks alot, Great work…. Its working and working very fine… Thank you so much again
Comment
I have been using this for well over a year – it awesome for keeping a track on the general size of a project. I have added several other file extensions and directories to exclude such as JS library dirs etc etc.
It really begins to feel good when you can hit 100,000 lines of YOUR OWN CODE!!! ( dont make the same mistake i did at first – it was counting all of the library files too which i didn’t write, hence the modding!)
Thank you for releasing this to the world, most useful utility page. I have a simple file in the root of my server the contins this script and a drop down listing all of the project folders available ( built on the fly). I just select the relevant project and hit count!
Comment
PS: for a giggle, do a SLOC count on a Joomla or Magento installation – YIKES!!!
Comment
your counter is not accurate lol!
Comment
I know it’s not, it doesn’t claim to be either, it gives you a rough estimate and it’s a great demonstration of the composite design pattern, you can extend it and make more accurate though and if you do, I will post a link to yours
Comment
Great script, it was exactly what I was looking for – and it being in PHP was a huge plus.
Comment
Nice, but wouldn’t have been better to INCLUDE file extensions rather than to exclude them? If I just want to read the .php files, I shouldn’t have to exclude every other extension under the sun.
Comment
To use an INCLUDE file list rather than an exclude file list, just alter the ‘exclude_extensions’ to your include extensions list and then reverse the function of:
in_array($file -> ext, $this -> exclude_extensions)
!in_array($file -> ext, $this -> exclude_extensions)
Should work fine, it did here.
Comment
Working great, thanks!
Comment
194078 lines of code is no problem.
Thanks for the script
Comment