Exakat PHP Index of coding

Not using @ is the poster child of good practices. It’s also looked upon, as an impossible goal. Did you know that the @ operator is only merely used by 50% of PHP applications ? Same for parenthesis with include (and co) : don’t use them, like 50% of the developpers. This is how the Exakat PHP Index of coding was born.

Every month, Exakat runs thousands of analysis on half a billion lines of PHP code. This is primarily for testing purpose, a kind of torture test that checks the engine runs on any kind of code. And it is very useful to ensure all situations are correctly handled.

We also extracted the following stats out of 1700+ projects, analysis by analysis. This way, any issue may be ranked from ‘wide spread’ to ‘very unusual’. In fact, ‘wide spread’ may also be understood as : ‘almost a feature’. May be we can suggest a few of them to wiki.php.net.

Each analysis is ranked below, with its frequency of appearance in code, its progression. If you want to test your own code, just install exakat and run an audit.

is for new analysis, and is for old one.

May 18 Apr 18 Prog. Name Rating Change
1 1 Uses Default Values   94.40 % -0.90 %
2 2 Used Once Variables (In Scope)   91.10 % -14.80 %
3 3 Unused Methods   90.73 % 10.40 %
4 7 Method Could Be Private Method   90.42 % 38.60 %
5 4 Should Use Local Class   90.10 % 10.50 %
6 6 Could Be Protected Method   89.27 % 19.60 %
7 5 Overwriting Variable   87.44 % -1.60 %
8 10 PHP Keywords As Names   82.05 % 2.40 %
9 11 Unresolved Classes   79.85 % 14.50 %
10 13 Undefined Classes   78.38 % 22.40 %
11 32 Property Used In One Method Only   78.23 % 137.90 %
12 16 Unused Classes   77.76 % 25.50 %
13 12 Nested Ifthen   76.60 % 2.30 %
14 14 Unitialized Properties   76.45 % 6.00 %
15 17 Relay Function   75.45 % 4.10 %
16 18 Not Definitions Only   75.03 % 0.50 %
17 29 Locally Unused Property   74.46 % 90.30 %
18 21 Used Once Variables   73.46 % 9.10 %
19 20 Should Make Ternary   73.46 % -2.50 %
20 19 Useless Parenthesis   72.42 % -14.00 %
21 311 Mark Callable   71.69 % 716.40 %
22 8 Unused Arguments   71.63 % -147.00 %
23 35 No Boolean As Default   71.37 % 82.00 %
24 N/A Use Named Boolean In Argument Definition   71.21 % 712.10 %
25 22 Buried Assignation   70.74 % -4.20 %
26 108 Strict Comparison With Booleans   70.59 % 329.60 %
27 24 Preprocessable   69.38 % -4.50 %
28 26 Avoid Optional Properties   68.81 % 0.80 %
29 9 Overwritten Literals   68.49 % -154.70 %
30 25 Property Variable Confusion   68.39 % -8.00 %
31 15 Long Arguments   68.39 % -74.00 %
32 23 Use Positive Condition   68.18 % -17.60 %
33 27 Pre-increment   66.24 % 5.80 %
34 28 Property Could Be Private Property   65.72 % 1.80 %
35 46 Constant Class   65.20 % 53.30 %
36 30 No Need For Else   64.10 % -8.60 %
37 34 Used Once Property   63.73 % 5.00 %
38 31 Could Make A Function   63.57 % -9.30 %
39 41 Use Class Operator   62.89 % 13.40 %
40 37 Bail Out Early   62.06 % -7.60 %
41 36 Switch To Switch   61.90 % -10.90 %
42 39 Iffectations   61.64 % -6.00 %
43 48 Could Use Alias   61.27 % 21.00 %
44 43 Never Used Properties   61.01 % 0.40 %
45 40 Assigned Twice   60.96 % -6.40 %
46 38 No Class As Typehint   60.70 % -18.90 %
47 42 No Class In Global   60.59 % -4.90 %
48 52 Could Be Private Class Constant   58.34 % 9.60 %
49 53 Could Be Protected Class Constant   58.34 % 9.60 %
50 N/A Local Globals   58.29 % 582.90 %
51 49 Check All Types   57.61 % -4.00 %
52 92 Undefined Interfaces   57.50 % 157.60 %
53 56 Undefined Constants   57.35 % 3.20 %
54 50 Altering Foreach Without Reference   57.19 % -5.40 %
55 51 Else If Versus Elseif   57.19 % -4.80 %
56 45 Drop Else After Return   56.98 % -30.00 %
57 55 Dont Change The Blind Var   56.82 % -3.80 %
58 44 Empty Function   56.56 % -34.80 %
59 58 include_once() Usage   55.67 % 2.60 %
60 59 No Parenthesis For Language Construct   55.52 % 4.00 %
61 183 Class Name Case Difference   54.78 % 357.30 %
62 60 Method Used Below   53.11 % -11.40 %
63 63 Exit() Usage   53.00 % 7.20 %
64 61 @ Operator   52.95 % -0.30 %
65 65 Echo With Concat   52.06 % 5.90 %
66 67 Could Be Protected Property   51.75 % 6.30 %
67 64 Switch Without Default   51.59 % -5.20 %
68 68 Static Loop   51.22 % 5.00 %
69 70 Empty Classes   51.07 % 9.30 %
70 66 Uncaught Exceptions   51.02 % -3.90 %
71 62 Undefined Functions   50.75 % -18.80 %
72 135 Undefined Parent   50.60 % 208.40 %
73 N/A Identical Consecutive Expression   50.44 % 504.40 %
74 N/A Property Could Be Local   50.44 % 504.40 %
75 57 Unresolved Use   50.23 % -53.50 %
76 71 Common Alternatives   49.39 % 1.80 %
77 81 Logical To in_array   49.29 % 28.00 %
78 74 Function Subscripting, Old Style   49.13 % 3.80 %
79 72 Use Instanceof   48.87 % -1.10 %
80 75 Several Instructions On The Same Line   48.77 % 7.70 %
81 78 Empty Instructions   48.61 % 11.30 %
82 N/A Missing Include   48.40 % 484.00 %
83 76 Use === null   47.72 % -2.20 %
84 96 Use random_int()   47.61 % 70.80 %
85 121 No Public Access   47.20 % 134.50 %
86 N/A Constants   46.78 % 467.80 %
87 79 Could Typehint   46.72 % -4.70 %
88 73 Mixed Concat And Interpolation   46.57 % -23.50 %
89 82 Strpos()-like Comparison   46.10 % -2.80 %
90 85 Mismatched Ternary Alternatives   45.94 % 16.50 %
91 N/A Useless Referenced Argument   45.68 % 456.80 %
92 84 Could Use Short Assignation   45.31 % 6.70 %
93 83 String May Hold A Variable   44.79 % -4.30 %
94 87 Undefined Properties   44.42 % 9.40 %
95 101 No Substr() One   44.16 % 42.70 %
96 86 Use const   44.11 % 4.00 %
97 107 Could Be Typehinted Callable   44.00 % 56.10 %
98 89 Useless Interfaces   43.58 % 9.70 %
99 N/A Ambiguous Static   43.17 % 431.70 %
100 91 Should Typecast   41.96 % -1.90 %
101 94 Could Be Class Constant   41.86 % 8.10 %
102 69 Aliases Usage   41.81 % -83.90 %
103 97 Empty Blocks   41.75 % 13.40 %
104 100 Unused Use   41.60 % 16.50 %
105 77 No array_merge() In Loops   41.33 % -63.20 %
106 98 Undefined Class Constants   41.23 % 8.80 %
107 95 Return True False   40.65 % -1.10 %
108 104 Double Assignation   40.03 % 11.20 %
109 128 Class Should Be Final By Ocramius   39.82 % 76.90 %
110 122 Repeated print()   39.71 % 61.90 %
111 103 Double Instructions   39.40 % 0.30 %
112 N/A Parent First   39.40 % 394.00 %
113 106 Unreachable Code   38.51 % 0.10 %
114 93 Unused Functions   37.36 % -37.50 %
115 109 Timestamp Difference   36.89 % 5.90 %
116 114 Useless Instructions   36.57 % 13.10 %
117 105 Forgotten Visibility   36.42 % -22.50 %
118 166 Unused Private Properties   36.36 % 128.60 %
119 112 Global Usage   36.05 % 5.00 %
120 113 Useless Check   36.00 % 6.30 %
121 111 For Using Functioncall   35.63 % 0.80 %
122 110 Logical Should Use Symbolic Operators   35.32 % -4.60 %
123 117 Modernize Empty With Expression   34.79 % 2.30 %
124 115 If With Same Conditions   34.74 % -1.10 %
125 80 Repeated Regex   34.74 % -119.30 %
126 116 Could Use self   34.58 % -1.00 %
127 248 Same Conditions In Condition   34.37 % 274.30 %
128 119 Could Use __DIR__   34.22 % 0.60 %
129 138 Cast To Boolean   34.22 % 49.80 %
130 126 Unused Constants   34.17 % 8.80 %
131 118 Unresolved Instanceof   34.11 % -1.60 %
132 N/A Unused Inherited Variable In Closure   34.11 % 341.10 %
133 271 Could Be Else   33.90 % 307.20 %
134 132 Should Use Coalesce   33.75 % 30.10 %
135 125 No Return Used   33.59 % 2.40 %
136 123 Wrong Parameter Type   33.22 % -3.00 %
137 124 Htmlentities Calls   32.96 % -4.50 %
138 N/A Useless Catch   32.39 % 323.90 %
139 129 var_dump()… Usage   32.12 % 1.00 %
140 127 Don’t Change Incomings   32.02 % -4.00 %
141 120 Unused Static Methods   31.08 % -30.20 %
142 130 Should Make Alias   31.08 % -3.60 %
143 136 Empty Try Catch   30.50 % 8.00 %
144 133 Unchecked Resources   30.29 % -1.60 %
145 255 Multiple Type Variable   30.14 % 244.10 %
146 146 Unconditional Break In Loop   29.82 % 27.80 %
147 137 No Choice   29.72 % 1.40 %
148 141 Unthrown Exception   29.40 % 11.50 %
149 N/A Never Used Parameter   29.30 % 293.00 %
150 140 Only Variable Passed By Reference   29.09 % 4.30 %
151 142 Multiple Alias Definitions   28.88 % 7.40 %
152 143 Assign Default To Properties   28.25 % 2.30 %
153 144 Implicit Global   28.10 % 4.80 %
154 54 Wrong Number Of Arguments   27.42 % -297.80 %
155 278 Printf Number Of Arguments   27.36 % 254.50 %
156 145 Make Global A Property   27.31 % 1.60 %
157 33 Randomly Sorted Arrays   27.15 % -372.90 %
158 150 Avoid Using stdClass   26.68 % 5.10 %
159 147 Eval() Usage   26.63 % -0.60 %
160 151 Written Only Variables   26.32 % 3.80 %
161 148 Multiple Constant Definition   26.21 % -1.30 %
162 154 Wrong Optional Parameter   26.11 % 6.40 %
163 155 No Hardcoded Hash   26.11 % 6.40 %
164 153 No Direct Call To Magic Method   25.95 % 3.00 %
165 233 Hardcoded Passwords   25.90 % 158.90 %
166 N/A Don’t Send This In Constructor   25.74 % 257.40 %
167 156 list() May Omit Variables   25.43 % 0.70 %
168 139 Forgotten Interface   25.32 % -38.00 %
169 152 Sequences In For   25.27 % -3.80 %
170 88 Static Methods Called From Object   25.11 % -176.20 %
171 161 Objects Don’t Need References   24.90 % 5.90 %
172 168 Unused Returned Value   24.59 % 14.90 %
173 162 One Variable String   24.48 % 4.00 %
174 149 Print And Die   24.48 % -16.90 %
175 164 Implied If   24.33 % 5.40 %
176 N/A nativeCallCounts   24.17 % 241.70 %
177 157 Useless Constructor   24.07 % -7.70 %
178 159 Useless Abstract Class   24.07 % -7.10 %
179 N/A Invalid Regex   24.07 % 240.70 %
180 171 Empty Interfaces   23.91 % 19.70 %
181 163 Dangling Array References   23.91 % 0.60 %
182 165 Use Constant As Arguments   23.91 % 3.50 %
183 167 Should Chain Exception   23.70 % 4.30 %
184 172 Incompilable Files   23.02 % 12.00 %
185 169 No Direct Usage   22.97 % 6.80 %
186 160 Mismatched Default Arguments   22.91 % -14.60 %
187 170 No Hardcoded Path   22.55 % 4.90 %
188 173 Useless Global   22.18 % 9.30 %
189 174 Useless Return   21.50 % 8.90 %
190 175 Undefined static:: Or self::   21.45 % 13.60 %
191 176 Unset In Foreach   21.14 % 11.70 %
192 131 Adding Zero   20.25 % -110.70 %
193 186 Useless Casting   20.25 % 13.80 %
194 181 Multiple Index Definition   20.19 % 8.00 %
195 179 Useless Switch   20.14 % 6.90 %
196 180 Forgotten Thrown   19.98 % 5.30 %
197 177 Var Keyword   19.62 % 0.00 %
198 199 Unused Global   19.57 % 36.50 %
199 184 Should Use Prepared Statement   19.51 % 5.20 %
200 178 Could Be Static   18.99 % -6.30 %
201 N/A Mistaken Concatenation   18.89 % 188.90 %
202 189 Alternative Syntax Consistence   18.83 % 8.80 %
203 187 No Isset With Empty   18.78 % 0.80 %
204 185 Too Many Local Variables   18.68 % -3.10 %
205 196 Redefined Default   18.31 % 15.80 %
206 190 Avoid get_class()   18.26 % 3.70 %
207 270 Strange Name For Variables   18.10 % 139.90 %
208 193 Logical Mistakes   17.84 % 2.40 %
209 188 Deprecated Functions   17.79 % -3.30 %
210 194 Unused Interfaces   17.73 % 5.40 %
211 N/A Test Then Cast   17.63 % 176.30 %
212 192 No Hardcoded Ip   17.58 % -1.90 %
213 235 Multiply By One   17.32 % 74.80 %
214 201 Dont Echo Error   17.32 % 21.00 %
215 191 Useless Unset   17.00 % -7.70 %
216 158 Could Use str_repeat()   16.90 % -79.40 %
217 197 Use Object Api   16.64 % 2.00 %
218 198 Non-constant Index In Array   15.54 % -8.40 %
219 200 $this Belongs To Classes Or Traits   15.22 % -0.60 %
220 202 Non Static Methods Called In A Static   14.86 % 2.70 %
221 203 One Letter Functions   14.54 % 0.10 %
222 208 Foreach Reference Is Not Modified   14.54 % 4.70 %
223 206 Use With Fully Qualified Name   14.39 % 2.70 %
224 209 Results May Be Missing   14.39 % 3.20 %
225 204 Should Use Constants   14.23 % 0.50 %
226 207 Forgotten Whitespace   14.18 % 1.10 %
227 212 While(List() = Each())   13.71 % 5.10 %
228 205 Old Style Constructor   13.65 % -4.70 %
229 214 Undefined Trait   13.55 % 6.40 %
230 213 Assign With And   13.44 % 3.60 %
231 219 eval() Without Try   13.23 % 16.50 %
232 211 Identical Conditions   13.13 % -2.40 %
233 N/A Don’t Unset Properties   13.08 % 130.80 %
234 215 Must Return Methods   12.55 % -0.10 %
235 220 Illegal Name For Method   12.34 % 7.60 %
236 218 Unpreprocessed Values   11.98 % 0.60 %
237 221 Indices Are Int Or String   11.77 % 6.00 %
238 217 Suspicious Comparison   11.66 % -3.20 %
239 222 Hidden Use Expression   11.45 % 4.00 %
240 224 Redeclared PHP Functions   11.25 % 2.50 %
241 258 self, parent, static Outside Class   11.04 % 57.20 %
242 210 Strings With Strange Space   11.04 % -23.90 %
243 227 Nested Ternary   10.98 % 3.90 %
244 228 Dependant Trait   10.98 % 5.00 %
245 226 Catch Overwrite Variable   10.72 % -0.50 %
246 231 Or Die   10.62 % 3.80 %
247 232 Already Parents Interface   10.57 % 5.00 %
248 N/A Identical On Both Sides   10.15 % 101.50 %
249 234 Phpinfo   10.09 % 1.40 %
250 229 Lone Blocks   10.09 % -2.70 %
251 230 Useless Brackets   10.09 % -2.70 %
252 225 Unknown Directive Name   9.83 % -10.50 %
253 238 Overwritten Exceptions   9.47 % 2.70 %
254 236 Deep Definitions   9.41 % -0.80 %
255 237 Wrong fopen() Mode   9.41 % 1.50 %
256 240 Access Protected Structures   9.15 % 5.30 %
257 239 Avoid Parenthesis   9.00 % -0.90 %
258 N/A Unknown Pcre2 Option   8.73 % 87.30 %
259 242 Redefined Class Constants   8.68 % 4.00 %
260 241 No Real Comparison   8.47 % -0.40 %
261 216 preg_replace With Option e   8.11 % -44.50 %
262 244 Scalar Or Object Property   8.11 % 3.60 %
263 243 Not Not   8.05 % 1.80 %
264 247 Multiples Identical Case   7.69 % 6.30 %
265 223 Failed Substr Comparison   6.90 % -41.50 %
266 N/A Same Variables Foreach   6.85 % 68.50 %
267 251 No Hardcoded Port   6.59 % 1.70 %
268 253 Queries In Loops   6.38 % 0.70 %
269 250 Use Pathinfo   6.33 % -0.90 %
270 256 Too Many Injections   6.01 % 4.60 %
271 257 $this Is Not An Array   5.86 % 3.60 %
272 252 Unkown Regex Options   5.86 % -5.60 %
273 245 Mismatched Typehint   5.80 % -19.00 %
274 254 Class, Interface Or Trait With Identical Names   5.70 % -1.40 %
275 265 No Self Referencing Constant   5.59 % 9.00 %
276 N/A Missing New ?   5.59 % 55.90 %
277 313 Next Month Trap   5.33 % 52.80 %
278 261 __DIR__ Then Slash   5.28 % 1.90 %
279 263 Static Methods Can’t Contain $this   4.97 % 2.80 %
280 264 $this Is Not For Static Methods   4.97 % 2.80 %
281 259 No Magic With Array   4.70 % -6.20 %
282 262 Instantiating Abstract Class   4.65 % -1.50 %
283 267 Ambiguous Array Index   4.60 % 2.00 %
284 269 Old Style __autoload()   4.44 % 2.20 %
285 268 Too Many Finds   4.39 % 0.50 %
286 266 Lost References   4.23 % -2.20 %
287 182 Multiple Class Declarations   3.81 % -154.10 %
288 N/A Redefined Private Property   3.66 % 36.60 %
289 273 Empty Traits   3.61 % 9.50 %
290 281 Is Actually Zero   3.34 % 16.70 %
291 272 Throw Functioncall   3.13 % 1.80 %
292 249 Unused Traits   2.77 % -41.20 %
293 275 Multiple Alias Definitions Per File   2.66 % 2.30 %
294 274 Crc32() Might Be Negative   2.66 % 0.60 %
295 276 Implement Is For Interface   2.14 % 0.60 %
296 195 Missing Cases In Switch   2.14 % -146.50 %
297 277 Only Variable Returned By Reference   2.09 % 1.30 %
298 279 Accessing Private   1.88 % 0.90 %
299 280 Ternary In Concat   1.88 % 0.90 %
300 282 error_reporting() With Integers   1.77 % 1.50 %
301 284 Use System Tmp   1.67 % 0.50 %
302 283 Parent, Static Or Self Outside Class   1.46 % -1.60 %
303 285 Silently Cast Integer   1.46 % 0.20 %
304 N/A Strtr Arguments   1.46 % 14.60 %
305 303 Classes Mutually Extending Each Other   1.36 % 10.20 %
306 294 Foreach Needs Reference Array   1.36 % 6.10 %
307 286 Empty Namespace   1.25 % -0.20 %
308 316 Break Outside Loop   1.25 % 12.50 %
309 288 Non Ascii Variables   1.20 % 1.60 %
310 287 Useless Final   1.09 % -0.60 %
311 289 Constants With Strange Names   0.99 % 0.70 %
312 295 Should Use SetCookie()   0.94 % 1.90 %
313 291 Invalid Constant Name   0.88 % 0.20 %
314 N/A Inclusion Wrong Case   0.88 % 8.80 %
315 293 No Empty Regex   0.83 % 0.20 %
316 292 Always Positive Comparison   0.73 % -1.30 %
317 301 Multiple Identical Trait Or Interface   0.73 % 2.70 %
318 296 Throw In Destruct   0.68 % -0.10 %
319 290 Class Function Confusion   0.68 % -2.40 %
320 297 __toString() Throws Exception   0.62 % -0.10 %
321 298 Unused Label   0.62 % -0.10 %
322 299 Abstract Static Methods   0.57 % 0.00 %
323 302 Throws An Assignement   0.36 % -0.40 %
324 N/A Php/NoReferenceForTernary   0.36 % 3.60 %
325 300 Compared Comparison   0.31 % -1.50 %
326 310 No Reference On Left Side   0.26 % 1.50 %
327 306 Constants Created Outside Its Namespace   0.15 % 0.40 %
328 N/A Not A Scalar Type   0.15 % 1.50 %
329 307 Fully Qualified Constants   0.10 % -0.10 %
330 308 Hash Algorithms   0.10 % -0.10 %
331 304 Can’t Extend Final   0.10 % -2.40 %
332 305 Pathinfo() Returns May Vary   0.10 % -0.70 %
333 N/A Foreach On Object   0.10 % 1.00 %
334 315 Concrete Visibility   0.05 % 0.50 %
335 309 Empty List   0.05 % -0.60 %
336 317 func_get_arg() Modified   0.05 % 0.50 %
337 312 Negative Power   0.05 % 0.00 %
338 318 Strange Name For Constants   0.05 % 0.50 %
339 319 Implemented Methods Are Public   0.05 % 0.50 %
340 N/A No get_class() With Null   0.05 % 0.50 %
341 N/A Possible Infinite Loop   0.05 % 0.50 %
342 314 Short Open Tags   0.00 % 0.00 %
343 246 Using $this Outside A Class   0.00 % -76.40 %

EPIC Methodology

The “Exakat PHP Index of Coding”, aka EPIC, represents how often an static analysis rule reports results when auditing PHP code. The higher the rating, the higher is the probability to report issues. The lower the rating, the rarer are the issues.

This popularity is built by analyzing 1730 Open Source project, with PHP 7.1. Any issue reported by Exakat makes the project count as affected. Only when a project reports no issues, is it counted as error free.

 

EPIC FAQ

  • Can I reuse those results in an article or in my code?
    Yes. Simply mention ‘https://www.exakat.io’ as the source, and may be the month of publication (Current is 05/2018
  • Is there a computer-readable version ? 
    The Exakat PHP Index of Coding is available as JSON .
  • How does the index handle the false-positives ?
    False positives are only human-detectable. Help us reduce the false positive by reporting bugs and informations to remove them.
  • Why are some rules down to 0 ? Aren’t they useless?
    Some analysis require an old version of PHP, while the Index works with more recent versions of PHP (7.1 at the moment). As such, those analysis will dwindle to the bottom of the ranking and disappear.