Detecting Code Smells In Php

Here's some code to detect a few code smells in a PHP file. It can be easily adapted to detect code smells in C, C++, Java, etc. code.

 $MAX_INDENTATION_LEVEL = 3;
 $MAX_FUNCTION_LINE_COUNT = 20;
 $MAX_NUM_PARAMETERS = 4;

function print_warning( $filename, $line, $line_number, $warning ) { print( "<code>$filename</code>: <strong>$warning</strong><br />\n" . "&nbsp; &nbsp; Line $line_number: <code>$line</code><br />\n" ); }

function test_line_for_indentation( $line, $max_indentation_level ) { $char_posit = 0; while( substr( $line, $char_posit, 1 ) == "\t" ) $char_posit++; if( $char_posit > $max_indentation_level ) return false; return true; }

function test_line_for_function_definition( $line, $max_num_parameters ) { if( substr( $line, 0, 9 ) == "function " ) { if( substr_count( $line, ',' ) >= $max_num_parameters ) return false; } return true; }

function test_file_for_smells( $filename ) { global $MAX_FUNCTION_LINE_COUNT, $MAX_INDENTATION_LEVEL; $function_line_count = 0; $found_continued_line = 0; $line_number = 0; $fp = fopen( $filename, "r" ); if( ! $fp ) return; while( ! feof( $fp ) ) { $line = chop( fgets( $fp, 4096 ) ); $line_number++; while( substr( $line, 0, 9 ) == "function " && substr( $line, strlen($line) - 1, 1 ) != ')' ) { $line = $line . chop( fgets( $fp, 4096 ) ) $found_continued_line++; } if( substr( $line, 0, 9 ) == "function " ) { $function_line_count = 1; $function_name = substr( $line, 9, strpos($line, '(') - 9 ); } if( $function_line_count > 0 ) { if( $line == "\t}" ) { $function_line_count = $function_line_count - 3; if( $function_line_count > $MAX_FUNCTION_LINE_COUNT ) print_warning( $filename, $line, $line_number, "$function_name() too long ($function_line_count lines)" ); $function_line_count = 0; } else $function_line_count++; $result = test_line_for_indentation( $line, $MAX_INDENTATION_LEVEL ); if( ! $result ) print_warning( $filename, $line, $line_number, "Too much nesting." ); $result = test_line_for_function_definition( $line, $MAX_NUM_PARAMETERS ); if( ! $result ) print_warning( $filename, $line, $line_number, "Too many parameters." ); if( $found_continued_line > 0 ) { $line_number += $found_continued_line; $found_continued_line = 0; } } } }

Please feel free to ReFactor this code. test_file_for_smells() would fail its own tests! -- BrentNewhall

Doesn't this assume tabs are always used for indentation?

This code probably needs to be refactored to use the tokenizer extension. I have a "CodeSmeller?" object written in PHP5, I will post it soon. -- JonathanArkell
CategoryPhp

EditText of this page (last edited October 23, 2003) or FindPage with title or text search