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 million lines of PHP code. This is primarily for testing purpose, a kind of torture test that checks the engine run 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.

Jun 2020 May 2018 Prog. Name Rating Change
1 1 Uses Default Values   97.50 % 2.84 %
2 2 Used Once Variables (In Scope)   95.98 % 4.51 %
3 N/A Method Could Be Static   95.61 % 95.61 %
4 N/A Class Could Be Final   95.55 % 95.55 %
5 5 Should Use Local Class   94.94 % 4.36 %
6 39 Bail Out Early   92.02 % 29.24 %
7 11 Undefined Classes   91.59 % 12.87 %
8 8 PHP Keywords As Names   89.95 % 7.62 %
9 19 Unused Arguments   89.09 % 16.02 %
10 14 Nested Ifthen   87.69 % 10.70 %
11 17 Used Once Variables   87.08 % 13.03 %
12 9 Unresolved Classes   86.96 % 6.67 %
13 26 Preprocessable   86.35 % 16.64 %
14 18 Should Make Ternary   85.99 % 12.03 %
15 10 Property Used In One Method Only   84.53 % 5.72 %
16 22 No Boolean As Default   84.28 % 12.42 %
17 23 Use Named Boolean In Argument Definition   84.15 % 12.54 %
18 15 Relay Function   83.61 % 7.71 %
19 27 Avoid Optional Properties   83.19 % 13.95 %
20 24 Buried Assignation   82.82 % 11.75 %
21 69 Uncaught Exceptions   81.66 % 30.15 %
22 31 Use Positive Condition   81.54 % 13.69 %
23 20 Useless Parenthesis   81.05 % 8.20 %
24 41 Iffectations   80.32 % 18.12 %
25 40 Switch To Switch   79.23 % 16.92 %
26 160 Written Only Variables   78.62 % 52.06 %
27 46 No Class In Global   78.62 % 17.64 %
28 29 Overwritten Literals   78.56 % 9.72 %
29 44 Assigned Twice   78.31 % 16.91 %
30 N/A Undefined Variable   77.51 % 77.51 %
31 25 Strict Comparison With Booleans   76.85 % 5.92 %
32 37 Could Make A Function   75.57 % 11.51 %
33 35 No Need For Else   74.96 % 10.37 %
34 32 Pre-increment   74.60 % 8.11 %
35 38 Use Class Operator   74.60 % 11.41 %
36 58 include_once() Usage   73.69 % 17.66 %
37 N/A Inconsistent Elseif   73.06 % 73.06 %
38 36 Used Once Property   72.89 % 8.67 %
39 12 Unused Classes   72.77 % -5.53 %
40 55 Dont Change The Blind Var   72.28 % 14.94 %
41 42 Never Used Properties   72.04 % 10.38 %
42 70 Undefined Functions   71.98 % 20.65 %
43 56 Empty Function   71.86 % 14.83 %
44 73 Property Could Be Local   71.78 % 21.34 %
45 131 Should Use Coalesce   71.07 % 36.87 %
46 53 Drop Else After Return   70.46 % 12.91 %
47 N/A Ambiguous Visibilities   70.26 % 70.26 %
48 50 Check All Types   68.75 % 10.60 %
49 66 Switch Without Default   68.39 % 16.28 %
50 30 Long Arguments   67.23 % -1.49 %
51 51 Undefined Interfaces   67.11 % 9.04 %
52 62 @ Operator   66.80 % 13.43 %
53 76 Logical To in_array   66.26 % 16.66 %
54 72 Unresolved Use   65.89 % 15.08 %
55 54 Else If Versus Elseif   65.46 % 7.96 %
56 N/A Could Be Abstract Class   65.38 % 65.38 %
57 67 Static Loop   65.22 % 13.63 %
58 200 Too Many Local Variables   65.04 % 45.86 %
59 96 Ambiguous Static   64.96 % 21.26 %
60 N/A Check JSON   64.47 % 64.47 %
61 308 Non Ascii Variables   64.06 % 62.76 %
62 71 Undefined Parent   63.21 % 11.99 %
63 77 Use Instanceof   63.03 % 13.64 %
64 87 Mismatched Ternary Alternatives   62.72 % 16.25 %
65 163 Hardcoded Passwords   61.44 % 35.15 %
66 74 Common Alternatives   61.44 % 11.63 %
67 80 Missing Include   61.36 % 12.65 %
68 59 No Parenthesis For Language Construct   61.20 % 5.38 %
69 84 No Public Access   60.84 % 13.22 %
70 89 Could Use Short Assignation   60.84 % 14.90 %
71 176 Useless Abstract Class   60.53 % 36.12 %
72 63 Exit() Usage   60.35 % 7.14 %
73 83 Use random_int()   59.86 % 11.98 %
74 114 Useless Instructions   58.70 % 21.64 %
75 65 Echo With Concat   58.70 % 6.56 %
76 91 Undefined Properties   58.58 % 13.63 %
77 82 Identical Consecutive Expression   58.43 % 10.50 %
78 68 Empty Classes   58.40 % 6.89 %
79 90 String May Hold A Variable   58.22 % 12.83 %
80 93 Avoid Substr() One   57.97 % 13.49 %
81 N/A Variable Is Not A Condition   57.52 % 57.52 %
82 78 Several Instructions On The Same Line   57.42 % 8.29 %
83 124 Could Use self   57.42 % 22.45 %
84 88 Useless Referenced Argument   57.40 % 11.25 %
85 100 Empty Blocks   57.36 % 15.18 %
86 109 Double Instructions   57.30 % 17.32 %
87 94 Use const   57.00 % 12.57 %
88 95 Useless Interfaces   57.00 % 13.15 %
89 127 Could Use __DIR__   56.69 % 22.12 %
90 123 Modernize Empty With Expression   56.33 % 21.15 %
91 102 No array_merge() In Loops   55.96 % 14.18 %
92 110 Parent First   55.57 % 15.59 %
93 106 Double Assignation   55.42 % 14.91 %
94 115 Cast To Boolean   55.42 % 18.47 %
95 57 Undefined Constants   54.99 % -1.51 %
96 86 Strpos()-like Comparison   54.14 % 7.46 %
97 105 Return True False   53.77 % 12.67 %
98 104 Undefined Class Constants   53.71 % 12.00 %
99 52 Altering Foreach Without Reference   52.80 % -4.75 %
100 81 Use === null   52.13 % 3.94 %
101 177 Forgotten Interface   52.13 % 27.81 %
102 118 Global Usage   52.00 % 15.78 %
103 288 Callback Needs Return   51.98 % 47.96 %
104 113 Timestamp Difference   50.97 % 13.65 %
105 N/A Incompatible Signature Methods   50.88 % 50.88 %
106 N/A Method Signature Must Be Compatible   50.15 % 50.15 %
107 34 Constant Class   49.75 % -15.95 %
108 126 Same Conditions In Condition   49.75 % 14.97 %
109 150 Assign Default To Properties   49.57 % 20.88 %
110 108 Repeated print()   49.51 % 9.47 %
111 142 Unchecked Resources   49.26 % 18.58 %
112 119 Useless Check   48.84 % 12.62 %
113 130 Could Be Else   48.68 % 14.45 %
114 128 Unresolved Instanceof   48.35 % 13.84 %
115 99 Should Typecast   47.92 % 5.64 %
116 141 Empty Try Catch   47.80 % 16.70 %
117 148 Never Used Parameter   47.71 % 18.18 %
118 144 Too Many Native Calls   47.47 % 17.05 %
119 136 Useless Catch   47.34 % 14.73 %
120 125 Repeated Regex   47.13 % 12.20 %
121 N/A strpos() Too Much   46.86 % 46.86 %
122 145 Unconditional Break In Loop   46.61 % 16.40 %
123 157 Avoid Using stdClass   45.55 % 18.42 %
124 135 Wrong Parameter Type   45.43 % 12.19 %
125 122 If With Same Conditions   44.82 % 9.49 %
126 137 Don’t Change Incomings   44.76 % 12.30 %
127 165 No Hardcoded Hash   44.76 % 18.58 %
128 139 Should Make Alias   44.15 % 12.74 %
129 147 Unthrown Exception   43.90 % 14.30 %
130 N/A Dont Mix ++   43.81 % 43.81 %
131 97 Mixed Concat And Interpolation   43.78 % 0.37 %
132 146 No Choice   43.36 % 13.20 %
133 143 Multiple Type Variable   43.26 % 12.74 %
134 79 Empty Instructions   43.17 % -5.65 %
135 107 Class Should Be Final By Ocramius   42.87 % 2.78 %
136 153 Printf Number Of Arguments   42.77 % 15.07 %
137 101 Aliases Usage   42.69 % 0.56 %
138 121 Logical Should Use Symbolic Operators   42.50 % 6.80 %
139 117 Forgotten Visibility   42.38 % 5.67 %
140 149 Multiple Alias Definitions   42.26 % 13.04 %
141 N/A Weak Typing   41.56 % 41.56 %
142 133 No Return Used   41.35 % 7.20 %
143 155 Randomly Sorted Arrays   41.23 % 13.93 %
144 161 No Direct Call To Magic Method   41.04 % 14.53 %
145 N/A Possible Missing Subpattern   40.95 % 40.95 %
146 138 var_dump()… Usage   40.49 % 8.24 %
147 199 Don’t Unset Properties   40.28 % 21.05 %
148 180 Dangling Array References   40.25 % 16.00 %
149 152 Only Variable Passed By Reference   40.07 % 12.15 %
150 170 Unused Returned Value   39.70 % 14.67 %
151 164 Don’t Send $this In Constructor   39.24 % 12.95 %
152 134 Htmlentities Calls   39.22 % 5.93 %
153 178 Empty Interfaces   38.79 % 14.49 %
154 162 Wrong Optional Parameter   38.42 % 11.92 %
155 156 Wrong Number Of Arguments   38.42 % 11.19 %
156 N/A Don’t Read And Write In One Expression   38.20 % 38.20 %
157 175 Useless Constructor   38.18 % 13.72 %
158 168 Static Methods Called From Object   38.12 % 12.55 %
159 192 Useless Casting   37.75 % 17.16 %
160 158 Eval() Usage   37.69 % 10.88 %
161 166 list() May Omit Variables   37.45 % 11.46 %
162 183 No Direct Usage   36.90 % 13.49 %
163 181 Should Chain Exception   36.29 % 12.35 %
164 N/A Undefined ::class   34.79 % 34.79 %
165 189 Unset In Foreach   34.77 % 13.29 %
166 229 eval() Without Try   34.28 % 20.80 %
167 188 Undefined static:: Or self::   33.92 % 12.18 %
168 154 Make Global A Property   33.86 % 6.26 %
169 185 No Hardcoded Path   33.61 % 10.61 %
170 184 Mismatched Default Arguments   33.43 % 10.02 %
171 190 Adding Zero   33.25 % 12.40 %
172 203 Avoid get_class()   32.76 % 13.95 %
173 213 Don’t Echo Error   32.70 % 15.19 %
174 208 Test Then Cast   32.48 % 14.29 %
175 287 Is Actually Zero   32.35 % 28.07 %
176 159 Multiple Constant Definition   32.09 % 5.38 %
177 209 Logical Mistakes   31.24 % 13.15 %
178 169 Objects Don’t Need References   31.18 % 5.83 %
179 194 Forgotten Thrown   30.99 % 10.70 %
180 193 Useless Switch   30.57 % 10.18 %
181 172 Print And Die   29.35 % 4.63 %
182 187 Useless Return   29.23 % 7.23 %
183 174 Implied If   29.23 % 4.56 %
184 171 One Variable String   29.11 % 4.13 %
185 202 No isset() With empty()   28.74 % 9.72 %
186 214 Useless Unset   28.38 % 10.92 %
187 238 Redeclared PHP Functions   28.25 % 16.70 %
188 N/A Cant Instantiate Class   28.21 % 28.21 %
189 233 Unpreprocessed Values   28.19 % 15.96 %
190 230 Identical Conditions   28.13 % 14.70 %
191 204 Strange Name For Variables   28.07 % 9.46 %
192 206 Redefined Default   26.73 % 8.23 %
193 216 Non-constant Index In Array   26.24 % 10.35 %
194 241 Dependant Trait   26.24 % 15.11 %
195 191 Multiple Index Definition   25.21 % 4.61 %
196 179 Use Constant As Arguments   25.15 % 0.85 %
197 N/A Only Variable For Reference   24.86 % 24.86 %
198 186 Useless Global   24.84 % 2.41 %
199 220 Foreach Reference Is Not Modified   24.54 % 9.54 %
200 223 Should Use Constants   24.48 % 10.06 %
201 N/A Insufficient Typehint   24.43 % 24.43 %
202 236 Hidden Use Expression   24.29 % 12.53 %
203 212 No Hardcoded Ip   24.17 % 6.45 %
204 260 Scalar Or Object Property   24.11 % 15.75 %
205 215 Use PHP Object API   23.62 % 6.68 %
206 217 $this Belongs To Classes Or Traits   23.44 % 8.18 %
207 N/A Continue Is For Loop   23.21 % 23.21 %
208 242 Catch Overwrite Variable   23.14 % 12.17 %
209 207 Deprecated Functions   22.95 % 4.61 %
210 257 No Real Comparison   22.28 % 13.39 %
211 197 Should Use Prepared Statement   22.28 % 2.68 %
212 195 Var Keyword   22.22 % 2.36 %
213 231 Must Return Methods   22.22 % 9.37 %
214 132 Unused Inherited Variable In Closure   22.18 % -12.00 %
215 228 Undefined Trait   21.19 % 7.39 %
216 205 Could Be Static   20.76 % 2.21 %
217 218 Non Static Methods Called In A Static   20.52 % 5.36 %
218 243 Nested Ternary   20.40 % 9.48 %
219 201 Alternative Syntax Consistence   20.21 % 1.13 %
220 232 Illegal Name For Method   19.73 % 7.08 %
221 251 Overwritten Exceptions   19.67 % 9.90 %
222 248 Identical On Both Sides   19.19 % 8.69 %
223 221 Results May Be Missing   18.81 % 4.02 %
224 196 Unused Global   18.75 % -1.07 %
225 173 Invalid Regex   18.52 % -6.20 %
226 280 Redefined Private Property   18.22 % 13.42 %
227 235 Indices Are Int Or String   18.08 % 5.96 %
228 N/A Assign And Compare   17.42 % 17.42 %
229 210 Multiply By One   17.05 % -0.77 %
230 244 Already Parents Interface   17.05 % 6.18 %
231 273 Class, Interface Or Trait With Identical Names   16.86 % 11.17 %
232 253 Wrong fopen() Mode   16.62 % 6.95 %
233 222 Use With Fully Qualified Name   16.26 % 1.84 %
234 240 Strings With Strange Space   15.83 % 4.54 %
235 258 Redefined Class Constants   15.71 % 6.83 %
236 227 While(List() = Each())   15.46 % 1.66 %
237 225 Forgotten Whitespace   15.34 % 1.13 %
238 255 Unknown Pcre2 Option   15.29 % 6.04 %
239 237 Suspicious Comparison   15.10 % 3.34 %
240 226 Old Style Constructor   14.92 % 1.01 %
241 269 Missing Parenthesis   14.50 % 8.39 %
242 246 Lone Blocks   14.31 % 3.81 %
243 247 Useless Brackets   14.31 % 3.81 %
244 286 Lost References   14.19 % 9.86 %
245 301 Accessing Private   13.52 % 11.70 %
246 245 Or Die   13.33 % 2.61 %
247 277 __DIR__ Then Slash   13.27 % 7.94 %
248 N/A Can’t Throw Throwable   13.16 % 13.16 %
249 259 Not Not   13.15 % 4.79 %
250 263 Same Variables Foreach   12.91 % 6.07 %
251 224 Could Use str_repeat()   12.85 % -1.37 %
252 252 Deep Definitions   12.36 % 2.69 %
253 N/A Typehinted References   12.30 % 12.30 %
254 290 Empty Traits   12.24 % 8.53 %
255 N/A Mismatch Type And Default   11.82 % 11.82 %
256 264 No Hardcoded Port   11.51 % 4.77 %
257 262 Multiples Identical Case   10.96 % 3.12 %
258 256 Avoid Parenthesis   10.53 % 1.39 %
259 283 No Magic With Array   10.41 % 5.71 %
260 N/A Typehint Must Be Returned   10.05 % 10.05 %
261 281 Ambiguous Array Index   9.86 % 5.16 %
262 282 Instantiating Abstract Class   9.56 % 4.86 %
263 293 Wrong Range Check   9.26 % 6.49 %
264 298 Implement Is For Interface   9.01 % 6.87 %
265 261 preg_replace With Option e   8.83 % 0.68 %
266 234 Assign With And   8.70 % -3.47 %
267 294 Multiple Alias Definitions Per File   8.46 % 5.80 %
268 265 Use Pathinfo   8.09 % 1.51 %
269 274 Next Month Trap   7.67 % 2.08 %
270 316 Inclusion Wrong Case   7.37 % 6.49 %
271 N/A Undefined Insteadof   7.37 % 7.37 %
272 266 Queries In Loops   7.12 % 0.70 %
273 296 Strtr Arguments   6.82 % 4.42 %
274 276 Failed Substr Comparison   6.76 % 1.28 %
275 313 Should Use SetCookie()   6.69 % 5.70 %
276 254 Access Protected Structures   6.51 % -3.05 %
277 285 Too Many Finds   6.45 % 1.90 %
278 324 Throws An Assignement   5.84 % 5.48 %
279 278 Static Methods Can’t Contain $this   5.54 % 0.42 %
280 279 $this Is Not For Static Methods   5.54 % 0.42 %
281 275 Missing New ?   5.42 % -0.17 %
282 289 Multiple Class Declarations   5.35 % 1.49 %
283 271 Mismatched Typehint   5.17 % -0.73 %
284 284 Old Style __autoload()   4.93 % 0.28 %
285 N/A Abstract Or Implements   4.14 % 4.14 %
286 320 __toString() Throws Exception   3.95 % 3.28 %
287 291 Throw Functioncall   3.77 % 0.59 %
288 N/A Wrong Access Style to Property   3.71 % 3.71 %
289 239 self, parent, static Outside Class   3.59 % -7.75 %
290 295 Crc32() Might Be Negative   3.59 % 0.93 %
291 309 Empty Namespace   3.53 % 2.23 %
292 270 $this Is Not An Array   3.47 % -2.43 %
293 300 Ternary In Concat   3.41 % 1.48 %
294 304 Silently Cast Integer   3.34 % 1.72 %
295 297 Only Variable Returned By Reference   3.16 % 0.97 %
296 N/A Bad Constants Names   2.86 % 2.86 %
297 299 Missing Cases In Switch   2.74 % 0.60 %
298 331 Can’t Extend Final   2.49 % 2.34 %
299 N/A Method Collision Traits   2.49 % 2.49 %
300 305 Parent, Static Or Self Outside Class   2.00 % 0.49 %
301 302 error_reporting() With Integers   1.70 % -0.07 %
302 311 Useless Final   1.70 % 0.55 %
303 312 Constants With Strange Names   1.40 % 0.41 %
304 303 Use System Tmp   1.33 % -0.44 %
305 315 No Empty Regex   1.33 % 0.45 %
306 314 Invalid Constant Name   1.03 % 0.15 %
307 318 Always Positive Comparison   0.97 % 0.24 %
308 325 No Reference For Ternary   0.79 % 0.43 %
309 267 Unkown Regex Options   0.73 % -5.49 %
310 329 Constants Created Outside Its Namespace   0.60 % 0.45 %
311 317 Throw In Destruct   0.54 % -0.24 %
312 327 No Reference On Left Side   0.42 % 0.11 %
313 344 Possible Infinite Loop   0.42 % 0.42 %
314 N/A Clone With Non-Object   0.42 % 0.42 %
315 326 Compared Comparison   0.30 % -0.01 %
316 333 Pathinfo() Returns May Vary   0.24 % 0.14 %
317 341 No get_class() With Null   0.24 % 0.19 %
318 334 Foreach On Object   0.24 % 0.14 %
319 N/A Invalid Pack Format   0.24 % 0.24 %
320 N/A Should Yield With Key   0.18 % 0.18 %
321 330 Hash Algorithms   0.12 % -0.03 %
322 321 Multiple Identical Trait Or Interface   0.06 % -0.61 %
323 339 Strange Name For Constants   0.06 % 0.01 %
324 N/A Must Call Parent Constructor   0.06 % 0.06 %
325 N/A Repeated Interface   0.06 % 0.06 %
326 N/A Useless Alias   0.06 % 0.06 %
327 N/A Methods Without Return   0.00 % 0.00 %
328 182 Incompilable Files   0.00 % -23.41 %
329 323 Abstract Static Methods   0.00 % -0.57 %
330 342 Short Open Tags   0.00 % 0.00 %
331 332 Fully Qualified Constants   0.00 % -0.10 %
332 N/A Use Constant   0.00 % 0.00 %
333 335 Concrete Visibility   0.00 % -0.05 %
334 272 No Self Referencing Constant   0.00 % -5.75 %
335 310 Break Outside Loop   0.00 % -1.25 %
336 336 Empty List   0.00 % -0.05 %
337 337 func_get_arg() Modified   0.00 % -0.05 %
338 338 Negative Power   0.00 % -0.05 %
339 343 Using $this Outside A Class   0.00 % 0.00 %
340 340 Implemented Methods Are Public   0.00 % -0.05 %
341 268 Too Many Injections   0.00 % -6.17 %
342 N/A Assert Function Is Reserved   0.00 % 0.00 %

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 06/2020
  • 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.