Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 16 | class DeprecatedFunctionsSniffTest extends BaseSniffTest |
||
| 17 | { |
||
| 18 | |||
| 19 | const TEST_FILE = 'sniff-examples/deprecated_functions.php'; |
||
| 20 | |||
| 21 | |||
| 22 | /** |
||
| 23 | * testDeprecatedFunction |
||
| 24 | * |
||
| 25 | * @dataProvider dataDeprecatedFunction |
||
| 26 | * |
||
| 27 | * @param string $functionName Name of the function. |
||
| 28 | * @param string $deprecatedIn The PHP version in which the function was deprecated. |
||
| 29 | * @param array $lines The line numbers in the test file which apply to this function. |
||
| 30 | * @param string $okVersion A PHP version in which the function was still valid. |
||
| 31 | * @param string $deprecatedVersion Optional PHP version to test deprecation message with - |
||
| 32 | * if different from the $deprecatedIn version. |
||
| 33 | * |
||
| 34 | * return void |
||
| 35 | */ |
||
| 36 | public function testDeprecatedFunction($functionName, $deprecatedIn, $lines, $okVersion, $deprecatedVersion = null) |
||
| 37 | { |
||
| 38 | $file = $this->sniffFile(self::TEST_FILE, $okVersion); |
||
| 39 | foreach($lines as $line) { |
||
| 40 | $this->assertNoViolation($file, $line); |
||
| 41 | } |
||
| 42 | |||
| 43 | if (isset($deprecatedVersion)){ |
||
| 44 | $file = $this->sniffFile(self::TEST_FILE, $deprecatedVersion); |
||
| 45 | } |
||
| 46 | else { |
||
| 47 | $file = $this->sniffFile(self::TEST_FILE, $deprecatedIn); |
||
| 48 | } |
||
| 49 | foreach($lines as $line) { |
||
| 50 | $this->assertWarning($file, $line, "The use of function {$functionName} is discouraged from PHP version {$deprecatedIn}"); |
||
| 51 | } |
||
| 52 | } |
||
| 53 | |||
| 54 | /** |
||
| 55 | * Data provider. |
||
| 56 | * |
||
| 57 | * @see testDeprecatedFunction() |
||
| 58 | * |
||
| 59 | * @return array |
||
| 60 | */ |
||
| 61 | public function dataDeprecatedFunction() |
||
| 62 | { |
||
| 63 | return array( |
||
| 64 | array('dl', '5.3', array(6), '5.2'), |
||
| 65 | array('ocifetchinto', '5.4', array(63), '5.3'), |
||
| 66 | array('ldap_sort', '7.0', array(97), '5.6'), |
||
| 67 | ); |
||
| 68 | } |
||
| 69 | |||
| 70 | |||
| 71 | /** |
||
| 72 | * testDeprecatedFunctionWithAlternative |
||
| 73 | * |
||
| 74 | * @dataProvider dataDeprecatedFunctionWithAlternative |
||
| 75 | * |
||
| 76 | * @param string $functionName Name of the function. |
||
| 77 | * @param string $deprecatedIn The PHP version in which the function was deprecated. |
||
| 78 | * @param string $alternative An alternative function. |
||
| 79 | * @param array $lines The line numbers in the test file which apply to this function. |
||
| 80 | * @param string $okVersion A PHP version in which the function was still valid. |
||
| 81 | * @param string $deprecatedVersion Optional PHP version to test deprecation message with - |
||
| 82 | * if different from the $deprecatedIn version. |
||
| 83 | * |
||
| 84 | * return void |
||
| 85 | */ |
||
| 86 | public function testDeprecatedFunctionWithAlternative($functionName, $deprecatedIn, $alternative, $lines, $okVersion, $deprecatedVersion = null) |
||
| 87 | { |
||
| 88 | $file = $this->sniffFile(self::TEST_FILE, $okVersion); |
||
| 89 | foreach($lines as $line) { |
||
| 90 | $this->assertNoViolation($file, $line); |
||
| 91 | } |
||
| 92 | |||
| 93 | if (isset($deprecatedVersion)){ |
||
| 94 | $file = $this->sniffFile(self::TEST_FILE, $deprecatedVersion); |
||
| 95 | } |
||
| 96 | else { |
||
| 97 | $file = $this->sniffFile(self::TEST_FILE, $deprecatedIn); |
||
| 98 | } |
||
| 99 | foreach($lines as $line) { |
||
| 100 | $this->assertWarning($file, $line, "The use of function {$functionName} is discouraged from PHP version {$deprecatedIn}; use {$alternative} instead"); |
||
| 101 | } |
||
| 102 | } |
||
| 103 | |||
| 104 | /** |
||
| 105 | * Data provider. |
||
| 106 | * |
||
| 107 | * @see testDeprecatedFunctionWithAlternative() |
||
| 108 | * |
||
| 109 | * @return array |
||
| 110 | */ |
||
| 111 | public function dataDeprecatedFunctionWithAlternative() |
||
| 112 | { |
||
| 113 | return array( |
||
| 114 | array('ocibindbyname', '5.4', 'oci_bind_by_name', array(41), '5.3'), |
||
| 115 | array('ocicancel', '5.4', 'oci_cancel', array(42), '5.3'), |
||
| 116 | array('ocicloselob', '5.4', 'OCI-Lob::close', array(43), '5.3'), |
||
| 117 | array('ocicollappend', '5.4', 'OCI-Collection::append', array(44), '5.3'), |
||
| 118 | array('ocicollassign', '5.4', 'OCI-Collection::assign', array(45), '5.3'), |
||
| 119 | array('ocicollassignelem', '5.4', 'OCI-Collection::assignElem', array(46), '5.3'), |
||
| 120 | array('ocicollgetelem', '5.4', 'OCI-Collection::getElem', array(47), '5.3'), |
||
| 121 | array('ocicollmax', '5.4', 'OCI-Collection::max', array(48), '5.3'), |
||
| 122 | array('ocicollsize', '5.4', 'OCI-Collection::size', array(49), '5.3'), |
||
| 123 | array('ocicolltrim', '5.4', 'OCI-Collection::trim', array(50), '5.3'), |
||
| 124 | array('ocicolumnisnull', '5.4', 'oci_field_is_null', array(51), '5.3'), |
||
| 125 | array('ocicolumnname', '5.4', 'oci_field_name', array(52), '5.3'), |
||
| 126 | array('ocicolumnprecision', '5.4', 'oci_field_precision', array(53), '5.3'), |
||
| 127 | array('ocicolumnscale', '5.4', 'oci_field_scale', array(54), '5.3'), |
||
| 128 | array('ocicolumnsize', '5.4', 'oci_field_size', array(55), '5.3'), |
||
| 129 | array('ocicolumntype', '5.4', 'oci_field_type', array(56), '5.3'), |
||
| 130 | array('ocicolumntyperaw', '5.4', 'oci_field_type_raw', array(57), '5.3'), |
||
| 131 | array('ocicommit', '5.4', 'oci_commit', array(58), '5.3'), |
||
| 132 | array('ocidefinebyname', '5.4', 'oci_define_by_name', array(59), '5.3'), |
||
| 133 | array('ocierror', '5.4', 'oci_error', array(60), '5.3'), |
||
| 134 | array('ociexecute', '5.4', 'oci_execute', array(61), '5.3'), |
||
| 135 | array('ocifetch', '5.4', 'oci_fetch', array(62), '5.3'), |
||
| 136 | array('ocifetchstatement', '5.4', 'oci_fetch_all', array(64), '5.3'), |
||
| 137 | array('ocifreecollection', '5.4', 'OCI-Collection::free', array(65), '5.3'), |
||
| 138 | array('ocifreecursor', '5.4', 'oci_free_statement', array(66), '5.3'), |
||
| 139 | array('ocifreedesc', '5.4', 'OCI-Lob::free', array(67), '5.3'), |
||
| 140 | array('ocifreestatement', '5.4', 'oci_free_statement', array(68), '5.3'), |
||
| 141 | array('ociinternaldebug', '5.4', 'oci_internal_debug', array(69), '5.3'), |
||
| 142 | array('ociloadlob', '5.4', 'OCI-Lob::load', array(70), '5.3'), |
||
| 143 | array('ocilogoff', '5.4', 'oci_close', array(71), '5.3'), |
||
| 144 | array('ocilogon', '5.4', 'oci_connect', array(72), '5.3'), |
||
| 145 | array('ocinewcollection', '5.4', 'oci_new_collection', array(73), '5.3'), |
||
| 146 | array('ocinewcursor', '5.4', 'oci_new_cursor', array(74), '5.3'), |
||
| 147 | array('ocinewdescriptor', '5.4', 'oci_new_descriptor', array(75), '5.3'), |
||
| 148 | array('ocinlogon', '5.4', 'oci_new_connect', array(76), '5.3'), |
||
| 149 | array('ocinumcols', '5.4', 'oci_num_fields', array(77), '5.3'), |
||
| 150 | array('ociparse', '5.4', 'oci_parse', array(78), '5.3'), |
||
| 151 | array('ociplogon', '5.4', 'oci_pconnect', array(79), '5.3'), |
||
| 152 | array('ociresult', '5.4', 'oci_result', array(80), '5.3'), |
||
| 153 | array('ocirollback', '5.4', 'oci_rollback', array(81), '5.3'), |
||
| 154 | array('ocirowcount', '5.4', 'oci_num_rows', array(82), '5.3'), |
||
| 155 | array('ocisavelob', '5.4', 'OCI-Lob::save', array(83), '5.3'), |
||
| 156 | array('ocisavelobfile', '5.4', 'OCI-Lob::import', array(84), '5.3'), |
||
| 157 | array('ociserverversion', '5.4', 'oci_server_version', array(85), '5.3'), |
||
| 158 | array('ocisetprefetch', '5.4', 'oci_set_prefetch', array(86), '5.3'), |
||
| 159 | array('ocistatementtype', '5.4', 'oci_statement_type', array(87), '5.3'), |
||
| 160 | array('ociwritelobtofile', '5.4', 'OCI-Lob::export', array(88), '5.3'), |
||
| 161 | array('ociwritetemporarylob', '5.4', 'OCI-Lob::writeTemporary', array(89), '5.3'), |
||
| 162 | |||
| 163 | ); |
||
| 164 | } |
||
| 165 | |||
| 166 | |||
| 167 | /** |
||
| 168 | * testForbiddenFunction |
||
| 169 | * |
||
| 170 | * @dataProvider dataForbiddenFunction |
||
| 171 | * |
||
| 172 | * @param string $functionName Name of the function. |
||
| 173 | * @param string $forbiddenIn The PHP version in which the function was forbidden. |
||
| 174 | * @param array $lines The line numbers in the test file which apply to this function. |
||
| 175 | * @param string $okVersion A PHP version in which the function was still valid. |
||
| 176 | * @param string $forbiddenVersion Optional PHP version to test forbidden message with - |
||
| 177 | * if different from the $forbiddenIn version. |
||
| 178 | * |
||
| 179 | * return void |
||
| 180 | */ |
||
| 181 | public function testForbiddenFunction($functionName, $forbiddenIn, $lines, $okVersion, $forbiddenVersion = null) |
||
| 182 | { |
||
| 183 | $file = $this->sniffFile(self::TEST_FILE, $okVersion); |
||
| 184 | foreach($lines as $line) { |
||
| 185 | $this->assertNoViolation($file, $line); |
||
| 186 | } |
||
| 187 | |||
| 188 | if (isset($forbiddenVersion)){ |
||
| 189 | $file = $this->sniffFile(self::TEST_FILE, $forbiddenVersion); |
||
| 190 | } |
||
| 191 | else { |
||
| 192 | $file = $this->sniffFile(self::TEST_FILE, $forbiddenIn); |
||
| 193 | } |
||
| 194 | foreach($lines as $line) { |
||
| 195 | $this->assertError($file, $line, "The use of function {$functionName} is forbidden from PHP version {$forbiddenIn}"); |
||
| 196 | } |
||
| 197 | } |
||
| 198 | |||
| 199 | /** |
||
| 200 | * Data provider. |
||
| 201 | * |
||
| 202 | * @see testForbiddenFunction() |
||
| 203 | * |
||
| 204 | * @return array |
||
| 205 | */ |
||
| 206 | public function dataForbiddenFunction() |
||
| 207 | { |
||
| 208 | return array( |
||
| 209 | array('php_logo_guid', '5.5', array(32), '5.4'), |
||
| 210 | array('php_egg_logo_guid', '5.5', array(33), '5.4'), |
||
| 211 | array('php_real_logo_guid', '5.5', array(34), '5.4'), |
||
| 212 | array('zend_logo_guid', '5.5', array(35), '5.4'), |
||
| 213 | array('imagepsbbox', '7.0', array(90), '5.6'), |
||
| 214 | array('imagepsencodefont', '7.0', array(91), '5.6'), |
||
| 215 | array('imagepsextendfont', '7.0', array(92), '5.6'), |
||
| 216 | array('imagepsfreefont', '7.0', array(93), '5.6'), |
||
| 217 | array('imagepsloadfont', '7.0', array(94), '5.6'), |
||
| 218 | array('imagepsslantfont', '7.0', array(95), '5.6'), |
||
| 219 | array('imagepstext', '7.0', array(96), '5.6'), |
||
| 220 | array('php_check_syntax', '5.0.5', array(98), '5.0', '5.1'), |
||
| 221 | array('mysqli_get_cache_stats', '5.4', array(99), '5.3'), |
||
| 222 | |||
| 223 | ); |
||
| 224 | } |
||
| 225 | |||
| 226 | |||
| 227 | /** |
||
| 228 | * testDeprecatedForbiddenFunction |
||
| 229 | * |
||
| 230 | * @dataProvider dataDeprecatedForbiddenFunction |
||
| 231 | * |
||
| 232 | * @param string $functionName Name of the function. |
||
| 233 | * @param string $deprecatedIn The PHP version in which the function was deprecated. |
||
| 234 | * @param string $forbiddenIn The PHP version in which the function was forbidden. |
||
| 235 | * @param array $lines The line numbers in the test file which apply to this function. |
||
| 236 | * @param string $okVersion A PHP version in which the function was still valid. |
||
| 237 | * @param string $deprecatedVersion Optional PHP version to test deprecation message with - |
||
| 238 | * if different from the $deprecatedIn version. |
||
| 239 | * @param string $forbiddenVersion Optional PHP version to test forbidden message with - |
||
| 240 | * if different from the $forbiddenIn version. |
||
| 241 | * |
||
| 242 | * return void |
||
| 243 | */ |
||
| 244 | public function testDeprecatedForbiddenFunction($functionName, $deprecatedIn, $forbiddenIn, $lines, $okVersion, $deprecatedVersion = null, $forbiddenVersion = null) |
||
| 245 | { |
||
| 246 | $file = $this->sniffFile(self::TEST_FILE, $okVersion); |
||
| 247 | foreach($lines as $line) { |
||
| 248 | $this->assertNoViolation($file, $line); |
||
| 249 | } |
||
| 250 | |||
| 251 | if (isset($deprecatedVersion)){ |
||
| 252 | $file = $this->sniffFile(self::TEST_FILE, $deprecatedVersion); |
||
| 253 | } |
||
| 254 | else { |
||
| 255 | $file = $this->sniffFile(self::TEST_FILE, $deprecatedIn); |
||
| 256 | } |
||
| 257 | foreach($lines as $line) { |
||
| 258 | $this->assertWarning($file, $line, "The use of function {$functionName} is discouraged from PHP version {$deprecatedIn}"); |
||
| 259 | } |
||
| 260 | |||
| 261 | if (isset($forbiddenVersion)){ |
||
| 262 | $file = $this->sniffFile(self::TEST_FILE, $forbiddenVersion); |
||
| 263 | } |
||
| 264 | else { |
||
| 265 | $file = $this->sniffFile(self::TEST_FILE, $forbiddenIn); |
||
| 266 | } |
||
| 267 | foreach($lines as $line) { |
||
| 268 | $this->assertError($file, $line, "The use of function {$functionName} is discouraged from PHP version {$deprecatedIn} and forbidden from PHP version {$forbiddenIn}"); |
||
| 269 | } |
||
| 270 | } |
||
| 271 | |||
| 272 | /** |
||
| 273 | * Data provider. |
||
| 274 | * |
||
| 275 | * @see testDeprecatedForbiddenFunction() |
||
| 276 | * |
||
| 277 | * @return array |
||
| 278 | */ |
||
| 279 | public function dataDeprecatedForbiddenFunction() |
||
| 280 | { |
||
| 281 | return array( |
||
| 282 | array('define_syslog_variables', '5.3', '5.4', array(5), '5.2'), |
||
| 283 | array('import_request_variables', '5.3', '5.4', array(11), '5.2'), |
||
| 284 | array('mysql_list_dbs', '5.4', '7.0', array(15), '5.3'), |
||
| 285 | array('magic_quotes_runtime', '5.3', '7.0', array(23), '5.2'), |
||
| 286 | array('set_magic_quotes_runtime', '5.3', '7.0', array(27), '5.2'), |
||
| 287 | array('sql_regcase', '5.3', '7.0', array(31), '5.2'), |
||
| 288 | array('mcrypt_ecb', '5.5', '7.0', array(37), '5.4'), |
||
| 289 | array('mcrypt_cbc', '5.5', '7.0', array(38), '5.4'), |
||
| 290 | array('mcrypt_cfb', '5.5', '7.0', array(39), '5.4'), |
||
| 291 | array('mcrypt_ofb', '5.5', '7.0', array(40), '5.4'), |
||
| 292 | |||
| 293 | ); |
||
| 294 | } |
||
| 295 | |||
| 296 | |||
| 297 | /** |
||
| 298 | * testDeprecatedForbiddenFunctionWithAlternative |
||
| 299 | * |
||
| 300 | * @dataProvider dataDeprecatedForbiddenFunctionWithAlternative |
||
| 301 | * |
||
| 302 | * @param string $functionName Name of the function. |
||
| 303 | * @param string $deprecatedIn The PHP version in which the function was deprecated. |
||
| 304 | * @param string $forbiddenIn The PHP version in which the function was forbidden. |
||
| 305 | * @param string $alternative An alternative function. |
||
| 306 | * @param array $lines The line numbers in the test file which apply to this function. |
||
| 307 | * @param string $okVersion A PHP version in which the function was still valid. |
||
| 308 | * @param string $deprecatedVersion Optional PHP version to test deprecation message with - |
||
| 309 | * if different from the $deprecatedIn version. |
||
| 310 | * @param string $forbiddenVersion Optional PHP version to test forbidden message with - |
||
| 311 | * if different from the $forbiddenIn version. |
||
| 312 | * |
||
| 313 | * return void |
||
| 314 | */ |
||
| 315 | public function testDeprecatedForbiddenFunctionWithAlternative($functionName, $deprecatedIn, $forbiddenIn, $alternative, $lines, $okVersion, $deprecatedVersion = null, $forbiddenVersion = null) |
||
| 316 | { |
||
| 317 | $file = $this->sniffFile(self::TEST_FILE, $okVersion); |
||
| 318 | foreach($lines as $line) { |
||
| 319 | $this->assertNoViolation($file, $line); |
||
| 320 | } |
||
| 321 | |||
| 322 | if (isset($deprecatedVersion)){ |
||
| 323 | $file = $this->sniffFile(self::TEST_FILE, $deprecatedVersion); |
||
| 324 | } |
||
| 325 | else { |
||
| 326 | $file = $this->sniffFile(self::TEST_FILE, $deprecatedIn); |
||
| 327 | } |
||
| 328 | foreach($lines as $line) { |
||
| 329 | $this->assertWarning($file, $line, "The use of function {$functionName} is discouraged from PHP version {$deprecatedIn}; use {$alternative} instead"); |
||
| 330 | } |
||
| 331 | |||
| 332 | if (isset($forbiddenVersion)){ |
||
| 333 | $file = $this->sniffFile(self::TEST_FILE, $forbiddenVersion); |
||
| 334 | } |
||
| 335 | else { |
||
| 336 | $file = $this->sniffFile(self::TEST_FILE, $forbiddenIn); |
||
| 337 | } |
||
| 338 | foreach($lines as $line) { |
||
| 339 | $this->assertError($file, $line, "The use of function {$functionName} is discouraged from PHP version {$deprecatedIn} and forbidden from PHP version {$forbiddenIn}; use {$alternative} instead"); |
||
| 340 | } |
||
| 341 | } |
||
| 342 | |||
| 343 | /** |
||
| 344 | * Data provider. |
||
| 345 | * |
||
| 346 | * @see testDeprecatedForbiddenFunctionWithAlternative() |
||
| 347 | * |
||
| 348 | * @return array |
||
| 349 | */ |
||
| 350 | public function dataDeprecatedForbiddenFunctionWithAlternative() |
||
| 351 | { |
||
| 352 | return array( |
||
| 353 | array('call_user_method', '5.3', '7.0', 'call_user_func', array(3), '5.2'), |
||
| 354 | array('call_user_method_array', '5.3', '7.0', 'call_user_func_array', array(4), '5.2'), |
||
| 355 | array('ereg', '5.3', '7.0', 'preg_match', array(7), '5.2'), |
||
| 356 | array('ereg_replace', '5.3', '7.0', 'preg_replace', array(8), '5.2'), |
||
| 357 | array('eregi', '5.3', '7.0', 'preg_match', array(9), '5.2'), |
||
| 358 | array('eregi_replace', '5.3', '7.0', 'preg_replace', array(10), '5.2'), |
||
| 359 | array('mcrypt_generic_end', '5.4', '7.0', 'mcrypt_generic_deinit', array(12), '5.3'), |
||
| 360 | array('mysql_db_query', '5.3', '7.0', 'mysqli_select_db and mysqli_query', array(13), '5.2'), |
||
| 361 | array('mysql_escape_string', '5.3', '7.0', 'mysqli_real_escape_string', array(14), '5.2'), |
||
| 362 | array('mysqli_bind_param', '5.3', '5.4', 'mysqli_stmt_bind_param', array(16), '5.2'), |
||
| 363 | array('mysqli_bind_result', '5.3', '5.4', 'mysqli_stmt_bind_result', array(17), '5.2'), |
||
| 364 | array('mysqli_client_encoding', '5.3', '5.4', 'mysqli_character_set_name', array(18), '5.2'), |
||
| 365 | array('mysqli_fetch', '5.3', '5.4', 'mysqli_stmt_fetch', array(19), '5.2'), |
||
| 366 | array('mysqli_param_count', '5.3', '5.4', 'mysqli_stmt_param_count', array(20), '5.2'), |
||
| 367 | array('mysqli_get_metadata', '5.3', '5.4', 'mysqli_stmt_result_metadata', array(21), '5.2'), |
||
| 368 | array('mysqli_send_long_data', '5.3', '5.4', 'mysqli_stmt_send_long_data', array(22), '5.2'), |
||
| 369 | array('session_register', '5.3', '5.4', '$_SESSION', array(24), '5.2'), |
||
| 370 | array('session_unregister', '5.3', '5.4', '$_SESSION', array(25), '5.2'), |
||
| 371 | array('session_is_registered', '5.3', '5.4', '$_SESSION', array(26), '5.2'), |
||
| 372 | array('set_socket_blocking', '5.3', '7.0', 'stream_set_blocking', array(28), '5.2'), |
||
| 373 | array('split', '5.3', '7.0', 'preg_split', array(29), '5.2'), |
||
| 374 | array('spliti', '5.3', '7.0', 'preg_split', array(30), '5.2'), |
||
| 375 | array('datefmt_set_timezone_id', '5.5', '7.0', 'datefmt_set_timezone', array(36), '5.4'), |
||
| 376 | |||
| 377 | ); |
||
| 378 | } |
||
| 379 | |||
| 380 | } |
||
| 381 |