{"title":"Denzyl Dick","subtitle":"My site ","link":[{"@attributes":{"rel":"self","type":"application\/atom+xml","href":"https:\/\/denzyl.io\/atom.xml"}},{"@attributes":{"rel":"alternate","type":"text\/html","href":"https:\/\/denzyl.io"}}],"generator":"Zola","updated":"2020-01-01T00:00:00+00:00","id":"https:\/\/denzyl.io\/atom.xml","entry":[{"title":"Detecting spaghetti code in AST of a PHP source code.","published":"2020-01-01T00:00:00+00:00","updated":"2020-01-01T00:00:00+00:00","author":{"name":"\n            \n              Unknown\n            \n          "},"link":{"@attributes":{"rel":"alternate","type":"text\/html","href":"https:\/\/denzyl.io\/blog\/detecting-spaghetti-code-in-ast-of-a-php-source-code\/"}},"id":"https:\/\/denzyl.io\/blog\/detecting-spaghetti-code-in-ast-of-a-php-source-code\/","content":"<blockquote>\n<p>This is the part(3) of a series. I suggest you read parts <a href=\"https:\/\/denzyl.io\/blog\/detecting-spaghetti-code-in-ast-of-a-php-source-code\/.\/Write_your_own_static_analyzer_for_PHP.md\">1<\/a> and <a href=\"https:\/\/denzyl.io\/blog\/detecting-spaghetti-code-in-ast-of-a-php-source-code\/.\/How_I_made_impossible_to_write_spaghetti_code.md\">2<\/a> before this one.<\/p>\n<\/blockquote>\n<p>In part <a href=\"https:\/\/denzyl.io\/blog\/detecting-spaghetti-code-in-ast-of-a-php-source-code\/.\/How_I_made_impossible_to_write_spaghetti_code.md\">2<\/a>, I made sure that the test passed correctly. The focus now is how we traverse a block of code inside its scope. We should be able to increase the variables in the formula at the right moment.<\/p>\n<p>If you have read part <a href=\"https:\/\/denzyl.io\/blog\/detecting-spaghetti-code-in-ast-of-a-php-source-code\/.\/Write_your_own_static_analyzer_for_PHP.md\">1<\/a>, you know that we need to implement the validate function that is mandatory in the trait <code>Rule<\/code>.<\/p>\n<pre data-lang=\"rust\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-rust \"><code class=\"language-rust\" data-lang=\"rust\"><span>\n<\/span><span style=\"color:#9d0006;\">impl <\/span><span>Rule <\/span><span style=\"color:#9d0006;\">for <\/span><span style=\"color:#407959;\">E009 <\/span><span>{\n<\/span><span>    <\/span><span style=\"color:#9d0006;\">fn <\/span><span style=\"color:#407959;\">validate<\/span><span>(\n<\/span><span>        <\/span><span style=\"color:#b23c15;\">&amp;<\/span><span style=\"color:#282828;\">self<\/span><span>,\n<\/span><span>        <\/span><span style=\"color:#282828;\">statement<\/span><span>: <\/span><span style=\"color:#b23c15;\">&amp;<\/span><span>php_parser_rs::parser::ast::Statement,\n<\/span><span>    ) -&gt; <\/span><span style=\"color:#b57614;\">Vec<\/span><span>&lt;crate::project::Suggestion&gt; {\n<\/span><span>\n<\/span><span>    }\n<\/span><span>}\n<\/span><span>\n<\/span><\/code><\/pre>\n<p>In part <a href=\"https:\/\/denzyl.io\/blog\/detecting-spaghetti-code-in-ast-of-a-php-source-code\/.\/How_I_made_impossible_to_write_spaghetti_code.md\">2<\/a> we have learned that :<\/p>\n<blockquote>\n<p>Nodes are like the conditional statement: if, else, while, for, etc.\nEdges are the paths that can be taken.<\/p>\n<\/blockquote>\n<p>The <code>validate<\/code> function will be executed for every statement in a source code. In the source code below, there are 32 lines of code.<\/p>\n<pre data-lang=\"php\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-php \"><code class=\"language-php\" data-lang=\"php\"><span>&lt;?php\n<\/span><span style=\"color:#282828;\">\n<\/span><span style=\"color:#9d0006;\">class <\/span><span style=\"color:#407959;\">Index<\/span><span style=\"color:#282828;\">{\n<\/span><span style=\"color:#282828;\">\n<\/span><span style=\"color:#282828;\">  <\/span><span style=\"color:#9d0006;\">public function <\/span><span style=\"color:#407959;\">tooComplex<\/span><span style=\"color:#282828;\">(){\n<\/span><span style=\"color:#282828;\">    $a <\/span><span style=\"color:#b23c15;\">= <\/span><span style=\"color:#8f3f71;\">1<\/span><span style=\"color:#282828;\">;\n<\/span><span style=\"color:#282828;\">    $b <\/span><span style=\"color:#b23c15;\">= <\/span><span style=\"color:#8f3f71;\">2<\/span><span style=\"color:#282828;\">;\n<\/span><span style=\"color:#282828;\">\n<\/span><span style=\"color:#282828;\">\n<\/span><span style=\"color:#282828;\">    <\/span><span style=\"color:#9d0006;\">if<\/span><span style=\"color:#282828;\">($a <\/span><span style=\"color:#b23c15;\">&gt; <\/span><span style=\"color:#282828;\">$b){\n<\/span><span style=\"color:#282828;\">      <\/span><span style=\"color:#9d0006;\">if<\/span><span style=\"color:#282828;\">($b <\/span><span style=\"color:#b23c15;\">&lt; <\/span><span style=\"color:#282828;\">$a){\n<\/span><span style=\"color:#282828;\">\n<\/span><span style=\"color:#282828;\">        <\/span><span style=\"color:#9d0006;\">if<\/span><span style=\"color:#282828;\">($a <\/span><span style=\"color:#b23c15;\">== <\/span><span style=\"color:#282828;\">$b){\n<\/span><span style=\"color:#282828;\">\n<\/span><span style=\"color:#282828;\">          <\/span><span style=\"color:#9d0006;\">while<\/span><span style=\"color:#282828;\">($b <\/span><span style=\"color:#b23c15;\">&gt; <\/span><span style=\"color:#282828;\">$a){\n<\/span><span style=\"color:#282828;\">\n<\/span><span style=\"color:#282828;\">          }\n<\/span><span style=\"color:#282828;\">\n<\/span><span style=\"color:#282828;\">        }\n<\/span><span style=\"color:#282828;\">      }\n<\/span><span style=\"color:#282828;\">    }\n<\/span><span style=\"color:#282828;\">  }\n<\/span><span style=\"color:#282828;\">}\n<\/span><span style=\"color:#282828;\">\n<\/span><\/code><\/pre>\n<p><a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/github.com\/denzyldick\/phanalist\">Phanalist<\/a> needs a way to detect when we are in the function\u2019s scope with the name <code>tooComplex().<\/code> With pattern matching, it is super easy to detect if the statement is either: <code>if<\/code>,<code>else<\/code>,<code>etc..<\/code> The first statement that I want to match for is <code>class Index{<\/code> and from there, we will continue down the tree. If you think the same way as I do you know that I will be using recursion to calculate the cyclomatic complexity. After we have matched the scope of the <code>tooComplex()<\/code> function.<\/p>\n<pre data-lang=\"rust\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-rust \"><code class=\"language-rust\" data-lang=\"rust\"><span style=\"color:#9d0006;\">impl <\/span><span>Rule <\/span><span style=\"color:#9d0006;\">for <\/span><span style=\"color:#407959;\">E009 <\/span><span>{\n<\/span><span>    <\/span><span style=\"color:#9d0006;\">fn <\/span><span style=\"color:#407959;\">validate<\/span><span>(\n<\/span><span>        <\/span><span style=\"color:#b23c15;\">&amp;<\/span><span style=\"color:#282828;\">self<\/span><span>,\n<\/span><span>        <\/span><span style=\"color:#282828;\">statement<\/span><span>: <\/span><span style=\"color:#b23c15;\">&amp;<\/span><span>php_parser_rs::parser::ast::Statement,\n<\/span><span>    ) -&gt; <\/span><span style=\"color:#b57614;\">Vec<\/span><span>&lt;crate::project::Suggestion&gt; {\n<\/span><span>        <\/span><span style=\"color:#9d0006;\">let mut<\/span><span> suggestions <\/span><span style=\"color:#b23c15;\">= <\/span><span style=\"color:#b57614;\">Vec<\/span><span>::new();\n<\/span><span>        <\/span><span style=\"color:#9d0006;\">let mut<\/span><span> graph <\/span><span style=\"color:#b23c15;\">=<\/span><span> Graph { n: <\/span><span style=\"color:#8f3f71;\">0<\/span><span>, e: <\/span><span style=\"color:#8f3f71;\">0<\/span><span>, p: <\/span><span style=\"color:#8f3f71;\">0 <\/span><span>};\n<\/span><span>        <\/span><span style=\"color:#9d0006;\">match<\/span><span> statement {\n<\/span><span>            Statement::Class(class) <\/span><span style=\"color:#b23c15;\">=&gt; <\/span><span>{\n<\/span><span>                <\/span><span style=\"color:#9d0006;\">for<\/span><span> member <\/span><span style=\"color:#b23c15;\">in &amp;<\/span><span>class.body.members {\n<\/span><span>                    <\/span><span style=\"color:#9d0006;\">match<\/span><span> member {\n<\/span><span>                        ClassMember::ConcreteMethod(concretemethod) <\/span><span style=\"color:#b23c15;\">=&gt; <\/span><span>{\n<\/span><span>                            <\/span><span style=\"color:#9d0006;\">match<\/span><span> concretemethod.body.<\/span><span style=\"color:#b57614;\">clone<\/span><span>() {\n<\/span><span>                                MethodBody {\n<\/span><span>                                    comments: <\/span><span style=\"color:#b23c15;\">_<\/span><span>,\n<\/span><span>                                    left_brace: <\/span><span style=\"color:#b23c15;\">_<\/span><span>,\n<\/span><span>                                    statements,\n<\/span><span>                                    right_brace: <\/span><span style=\"color:#b23c15;\">_<\/span><span>,\n<\/span><span>                                } <\/span><span style=\"color:#b23c15;\">=&gt; <\/span><span>{\n<\/span><span>                                   <\/span><span style=\"font-style:italic;color:#928374;\">\/\/\/ HERE !!\n<\/span><span>                                    }\n<\/span><span>                                }\n<\/span><span>                            }\n<\/span><span>                        }\n<\/span><span>                        <\/span><span style=\"color:#b23c15;\">_ =&gt; <\/span><span>{}\n<\/span><span>                    }\n<\/span><span>                }\n<\/span><span>            }\n<\/span><span>            <\/span><span style=\"color:#b23c15;\">_ =&gt; <\/span><span>{}\n<\/span><span>        }\n<\/span><span>        suggestions\n<\/span><span>    }\n<\/span><span>}\n<\/span><span>\n<\/span><\/code><\/pre>\n<p>If you aren\u2019t familiar with pattern matching, it\u2019s kind of a switch keyword on steroids. Look for the Look for <code>\/\/\/ HERE !!<\/code> in the above code.<\/p>\n<pre data-lang=\"rust\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-rust \"><code class=\"language-rust\" data-lang=\"rust\"><span> MethodBody {\n<\/span><span>                                    comments: <\/span><span style=\"color:#b23c15;\">_<\/span><span>,\n<\/span><span>                                    left_brace: <\/span><span style=\"color:#b23c15;\">_<\/span><span>,\n<\/span><span>                                    statements,\n<\/span><span>                                    right_brace: <\/span><span style=\"color:#b23c15;\">_<\/span><span>,\n<\/span><span>                                } <\/span><span style=\"color:#b23c15;\">=&gt; <\/span><span>{\n<\/span><span>                                    <\/span><span style=\"font-style:italic;color:#928374;\">\/\/\/ HERE 1\n<\/span><span>\n<\/span><span>                                    }\n<\/span><span>                                }\n<\/span><span>\n<\/span><\/code><\/pre>\n<p>As you can see we have four parameters that we can use. The ones we are looking for are the statements. The type of this parameter is <code>Vec&lt;Statement&gt;<\/code> meaning it can be anything.<\/p>\n<p>Let\u2019s use the <code>Graph<\/code> we previously created in part <a href=\"https:\/\/denzyl.io\/blog\/detecting-spaghetti-code-in-ast-of-a-php-source-code\/.\/How_I_made_impossible_to_write_spaghetti_code.md\">2<\/a><\/p>\n<p>In the source code below, <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/github.com\/denzyldick\/phanalist\">Phanalist<\/a> calls a function with <code>let graph  = calculate _cyclomatic_complexity();<\/code> This function will return a struct of the type <code>Graph<\/code>. The first parameter passed is <code>statements.clone()<\/code>. This function uses recursion to traverse down the tree. In part 4 I will explain the recursion we were thinking about.<\/p>\n<pre data-lang=\"rust\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-rust \"><code class=\"language-rust\" data-lang=\"rust\"><span>\n<\/span><span> <\/span><span style=\"color:#9d0006;\">let<\/span><span> graph <\/span><span style=\"color:#b23c15;\">= <\/span><span style=\"color:#b57614;\">calculate_cyclomatic_complexity<\/span><span>(\n<\/span><span>                                        statements.<\/span><span style=\"color:#b57614;\">clone<\/span><span>(),\n<\/span><span>                                        <\/span><span style=\"color:#b23c15;\">&amp;<\/span><span style=\"color:#9d0006;\">mut<\/span><span> graph,\n<\/span><span>                                    );\n<\/span><span> <\/span><span style=\"color:#9d0006;\">if<\/span><span> graph.<\/span><span style=\"color:#b57614;\">calculate<\/span><span>() <\/span><span style=\"color:#b23c15;\">&gt; <\/span><span style=\"color:#8f3f71;\">10 <\/span><span>{\n<\/span><span>suggestions.<\/span><span style=\"color:#b57614;\">push<\/span><span>(Suggestion::from(<\/span><span style=\"color:#79740e;\">&quot;This method body is too complex. Make it easier to understand.&quot;<\/span><span>.<\/span><span style=\"color:#b57614;\">to_string<\/span><span>(),\n<\/span><span>                concretemethod.function,\n<\/span><span style=\"color:#79740e;\">&quot;E009&quot;<\/span><span>.<\/span><span style=\"color:#b57614;\">to_string<\/span><span>() ));\n<\/span><span>}\n<\/span><span>\n<\/span><\/code><\/pre>\n<p>The <code>Graph<\/code> struct has the <code>calculate<\/code> function we previously used to calculate the cyclomatic complexity. My threshold is always ten, so I will be using that.<\/p>\n<p>If the value exceeds ten, I push the <code>Suggestion<\/code> onto the vector. The vector of <code>Suggestion<\/code> is the value returned to the validate function\u2019s caller.<\/p>\n<h1 id=\"recursion\"><a class=\"zola-anchor\" href=\"#recursion\" aria-label=\"Anchor link for: recursion\">\ud83d\udd17<\/a>Recursion<\/h1>\n<p><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/wj5yh9nh4jtfjnie3ncf.png\" alt=\"Image description\" \/><\/p>\n<blockquote>\n<p>In computer science, recursion is a method of solving a computational problem where the solution depends on solutions to smaller instances of the same problem. Recursion solves such recursive problems using functions that call themselves from within their code. <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/en.wikipedia.org\/wiki\/Recursion_(computer_science)\">Wikipedia<\/a><\/p>\n<\/blockquote>\n<h1 id=\"conclusion\"><a class=\"zola-anchor\" href=\"#conclusion\" aria-label=\"Anchor link for: conclusion\">\ud83d\udd17<\/a>Conclusion<\/h1>\n<p>If you are a PHP developer, you know that a developer can make many more mistakes in PHP. In the future, the list of Rules will continue to grow into something more useful.<\/p>\n<p>Thanks for reading!<\/p>\n<p>Contribution is always welcome if you have a mistake you would like to add to <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/github.com\/denzyldick\/phanalist\">Phanalist<\/a>.<\/p>\n"},{"title":"How I made it impossible to write spaghetti code","published":"2020-01-01T00:00:00+00:00","updated":"2020-01-01T00:00:00+00:00","author":{"name":"\n            \n              Unknown\n            \n          "},"link":{"@attributes":{"rel":"alternate","type":"text\/html","href":"https:\/\/denzyl.io\/blog\/how-i-made-impossible-to-write-spaghetti-code\/"}},"id":"https:\/\/denzyl.io\/blog\/how-i-made-impossible-to-write-spaghetti-code\/","content":"<blockquote>\n<p>This is part 2 of a series of my static analyzer for PHP. If you did not read part <a href=\"https:\/\/denzyl.io\/blog\/how-i-made-impossible-to-write-spaghetti-code\/.\/Write_your_own_static_analyzer_for_PHP.md\">1<\/a>, I suggest you to read it first.<\/p>\n<\/blockquote>\n<p>A long time ago, I went to a development user group, and one of the talks was about cyclomatic complexity. At that time, I thought, what a cool name. If you already know the meaning of that cool name. Congrats, you are probably 1 of those developers who can detect lousy code without reading it. By seeing the indentation\u2019s shape, you can smell the bad code.\n<img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/eo1n1vk543d8cz6ftb64.png\" alt=\"Bad code with too many identation\" \/><\/p>\n<p><em><strong>Cyclomatic definition:<\/strong>\nUsed to describe the number of circuits in a network; equal to the number of edges minus the number of nodes plus the number of graphs.<\/em><\/p>\n<p>Ok, breathe. If we translate the definitions into code, it will be something like this.<\/p>\n<p><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/ugeaorf0204fpyhyuq6a.png\" alt=\"Bad code example\" \/><\/p>\n<p>Nodes are like the conditional statement: <code>if<\/code>, <code>else<\/code>, <code>while<\/code>, <code>for<\/code>, etc.\nEdges are the paths that can be taken. There are two paths in the code on lines <code>4<\/code> and <code>14<\/code>. One of the two can be taken if the variable defined on line <code>3<\/code> has the value of <code>Hola<\/code>; in this case, the first path will be taken. But in this example, the value of the <code>$a<\/code> is <code>Helloworld<\/code> so the second path will be taken. In the control flow graph below, you can view a better representation.<\/p>\n<p><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/eehbcsl5fsphsjk3klw2.png\" alt=\"Control flow graph\" \/><\/p>\n<p>Ok, right; what is the complexity of that cool name I previously told you about?<\/p>\n<p>The code above is a small example, but imagine you have a method that has 100 lines of code. Then, the complexity of the code will increase drastically.<\/p>\n<h2 id=\"calculate-the-complexity\"><a class=\"zola-anchor\" href=\"#calculate-the-complexity\" aria-label=\"Anchor link for: calculate-the-complexity\">\ud83d\udd17<\/a>Calculate the complexity<\/h2>\n<p>The equation for calculating the cyclomatic complexity is:<\/p>\n<p>{% katex %} M = N - E + 2P {% endkatex %}<\/p>\n<blockquote>\n<p>This formula is also known as McCabe\u2019s Cyclomatic Complexity (MCC) and is widely used to measure the complexity of a program by analyzing its control flow structure.<\/p>\n<\/blockquote>\n<p><code>N<\/code> stands for the number of nodes, and <code>E<\/code> stands for the number of edges. The <code>2P<\/code> stands for two multiplied by the number of exit nodes. In our example, this will translate into:<\/p>\n<p>{% katex %} 5 = 8 - 9 + 2 x 3 {% endkatex %}<\/p>\n<p>So, I started this blog by saying I can prevent myself from writing spaghetti code. If you did not read part <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/dev.to\/denzyldick\/the-beginning-of-my-php-static-analyzer-in-rust-5bp8\">1<\/a> of this series, you might not know I\u2019m working on a static analyzer for PHP. The project\u2019s name is phanalist, and it\u2019s available on <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/github.com\/denzyldick\/phanalist\">github<\/a>.<\/p>\n<p>In the following paragraph, we will see how <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/github.com\/denzyldick\/phanalist\">phanalist<\/a> can calculate the cyclomatic complexity of the scope of a method. Before creating Phanalist, I always kept the cyclomatic complexity of the methods I wrote in my mind. And if I see that the complexity is higher than 10. I always try to refactor the method, making it easier to understand.<\/p>\n<p>How does <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/github.com\/denzyldick\/phanalist\">phanalist<\/a> calculate the cyclomatic complexity? Let\u2019s start by implementing the equation above. We will start by creating a struct named Graph. This struct will have the three variables from the equation(n, e, and p).<\/p>\n<pre data-lang=\"rust\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-rust \"><code class=\"language-rust\" data-lang=\"rust\"><span style=\"color:#9d0006;\">struct <\/span><span style=\"color:#407959;\">Graph <\/span><span>{\n<\/span><span>    <\/span><span style=\"color:#282828;\">n<\/span><span>: <\/span><span style=\"color:#9d0006;\">i64<\/span><span>,\n<\/span><span>    <\/span><span style=\"color:#282828;\">e<\/span><span>: <\/span><span style=\"color:#9d0006;\">i64<\/span><span>,\n<\/span><span>    <\/span><span style=\"color:#282828;\">p<\/span><span>: <\/span><span style=\"color:#9d0006;\">i64<\/span><span>,\n<\/span><span>}\n<\/span><\/code><\/pre>\n<blockquote>\n<p>This struct will be passed around when traversing the abstract syntax tree.<\/p>\n<\/blockquote>\n<p>{% katex %} M = N - E + 2P {% endkatex %}<\/p>\n<p>When traversing the AST, we can increase the variables at the right moment. After that, I used the MCC equation to calculate the cyclomatic complexity of our example code.<\/p>\n<pre data-lang=\"rust\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-rust \"><code class=\"language-rust\" data-lang=\"rust\"><span style=\"color:#9d0006;\">impl <\/span><span style=\"color:#407959;\">Graph <\/span><span>{\n<\/span><span>    <\/span><span style=\"color:#9d0006;\">pub fn <\/span><span style=\"color:#407959;\">calculate<\/span><span>(<\/span><span style=\"color:#282828;\">self<\/span><span>) -&gt; <\/span><span style=\"color:#9d0006;\">i64 <\/span><span>{\n<\/span><span>        <\/span><span style=\"color:#282828;\">self<\/span><span>.n <\/span><span style=\"color:#b23c15;\">- <\/span><span style=\"color:#282828;\">self<\/span><span>.e <\/span><span style=\"color:#b23c15;\">+ <\/span><span>(<\/span><span style=\"color:#8f3f71;\">2 <\/span><span style=\"color:#b23c15;\">* <\/span><span style=\"color:#282828;\">self<\/span><span>.p)\n<\/span><span>    }\n<\/span><span>}\n<\/span><span>#[<\/span><span style=\"color:#282828;\">test<\/span><span>]\n<\/span><span style=\"color:#9d0006;\">pub fn <\/span><span style=\"color:#407959;\">calculate<\/span><span>() {\n<\/span><span>    <\/span><span style=\"color:#9d0006;\">let<\/span><span> g <\/span><span style=\"color:#b23c15;\">=<\/span><span> Graph { n: <\/span><span style=\"color:#8f3f71;\">8<\/span><span>, e: <\/span><span style=\"color:#8f3f71;\">9<\/span><span>, p: <\/span><span style=\"color:#8f3f71;\">3 <\/span><span>};\n<\/span><span>    <\/span><span style=\"color:#b57614;\">assert_eq!<\/span><span>(g.<\/span><span style=\"color:#b57614;\">calculate<\/span><span>(), <\/span><span style=\"color:#8f3f71;\">5<\/span><span>);\n<\/span><span>}\n<\/span><span>\n<\/span><\/code><\/pre>\n<p>In part <a href=\"https:\/\/denzyl.io\/blog\/how-i-made-impossible-to-write-spaghetti-code\/.\/How_I_made_impossible_to_write_spaghetti_code.md\">1<\/a>, I explained how to navigate the abstract syntax tree and how Phanalist generates one. If you missed it, I suggest you read that before reading the next part of the series.<\/p>\n<p>In part <a href=\"https:\/\/denzyl.io\/blog\/how-i-made-impossible-to-write-spaghetti-code\/.\/Detecting_spaghetti_code_in_AST_of_a_PHP_source_code.md\">3<\/a> of this series. I will explain how we traverse the AST when calculating the cyclomatic complexity.<\/p>\n"},{"title":"Improve your CI output","published":"2020-01-01T00:00:00+00:00","updated":"2020-01-01T00:00:00+00:00","author":{"name":"\n            \n              Unknown\n            \n          "},"link":{"@attributes":{"rel":"alternate","type":"text\/html","href":"https:\/\/denzyl.io\/blog\/improve-your-ci-output\/"}},"id":"https:\/\/denzyl.io\/blog\/improve-your-ci-output\/","content":"<p>Have you ever been in a situation where you made a PR or MR and waited for a couple of seconds for the output of the CI pipeline? But something went wrong, and you can\u2019t see the issue in the blink of an eye. And you get annoyed that you must read a few logs to discover the problem?<\/p>\n<p>It\u2019s a scenario that many of us have likely encountered at some point.<\/p>\n<p>This article teaches how to improve your CI output. I will use Github.<\/p>\n<blockquote>\n<p>This article is part of a series about a static analysis tool I\u2019ve worked on for over a year. It\u2019s called <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/github.com\/denzyldick\/phanalist\">Phanalist<\/a>. Please check it out and hit the star button. Thank you.<\/p>\n<\/blockquote>\n<p>How can I improve the CI output in Github? When running your CI tools, you probably output everything to STDOUT and view the content in the log viewer.<\/p>\n<p>Something like this:<\/p>\n<p><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/6jkmm3hl8flza7socosu.png\" alt=\"Image description\" \/><\/p>\n<p>The output format text in Phanalist is not so bad. It\u2019s readable because of the table layout. But why stop there?<\/p>\n<p>Microsoft is not so evil anymore, and Github has solved that problem I\u2019ve already. What we will be using is what they call <code>SARIF<\/code>. It stands\nfor Static Analysis Results Interchange Format. It\u2019s a specification for understanding the output of static analysis tools. That is how the tools can display information in the code scanning section under the security tab on a repository.<\/p>\n<p><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/zibtgelhhm0kyx8x1yys.png\" alt=\"Image description\" \/><\/p>\n<p>For Phanalist to have a chance to be adopted by more people, this is a must feature that should be implemented first. Then, I can focus on adding more rules to the tool.<\/p>\n<p>For context, <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/gitub.com\/denzyldick\/phanalist\">Phanalist<\/a> consists of rules implemented by the contributors. Every rule has a detailed explanation of what you are doing wrong and guides you in the right direction so you can fix it.<\/p>\n<p>The tools under the code scanning section use a Github action called <code>github\/codeql-action\/upload-sarif<\/code>. This action uploads a <code>.sarif<\/code> file to GitHub. Remember that you will need the right permissions to upload a file from the Github workflow. After uploading, Github will validate the file\u2019s content, and if there are any errors, they will be displayed in the logs. If everything goes well, you will have more issues to fix under the security tab.<\/p>\n<p>The tools you use should have a <code>Sarif<\/code> output. At the time of writing, I do not know if the popular static analysis tools in the PHP ecosystem support Sarif, but if not, you can help them with that.<\/p>\n<p>But <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/github.com\/denzyldick\/phanalist\">Phanalist<\/a> supports that format. It can output information in three formats: <code>text<\/code>, <code>json<\/code>, and <code>sarif<\/code>.<\/p>\n<pre data-lang=\"bash\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-bash \"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"color:#282828;\">phanalist --src<\/span><span style=\"color:#b23c15;\">=<\/span><span style=\"color:#282828;\">. --output-format<\/span><span style=\"color:#b23c15;\">=<\/span><span style=\"color:#282828;\">sarif\n<\/span><\/code><\/pre>\n<p>The output will be something like this:<\/p>\n<pre data-lang=\"json\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-json \"><code class=\"language-json\" data-lang=\"json\"><span>{\n<\/span><span>  <\/span><span style=\"color:#79740e;\">&quot;version&quot;<\/span><span>: <\/span><span style=\"color:#79740e;\">&quot;2.1.0&quot;<\/span><span>,\n<\/span><span>  <\/span><span style=\"color:#79740e;\">&quot;$schema&quot;<\/span><span>: <\/span><span style=\"color:#79740e;\">&quot;http:\/\/json.schemastore.org\/sarif-2.1.0-rtm.4&quot;<\/span><span>,\n<\/span><span>  <\/span><span style=\"color:#79740e;\">&quot;runs&quot;<\/span><span>: [\n<\/span><span>    {\n<\/span><span>      <\/span><span style=\"color:#79740e;\">&quot;tool&quot;<\/span><span>: {\n<\/span><span>        <\/span><span style=\"color:#79740e;\">&quot;driver&quot;<\/span><span>: {\n<\/span><span>          <\/span><span style=\"color:#79740e;\">&quot;name&quot;<\/span><span>: <\/span><span style=\"color:#79740e;\">&quot;Phanalist&quot;<\/span><span>,\n<\/span><span>          <\/span><span style=\"color:#79740e;\">&quot;informationUri&quot;<\/span><span>: <\/span><span style=\"color:#79740e;\">&quot;https:\/\/github.com\/denzyldick\/phanalist&quot;<\/span><span>,\n<\/span><span>          <\/span><span style=\"color:#79740e;\">&quot;rules&quot;<\/span><span>: [\n<\/span><span>            {\n<\/span><span>              <\/span><span style=\"color:#79740e;\">&quot;id&quot;<\/span><span>: <\/span><span style=\"color:#79740e;\">&quot;e0009&quot;<\/span><span>,\n<\/span><span>              <\/span><span style=\"color:#79740e;\">&quot;shortDescription&quot;<\/span><span>: {\n<\/span><span>                <\/span><span style=\"color:#79740e;\">&quot;text&quot;<\/span><span>: <\/span><span style=\"color:#79740e;\">&quot;Method is too complex&quot;\n<\/span><span>              },\n<\/span><span>              <\/span><span style=\"color:#79740e;\">&quot;properties&quot;<\/span><span>: {\n<\/span><span>                <\/span><span style=\"color:#79740e;\">&quot;category&quot;<\/span><span>: <\/span><span style=\"color:#79740e;\">&quot;phanalist&quot;\n<\/span><span>              }\n<\/span><span>            }\n<\/span><span>          ]\n<\/span><span>        }\n<\/span><span>      },\n<\/span><span>      <\/span><span style=\"color:#79740e;\">&quot;artifacts&quot;<\/span><span>: [\n<\/span><span>        {\n<\/span><span>          <\/span><span style=\"color:#79740e;\">&quot;location&quot;<\/span><span>: {\n<\/span><span>            <\/span><span style=\"color:#79740e;\">&quot;uri&quot;<\/span><span>: <\/span><span style=\"color:#79740e;\">&quot;src\/complex.php&quot;\n<\/span><span>          }\n<\/span><span>        }\n<\/span><span>      ],\n<\/span><span>      <\/span><span style=\"color:#79740e;\">&quot;results&quot;<\/span><span>: [\n<\/span><span>        {\n<\/span><span>          <\/span><span style=\"color:#79740e;\">&quot;level&quot;<\/span><span>: <\/span><span style=\"color:#79740e;\">&quot;warning&quot;<\/span><span>,\n<\/span><span>          <\/span><span style=\"color:#79740e;\">&quot;message&quot;<\/span><span>: {\n<\/span><span>            <\/span><span style=\"color:#79740e;\">&quot;text&quot;<\/span><span>: <\/span><span style=\"color:#79740e;\">&quot;Method is too complex.&quot;\n<\/span><span>          },\n<\/span><span>          <\/span><span style=\"color:#79740e;\">&quot;locations&quot;<\/span><span>: [\n<\/span><span>            {\n<\/span><span>              <\/span><span style=\"color:#79740e;\">&quot;physicalLocation&quot;<\/span><span>: {\n<\/span><span>                <\/span><span style=\"color:#79740e;\">&quot;artifactLocation&quot;<\/span><span>: {\n<\/span><span>                  <\/span><span style=\"color:#79740e;\">&quot;uri&quot;<\/span><span>: <\/span><span style=\"color:#79740e;\">&quot;src\/complex.php&quot;<\/span><span>,\n<\/span><span>                  <\/span><span style=\"color:#79740e;\">&quot;index&quot;<\/span><span>: <\/span><span style=\"color:#8f3f71;\">0\n<\/span><span>                },\n<\/span><span>                <\/span><span style=\"color:#79740e;\">&quot;region&quot;<\/span><span>: {\n<\/span><span>                  <\/span><span style=\"color:#79740e;\">&quot;startLine&quot;<\/span><span>: <\/span><span style=\"color:#8f3f71;\">1<\/span><span>,\n<\/span><span>                  <\/span><span style=\"color:#79740e;\">&quot;startColumn&quot;<\/span><span>: <\/span><span style=\"color:#8f3f71;\">5\n<\/span><span>                }\n<\/span><span>              }\n<\/span><span>            }\n<\/span><span>          ],\n<\/span><span>          <\/span><span style=\"color:#79740e;\">&quot;ruleId&quot;<\/span><span>: <\/span><span style=\"color:#79740e;\">&quot;no-unused-vars&quot;<\/span><span>,\n<\/span><span>          <\/span><span style=\"color:#79740e;\">&quot;ruleIndex&quot;<\/span><span>: <\/span><span style=\"color:#8f3f71;\">0\n<\/span><span>        }\n<\/span><span>      ]\n<\/span><span>    }\n<\/span><span>  ]\n<\/span><span>}\n<\/span><\/code><\/pre>\n<p>I won\u2019t explain Sarif in detail in this article; the people behind it have already done an excellent job.<\/p>\n<p>The next step is to upload this output to Github using the <code>github\/codeql-action\/upload-sarif<\/code>.<\/p>\n<pre data-lang=\"yaml\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-yaml \"><code class=\"language-yaml\" data-lang=\"yaml\"><span style=\"color:#8f3f71;\">on<\/span><span>:\n<\/span><span>  <\/span><span style=\"font-weight:bold;color:#407959;\">push<\/span><span>:\n<\/span><span>    <\/span><span style=\"font-weight:bold;color:#407959;\">branches<\/span><span>:\n<\/span><span>      - <\/span><span style=\"color:#79740e;\">&quot;main&quot;\n<\/span><span style=\"font-weight:bold;color:#407959;\">name<\/span><span>: <\/span><span style=\"color:#79740e;\">Sarif\n<\/span><span style=\"font-weight:bold;color:#407959;\">jobs<\/span><span>:\n<\/span><span>  <\/span><span style=\"font-weight:bold;color:#407959;\">upload-sarif<\/span><span>:\n<\/span><span>    <\/span><span style=\"font-weight:bold;color:#407959;\">runs-on<\/span><span>: <\/span><span style=\"color:#79740e;\">ubuntu-latest\n<\/span><span>    <\/span><span style=\"font-weight:bold;color:#407959;\">steps<\/span><span>:\n<\/span><span>      - <\/span><span style=\"font-weight:bold;color:#407959;\">uses<\/span><span>: <\/span><span style=\"color:#79740e;\">actions\/checkout@v4\n<\/span><span>      - <\/span><span style=\"font-weight:bold;color:#407959;\">name<\/span><span>: <\/span><span style=\"color:#79740e;\">Install Rust toolchain\n<\/span><span>        <\/span><span style=\"font-weight:bold;color:#407959;\">uses<\/span><span>: <\/span><span style=\"color:#79740e;\">actions-rs\/toolchain@v1.0.6 <\/span><span style=\"font-style:italic;color:#928374;\">#@v1\n<\/span><span>        <\/span><span style=\"font-weight:bold;color:#407959;\">with<\/span><span>:\n<\/span><span>          <\/span><span style=\"font-weight:bold;color:#407959;\">profile<\/span><span>: <\/span><span style=\"color:#79740e;\">minimal\n<\/span><span>          <\/span><span style=\"font-weight:bold;color:#407959;\">toolchain<\/span><span>: <\/span><span style=\"color:#79740e;\">stable\n<\/span><span>          <\/span><span style=\"font-weight:bold;color:#407959;\">override<\/span><span>: <\/span><span style=\"color:#8f3f71;\">true\n<\/span><span>      - <\/span><span style=\"font-weight:bold;color:#407959;\">run<\/span><span>: <\/span><span style=\"color:#79740e;\">cargo run --release -- --src=. --output-format=sarif | tee results.sarif\n<\/span><span>      - <\/span><span style=\"font-weight:bold;color:#407959;\">name<\/span><span>: <\/span><span style=\"color:#79740e;\">Upload SARIF file\n<\/span><span>        <\/span><span style=\"font-weight:bold;color:#407959;\">uses<\/span><span>: <\/span><span style=\"color:#79740e;\">github\/codeql-action\/upload-sarif@v3\n<\/span><span>        <\/span><span style=\"font-weight:bold;color:#407959;\">with<\/span><span>:\n<\/span><span>          <\/span><span style=\"font-weight:bold;color:#407959;\">sarif_file<\/span><span>: <\/span><span style=\"color:#79740e;\">results.sarif\n<\/span><\/code><\/pre>\n<p>After executing this workflow, the result will be displayed in the security tab under code scanning.<\/p>\n<p><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/qmo3430915c3cossaims.png\" alt=\"Code scanning\" \/><\/p>\n<p>The rules in Phanalist also consist of detailed explanations written in Markdown, which are backed into the executable binary. This comes in very handy when scanning code. In <code>Sarif,<\/code> you can specify a Markdown for the result found when you ran your tool.<\/p>\n<p>If I click and open one of the warnings, I will be greeted with a detailed explanation. Including the file and location that is causing the issue.<\/p>\n<p><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/xj6yxra96lf87w4a0pzq.png\" alt=\"Detailed explanation\" \/><\/p>\n<p><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/75rajcv2fob5chr3xbim.png\" alt=\"Detailed explanation\" \/><\/p>\n<p>I hope you learned something useful and can now improve your CI output.<\/p>\n"},{"title":"Why using unserialize in PHP is a bad idea","published":"2020-01-01T00:00:00+00:00","updated":"2020-01-01T00:00:00+00:00","author":{"name":"\n            \n              Unknown\n            \n          "},"link":{"@attributes":{"rel":"alternate","type":"text\/html","href":"https:\/\/denzyl.io\/blog\/why-using-unserialize-php-is-a-bad-idea\/"}},"id":"https:\/\/denzyl.io\/blog\/why-using-unserialize-php-is-a-bad-idea\/","content":"<p>Serializing in PHP is a way of converting a PHP object into a string. This string can be used in various ways, such as storing it in a database or passing it to another function. The PHP documentation says this is handy when passing PHP values around without losing their type and structure. But I have never had that problem before. Maybe I\u2019m not seeing it.<\/p>\n<pre data-lang=\"php\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-php \"><code class=\"language-php\" data-lang=\"php\"><span>&lt;?php\n<\/span><span style=\"color:#282828;\">$test <\/span><span style=\"color:#b23c15;\">= <\/span><span style=\"color:#9d0006;\">new <\/span><span style=\"color:#407959;\">User<\/span><span style=\"color:#282828;\">();\n<\/span><span style=\"color:#282828;\">$test-&gt;name <\/span><span style=\"color:#b23c15;\">= <\/span><span style=\"color:#79740e;\">&quot;Denzyl&quot;<\/span><span style=\"color:#282828;\">;\n<\/span><span style=\"color:#b57614;\">echo serialize<\/span><span style=\"color:#282828;\">($test);\n<\/span><span style=\"font-style:italic;color:#928374;\">\/\/\/ Output: O:4:&quot;User&quot;:1:{s:4:&quot;name&quot;;s:6:&quot;Denzyl&quot;;}\n<\/span><\/code><\/pre>\n<p>So, let\u2019s digest the string. The <code>o<\/code> stands for Object, and the following number is the length of the object\u2019s name. The two letters  <code>s<\/code> stand for string and the length of the string\u2019s name.<br \/>\nWhen you need to convert the string back into PHP, call the <code>unserialize<\/code> function and pass the string as a parameter.<\/p>\n<p>When serializing an object, two methods are automagically being called. <code>__serialize()<\/code> &amp; <code>__sleep()<\/code>. This will allow the class author to do something before converting the object into a string.\nThat is straight to the point. But for now, let\u2019s focus on unserializing the string. This means converting the string into a real PHP object that can be later used at runtime in your PHP code.<\/p>\n<pre data-lang=\"php\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-php \"><code class=\"language-php\" data-lang=\"php\"><span>&lt;?php\n<\/span><span style=\"color:#282828;\">\n<\/span><span style=\"color:#282828;\">$string <\/span><span style=\"color:#b23c15;\">= <\/span><span style=\"color:#79740e;\">&#39;O:8:&quot;User&quot;:1:{s:4:&quot;name&quot;;s:6:&quot;Denzyl&quot;;}&#39;<\/span><span style=\"color:#282828;\">;\n<\/span><span style=\"color:#b57614;\">echo unserialize<\/span><span style=\"color:#282828;\">($string)-&gt;name;\n<\/span><span style=\"font-style:italic;color:#928374;\">\/\/\/ Output: Denzyl\n<\/span><\/code><\/pre>\n<p>The same functionalities also apply to unserializing. But this time, the two methods are <code>__unserialize()<\/code> and <code>__wakeup().<\/code><\/p>\n<h3 id=\"but-why-is-it-a-bad-idea\"><a class=\"zola-anchor\" href=\"#but-why-is-it-a-bad-idea\" aria-label=\"Anchor link for: but-why-is-it-a-bad-idea\">\ud83d\udd17<\/a>But why is it a bad idea?<\/h3>\n<p>Using <code>unserialize<\/code> without knowing it can lead to remote code execution. That\u2019s why they say never to trust input.\nLet\u2019s say you are lazy and you trust a random input, and you concatenate to the serialized object so you can\nchange a value inside the object. BOOM, you can be hacked.<\/p>\n<pre data-lang=\"php\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-php \"><code class=\"language-php\" data-lang=\"php\"><span>&lt;?php\n<\/span><span style=\"color:#282828;\">$username <\/span><span style=\"color:#b23c15;\">= <\/span><span style=\"color:#282828;\">$_GET[<\/span><span style=\"color:#79740e;\">&#39;username&#39;<\/span><span style=\"color:#282828;\">];\n<\/span><span style=\"color:#282828;\">$serialized <\/span><span style=\"color:#b23c15;\">= <\/span><span style=\"color:#79740e;\">&#39;O:8:&quot;User&quot;:1:{s:4:&quot;name&quot;;s:6:&quot;&#39; <\/span><span style=\"color:#b23c15;\">. <\/span><span style=\"color:#282828;\">$username <\/span><span style=\"color:#b23c15;\">. <\/span><span style=\"color:#79740e;\">&#39;&quot;;}&#39;<\/span><span style=\"color:#282828;\">;\n<\/span><\/code><\/pre>\n<p>I won\u2019t explain how to write an exploit for something like this. Some tools can automatically generate a payload for you, and you can call yourself a script kiddie(we all start somewhere). The one I know is <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/github.com\/ambionics\/phpggc\">PHPGGC<\/a>.<\/p>\n<p>To understand the exploit, you can read the OWASP <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/owasp.org\/www-community\/vulnerabilities\/PHP_Object_Injection\">article<\/a>.\nIf you didn\u2019t know this before, also read the rest of the OWASP <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/owasp.org\/www-community\/vulnerabilities\/\">articles<\/a> about vulnerabilities<\/p>\n<p><em>I know I haven\u2019t explained how to write an exploit. I don\u2019t think I can do a better job than the articles on the internet. But now you know this, and you can do your research.<\/em><\/p>\n<h3 id=\"how-to-prevent-being-exploited\"><a class=\"zola-anchor\" href=\"#how-to-prevent-being-exploited\" aria-label=\"Anchor link for: how-to-prevent-being-exploited\">\ud83d\udd17<\/a>How to prevent being exploited?<\/h3>\n<p>Why would you want to use this? I do not know; I haven\u2019t been programming long enough(~15 years) to have the opportunity to solve a problem using serialize\/unserialize.\nMy solution is too drastic. The simple answer is. <strong>Don\u2019t<\/strong> use it in my PHP projects.<\/p>\n<p>This article is part of a series of articles in my journey of writing a <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/github.com\/denzyldick\/phanalist\">static analysis<\/a> tool for PHP that can scan massive projects in a couple of minutes\/seconds. And look for rules\nthat the developers want to have in their projects. At the time of writing this article, I\u2019m working on a rule to stop\npeople from using <code>unserialize<\/code>, and it should be ready for the next release. Follow the <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/github.com\/denzyldick\/phanalist\">project<\/a> so that you will get notified when\nI decided to write even more rules.<\/p>\n"},{"title":"Write your own static analyzer for PHP","published":"2020-01-01T00:00:00+00:00","updated":"2020-01-01T00:00:00+00:00","author":{"name":"\n            \n              Unknown\n            \n          "},"link":{"@attributes":{"rel":"alternate","type":"text\/html","href":"https:\/\/denzyl.io\/blog\/write-your-own-static-analyzer-for-php\/"}},"id":"https:\/\/denzyl.io\/blog\/write-your-own-static-analyzer-for-php\/","content":"<p>I keep reading everywhere that rust is fast, has memory safety guardrails, and is 1 of the most loved languages lately. After reading the book and dreaming about understanding the language, I decided to build a static analyzer for the language I\u2019ve been using for over a decade. I will be naming it <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/github.com\/denzyldick\/phanalist\">Phanalist<\/a> and the code will also be available on\n<a href=\"https:\/\/denzyl.io\/blog\/write-your-own-static-analyzer-for-php\/github\">https:\/\/github.com\/denzyldick\/phanalist<\/a>.<\/p>\n<p>To see if this idea would work, I made a list of 4 common bad practices\/mistakes I often see. As you can see in the code below, we can all agree that the class doesn\u2019t make you happy.<\/p>\n<pre data-lang=\"php\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-php \"><code class=\"language-php\" data-lang=\"php\"><span> &lt;?php\n<\/span><span style=\"color:#282828;\">\n<\/span><span style=\"color:#282828;\"> <\/span><span style=\"color:#9d0006;\">class <\/span><span style=\"color:#407959;\">uTesting <\/span><span style=\"color:#9d0006;\">extends <\/span><span style=\"color:#407959;\">FakeClass\n<\/span><span style=\"color:#282828;\">  {\n<\/span><span style=\"color:#282828;\">    <\/span><span style=\"color:#9d0006;\">const <\/span><span style=\"color:#282828;\">I_ <\/span><span style=\"color:#b23c15;\">= <\/span><span style=\"color:#8f3f71;\">null<\/span><span style=\"color:#282828;\">;\n<\/span><span style=\"color:#282828;\">    <\/span><span style=\"color:#9d0006;\">const <\/span><span style=\"color:#282828;\">hello <\/span><span style=\"color:#b23c15;\">= <\/span><span style=\"color:#8f3f71;\">null<\/span><span style=\"color:#282828;\">;\n<\/span><span style=\"color:#282828;\">    $no_<\/span><span style=\"color:#b23c15;\">= <\/span><span style=\"color:#8f3f71;\">null<\/span><span style=\"color:#282828;\">, $no_modifier <\/span><span style=\"color:#b23c15;\">= <\/span><span style=\"color:#8f3f71;\">null<\/span><span style=\"color:#282828;\">;\n<\/span><span style=\"color:#282828;\">\n<\/span><span style=\"color:#282828;\">    <\/span><span style=\"color:#9d0006;\">public function <\/span><span style=\"color:#b57614;\">__construct<\/span><span style=\"color:#282828;\">($o)\n<\/span><span style=\"color:#282828;\">    {\n<\/span><span style=\"color:#282828;\">      $this-&gt;fake_variable <\/span><span style=\"color:#b23c15;\">= <\/span><span style=\"color:#79740e;\">&#39;hellworld&#39;<\/span><span style=\"color:#282828;\">;\n<\/span><span style=\"color:#282828;\">    }\n<\/span><span style=\"color:#282828;\">\n<\/span><span style=\"color:#282828;\">    <\/span><span style=\"color:#9d0006;\">function <\/span><span style=\"color:#407959;\">test<\/span><span style=\"color:#282828;\">($a){\n<\/span><span style=\"color:#282828;\">      <\/span><span style=\"color:#9d0006;\">return <\/span><span style=\"color:#8f3f71;\">1<\/span><span style=\"color:#282828;\">;\n<\/span><span style=\"color:#282828;\">    }\n<\/span><span style=\"color:#282828;\">  }\n<\/span><\/code><\/pre>\n<p>To keep it easy, I will first find these four common mistakes that are easy to spot. This list will continue to grow in the future.<\/p>\n<ul>\n<li>Misplaced opening tag.<\/li>\n<li>Class name that starts in lowercase<\/li>\n<li>Lowercase constants<\/li>\n<li>Defining parameters without a type.<\/li>\n<\/ul>\n<p>The static analyzer should be beginner friendly. Instead of making the developer\u2019s life harder, it should be able to explain the error in a way that the developer should understand. But first, let us focus on the first steps.<\/p>\n<p>I will use <code>PHP-Parser<\/code> a rust library that can parse PHP code and generate an AST(abstract syntax tree). The parser\u2019s output for the PHP code above will be a vector(<code>Vec&lt;Statement<\/code>) containing all the statements.<\/p>\n<pre data-lang=\"rust\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-rust \"><code class=\"language-rust\" data-lang=\"rust\"><span>   [\n<\/span><span>    FullOpeningTag(\n<\/span><span>        Span {\n<\/span><span>            line: <\/span><span style=\"color:#8f3f71;\">1<\/span><span>,\n<\/span><span>            column: <\/span><span style=\"color:#8f3f71;\">1<\/span><span>,\n<\/span><span>            position: <\/span><span style=\"color:#8f3f71;\">0<\/span><span>,\n<\/span><span>        },\n<\/span><span>    ),\n<\/span><span>    Class(\n<\/span><span>        ClassStatement {\n<\/span><span>            attributes: [],\n<\/span><span>            modifiers: ClassModifierGroup {\n<\/span><span>                modifiers: [],\n<\/span><span>            },\n<\/span><span>            class: Span {\n<\/span><span>                line: <\/span><span style=\"color:#8f3f71;\">2<\/span><span>,\n<\/span><span>                column: <\/span><span style=\"color:#8f3f71;\">2<\/span><span>,\n<\/span><span>                position: <\/span><span style=\"color:#8f3f71;\">7<\/span><span>,\n<\/span><span>            },\n<\/span><span>            name: SimpleIdentifier {\n<\/span><span>                span: Span {\n<\/span><span>                    line: <\/span><span style=\"color:#8f3f71;\">2<\/span><span>,\n<\/span><span>                    column: <\/span><span style=\"color:#8f3f71;\">8<\/span><span>,\n<\/span><span>                    position: <\/span><span style=\"color:#8f3f71;\">13<\/span><span>,\n<\/span><span>                },\n<\/span><span>                value: <\/span><span style=\"color:#79740e;\">&quot;uTesting&quot;<\/span><span>,\n<\/span><span>            },\n<\/span><span>            extends: <\/span><span style=\"color:#b57614;\">Some<\/span><span>(\n<\/span><span>                ClassExtends {\n<\/span><span>                    extends: Span {\n<\/span><span>                        line: <\/span><span style=\"color:#8f3f71;\">2<\/span><span>,\n<\/span><span>                        column: <\/span><span style=\"color:#8f3f71;\">17<\/span><span>,\n<\/span><span>                        position: <\/span><span style=\"color:#8f3f71;\">22<\/span><span>,\n<\/span><span>                    },\n<\/span><span>                    parent: SimpleIdentifier {\n<\/span><span>                        span: Span {\n<\/span><span>                            line: <\/span><span style=\"color:#8f3f71;\">2<\/span><span>,\n<\/span><span>                            column: <\/span><span style=\"color:#8f3f71;\">25<\/span><span>,\n<\/span><span>                            position: <\/span><span style=\"color:#8f3f71;\">30<\/span><span>,\n<\/span><span>                        },\n<\/span><span>                        value: <\/span><span style=\"color:#79740e;\">&quot;FakeClass&quot;<\/span><span>,\n<\/span><span>                    },\n<\/span><span>                },\n<\/span><span>            ),\n<\/span><span>            implements: <\/span><span style=\"color:#b57614;\">None<\/span><span>,\n<\/span><span>            body: ClassBody {\n<\/span><span>                left_brace: Span {\n<\/span><span>                    line: <\/span><span style=\"color:#8f3f71;\">3<\/span><span>,\n<\/span><span>                    column: <\/span><span style=\"color:#8f3f71;\">3<\/span><span>,\n<\/span><span>                    position: <\/span><span style=\"color:#8f3f71;\">42<\/span><span>,\n<\/span><span>                },\n<\/span><span>                members: [\n<\/span><span>                    Constant(\n<\/span><span>                        ClassishConstant {\n<\/span><span>                            comments: CommentGroup {\n<\/span><span>                                comments: [],\n<\/span><span>                            },\n<\/span><span>                            attributes: [],\n<\/span><span>                            modifiers: ConstantModifierGroup {\n<\/span><span>                                modifiers: [],\n<\/span><span>                            },\n<\/span><span>                            <\/span><span style=\"color:#9d0006;\">const<\/span><span>: Span {\n<\/span><span>                                line: <\/span><span style=\"color:#8f3f71;\">4<\/span><span>,\n<\/span><span>                                column: <\/span><span style=\"color:#8f3f71;\">5<\/span><span>,\n<\/span><span>                                position: <\/span><span style=\"color:#8f3f71;\">48<\/span><span>,\n<\/span><span>                            },\n<\/span><span>                            entries: [\n<\/span><span>                                ConstantEntry {\n<\/span><span>                                    name: SimpleIdentifier {\n<\/span><span>                                        span: Span {\n<\/span><span>                                            line: <\/span><span style=\"color:#8f3f71;\">4<\/span><span>,\n<\/span><span>                                            column: <\/span><span style=\"color:#8f3f71;\">11<\/span><span>,\n<\/span><span>                                            position: <\/span><span style=\"color:#8f3f71;\">54<\/span><span>,\n<\/span><span>                                        },\n<\/span><span>                                        value: <\/span><span style=\"color:#79740e;\">&quot;I_&quot;<\/span><span>,\n<\/span><span>                                    },\n<\/span><span>                                    equals: Span {\n<\/span><span>                                        line: <\/span><span style=\"color:#8f3f71;\">4<\/span><span>,\n<\/span><span>                                        column: <\/span><span style=\"color:#8f3f71;\">14<\/span><span>,\n<\/span><span>                                        position: <\/span><span style=\"color:#8f3f71;\">57<\/span><span>,\n<\/span><span>                                    },\n<\/span><span>                                    value: Null,\n<\/span><span>                                },\n<\/span><span>                            ],\n<\/span><span>                            semicolon: Span {\n<\/span><span>                                line: <\/span><span style=\"color:#8f3f71;\">4<\/span><span>,\n<\/span><span>                                column: <\/span><span style=\"color:#8f3f71;\">20<\/span><span>,\n<\/span><span>                                position: <\/span><span style=\"color:#8f3f71;\">63<\/span><span>,\n<\/span><span>                            },\n<\/span><span>                        },\n<\/span><span>                    ),\n<\/span><span>                    Constant(\n<\/span><span>                        ClassishConstant {\n<\/span><span>                            comments: CommentGroup {\n<\/span><span>                                comments: [],\n<\/span><span>                            },\n<\/span><span>                            attributes: [],\n<\/span><span>                            modifiers: ConstantModifierGroup {\n<\/span><span>                                modifiers: [],\n<\/span><span>                            },\n<\/span><span>                            <\/span><span style=\"color:#9d0006;\">const<\/span><span>: Span {\n<\/span><span>                                line: <\/span><span style=\"color:#8f3f71;\">5<\/span><span>,\n<\/span><span>                                column: <\/span><span style=\"color:#8f3f71;\">5<\/span><span>,\n<\/span><span>                                position: <\/span><span style=\"color:#8f3f71;\">69<\/span><span>,\n<\/span><span>                            },\n<\/span><span>                            entries: [\n<\/span><span>                                ConstantEntry {\n<\/span><span>                                    name: SimpleIdentifier {\n<\/span><span>                                        span: Span {\n<\/span><span>                                            line: <\/span><span style=\"color:#8f3f71;\">5<\/span><span>,\n<\/span><span>                                            column: <\/span><span style=\"color:#8f3f71;\">11<\/span><span>,\n<\/span><span>                                            position: <\/span><span style=\"color:#8f3f71;\">75<\/span><span>,\n<\/span><span>                                        },\n<\/span><span>                                        value: <\/span><span style=\"color:#79740e;\">&quot;hello&quot;<\/span><span>,\n<\/span><span>                                    },\n<\/span><span>                                    equals: Span {\n<\/span><span>                                        line: <\/span><span style=\"color:#8f3f71;\">5<\/span><span>,\n<\/span><span>                                        column: <\/span><span style=\"color:#8f3f71;\">17<\/span><span>,\n<\/span><span>                                        position: <\/span><span style=\"color:#8f3f71;\">81<\/span><span>,\n<\/span><span>                                    },\n<\/span><span>                                    value: Null,\n<\/span><span>                                },\n<\/span><span>                            ],\n<\/span><span>                            semicolon: Span {\n<\/span><span>                                line: <\/span><span style=\"color:#8f3f71;\">5<\/span><span>,\n<\/span><span>                                column: <\/span><span style=\"color:#8f3f71;\">23<\/span><span>,\n<\/span><span>                                position: <\/span><span style=\"color:#8f3f71;\">87<\/span><span>,\n<\/span><span>                            },\n<\/span><span>                        },\n<\/span><span>                    ),\n<\/span><span>                    Property(\n<\/span><span>                        Property {\n<\/span><span>                            attributes: [],\n<\/span><span>                            modifiers: PropertyModifierGroup {\n<\/span><span>                                modifiers: [],\n<\/span><span>                            },\n<\/span><span>                            <\/span><span style=\"color:#9d0006;\">type<\/span><span>: <\/span><span style=\"color:#b57614;\">None<\/span><span>,\n<\/span><span>                            entries: [\n<\/span><span>                                Initialized {\n<\/span><span>                                    variable: SimpleVariable {\n<\/span><span>                                        span: Span {\n<\/span><span>                                            line: <\/span><span style=\"color:#8f3f71;\">6<\/span><span>,\n<\/span><span>                                            column: <\/span><span style=\"color:#8f3f71;\">5<\/span><span>,\n<\/span><span>                                            position: <\/span><span style=\"color:#8f3f71;\">93<\/span><span>,\n<\/span><span>                                        },\n<\/span><span>                                        name: <\/span><span style=\"color:#79740e;\">&quot;$no_&quot;<\/span><span>,\n<\/span><span>                                    },\n<\/span><span>                                    equals: Span {\n<\/span><span>                                        line: <\/span><span style=\"color:#8f3f71;\">6<\/span><span>,\n<\/span><span>                                        column: <\/span><span style=\"color:#8f3f71;\">9<\/span><span>,\n<\/span><span>                                        position: <\/span><span style=\"color:#8f3f71;\">97<\/span><span>,\n<\/span><span>                                    },\n<\/span><span>                                    value: Null,\n<\/span><span>                                },\n<\/span><span>                                Initialized {\n<\/span><span>                                    variable: SimpleVariable {\n<\/span><span>                                        span: Span {\n<\/span><span>                                            line: <\/span><span style=\"color:#8f3f71;\">6<\/span><span>,\n<\/span><span>                                            column: <\/span><span style=\"color:#8f3f71;\">17<\/span><span>,\n<\/span><span>                                            position: <\/span><span style=\"color:#8f3f71;\">105<\/span><span>,\n<\/span><span>                                        },\n<\/span><span>                                        name: <\/span><span style=\"color:#79740e;\">&quot;$no_modifier&quot;<\/span><span>,\n<\/span><span>                                    },\n<\/span><span>                                    equals: Span {\n<\/span><span>                                        line: <\/span><span style=\"color:#8f3f71;\">6<\/span><span>,\n<\/span><span>                                        column: <\/span><span style=\"color:#8f3f71;\">30<\/span><span>,\n<\/span><span>                                        position: <\/span><span style=\"color:#8f3f71;\">118<\/span><span>,\n<\/span><span>                                    },\n<\/span><span>                                    value: Null,\n<\/span><span>                                },\n<\/span><span>                            ],\n<\/span><span>                            end: Span {\n<\/span><span>                                line: <\/span><span style=\"color:#8f3f71;\">6<\/span><span>,\n<\/span><span>                                column: <\/span><span style=\"color:#8f3f71;\">36<\/span><span>,\n<\/span><span>                                position: <\/span><span style=\"color:#8f3f71;\">124<\/span><span>,\n<\/span><span>                            },\n<\/span><span>                        },\n<\/span><span>                    ),\n<\/span><span>                    ConcreteConstructor(\n<\/span><span>                        ConcreteConstructor {\n<\/span><span>                            comments: CommentGroup {\n<\/span><span>                                comments: [],\n<\/span><span>                            },\n<\/span><span>                            attributes: [],\n<\/span><span>                            modifiers: MethodModifierGroup {\n<\/span><span>                                modifiers: [\n<\/span><span>                                    Public(\n<\/span><span>                                        Span {\n<\/span><span>                                            line: <\/span><span style=\"color:#8f3f71;\">8<\/span><span>,\n<\/span><span>                                            column: <\/span><span style=\"color:#8f3f71;\">5<\/span><span>,\n<\/span><span>                                            position: <\/span><span style=\"color:#8f3f71;\">131<\/span><span>,\n<\/span><span>                                        },\n<\/span><span>                                    ),\n<\/span><span>                                ],\n<\/span><span>                            },\n<\/span><span>                            function: Span {\n<\/span><span>                                line: <\/span><span style=\"color:#8f3f71;\">8<\/span><span>,\n<\/span><span>                                column: <\/span><span style=\"color:#8f3f71;\">12<\/span><span>,\n<\/span><span>                                position: <\/span><span style=\"color:#8f3f71;\">138<\/span><span>,\n<\/span><span>                            },\n<\/span><span>                            ampersand: <\/span><span style=\"color:#b57614;\">None<\/span><span>,\n<\/span><span>                            name: SimpleIdentifier {\n<\/span><span>                                span: Span {\n<\/span><span>                                    line: <\/span><span style=\"color:#8f3f71;\">8<\/span><span>,\n<\/span><span>                                    column: <\/span><span style=\"color:#8f3f71;\">21<\/span><span>,\n<\/span><span>                                    position: <\/span><span style=\"color:#8f3f71;\">147<\/span><span>,\n<\/span><span>                                },\n<\/span><span>                                value: <\/span><span style=\"color:#79740e;\">&quot;__construct&quot;<\/span><span>,\n<\/span><span>                            },\n<\/span><span>                            parameters: ConstructorParameterList {\n<\/span><span>                                comments: CommentGroup {\n<\/span><span>                                    comments: [],\n<\/span><span>                                },\n<\/span><span>                                left_parenthesis: Span {\n<\/span><span>                                    line: <\/span><span style=\"color:#8f3f71;\">8<\/span><span>,\n<\/span><span>                                    column: <\/span><span style=\"color:#8f3f71;\">32<\/span><span>,\n<\/span><span>                                    position: <\/span><span style=\"color:#8f3f71;\">158<\/span><span>,\n<\/span><span>                                },\n<\/span><span>                                parameters: CommaSeparated {\n<\/span><span>                                    inner: [\n<\/span><span>                                        ConstructorParameter {\n<\/span><span>                                            attributes: [],\n<\/span><span>                                            comments: CommentGroup {\n<\/span><span>                                                comments: [],\n<\/span><span>                                            },\n<\/span><span>                                            ampersand: <\/span><span style=\"color:#b57614;\">None<\/span><span>,\n<\/span><span>                                            name: SimpleVariable {\n<\/span><span>                                                span: Span {\n<\/span><span>                                                    line: <\/span><span style=\"color:#8f3f71;\">8<\/span><span>,\n<\/span><span>                                                    column: <\/span><span style=\"color:#8f3f71;\">33<\/span><span>,\n<\/span><span>                                                    position: <\/span><span style=\"color:#8f3f71;\">159<\/span><span>,\n<\/span><span>                                                },\n<\/span><span>                                                name: <\/span><span style=\"color:#79740e;\">&quot;$o&quot;<\/span><span>,\n<\/span><span>                                            },\n<\/span><span>                                            data_type: <\/span><span style=\"color:#b57614;\">None<\/span><span>,\n<\/span><span>                                            ellipsis: <\/span><span style=\"color:#b57614;\">None<\/span><span>,\n<\/span><span>                                            default: <\/span><span style=\"color:#b57614;\">None<\/span><span>,\n<\/span><span>                                            modifiers: PromotedPropertyModifierGroup {\n<\/span><span>                                                modifiers: [],\n<\/span><span>                                            },\n<\/span><span>                                        },\n<\/span><span>                                    ],\n<\/span><span>                                    commas: [],\n<\/span><span>                                },\n<\/span><span>                                right_parenthesis: Span {\n<\/span><span>                                    line: <\/span><span style=\"color:#8f3f71;\">8<\/span><span>,\n<\/span><span>                                    column: <\/span><span style=\"color:#8f3f71;\">35<\/span><span>,\n<\/span><span>                                    position: <\/span><span style=\"color:#8f3f71;\">161<\/span><span>,\n<\/span><span>                                },\n<\/span><span>                            },\n<\/span><span>                            body: MethodBody {\n<\/span><span>                                comments: CommentGroup {\n<\/span><span>                                    comments: [],\n<\/span><span>                                },\n<\/span><span>                                left_brace: Span {\n<\/span><span>                                    line: <\/span><span style=\"color:#8f3f71;\">9<\/span><span>,\n<\/span><span>                                    column: <\/span><span style=\"color:#8f3f71;\">5<\/span><span>,\n<\/span><span>                                    position: <\/span><span style=\"color:#8f3f71;\">167<\/span><span>,\n<\/span><span>                                },\n<\/span><span>                                statements: [\n<\/span><span>                                    Expression(\n<\/span><span>                                        ExpressionStatement {\n<\/span><span>                                            expression: AssignmentOperation(\n<\/span><span>                                                Assign {\n<\/span><span>                                                    left: PropertyFetch {\n<\/span><span>                                                        target: Variable(\n<\/span><span>                                                            SimpleVariable(\n<\/span><span>                                                                SimpleVariable {\n<\/span><span>                                                                    span: Span {\n<\/span><span>                                                                        line: <\/span><span style=\"color:#8f3f71;\">10<\/span><span>,\n<\/span><span>                                                                        column: <\/span><span style=\"color:#8f3f71;\">7<\/span><span>,\n<\/span><span>                                                                        position: <\/span><span style=\"color:#8f3f71;\">175<\/span><span>,\n<\/span><span>                                                                    },\n<\/span><span>                                                                    name: <\/span><span style=\"color:#79740e;\">&quot;$this&quot;<\/span><span>,\n<\/span><span>                                                                },\n<\/span><span>                                                            ),\n<\/span><span>                                                        ),\n<\/span><span>                                                        arrow: Span {\n<\/span><span>                                                            line: <\/span><span style=\"color:#8f3f71;\">10<\/span><span>,\n<\/span><span>                                                            column: <\/span><span style=\"color:#8f3f71;\">12<\/span><span>,\n<\/span><span>                                                            position: <\/span><span style=\"color:#8f3f71;\">180<\/span><span>,\n<\/span><span>                                                        },\n<\/span><span>                                                        property: Identifier(\n<\/span><span>                                                            SimpleIdentifier(\n<\/span><span>                                                                SimpleIdentifier {\n<\/span><span>                                                                    span: Span {\n<\/span><span>                                                                        line: <\/span><span style=\"color:#8f3f71;\">10<\/span><span>,\n<\/span><span>                                                                        column: <\/span><span style=\"color:#8f3f71;\">14<\/span><span>,\n<\/span><span>                                                                        position: <\/span><span style=\"color:#8f3f71;\">182<\/span><span>,\n<\/span><span>                                                                    },\n<\/span><span>                                                                    value: <\/span><span style=\"color:#79740e;\">&quot;fake_variable&quot;<\/span><span>,\n<\/span><span>                                                                },\n<\/span><span>                                                            ),\n<\/span><span>                                                        ),\n<\/span><span>                                                    },\n<\/span><span>                                                    equals: Span {\n<\/span><span>                                                        line: <\/span><span style=\"color:#8f3f71;\">10<\/span><span>,\n<\/span><span>                                                        column: <\/span><span style=\"color:#8f3f71;\">28<\/span><span>,\n<\/span><span>                                                        position: <\/span><span style=\"color:#8f3f71;\">196<\/span><span>,\n<\/span><span>                                                    },\n<\/span><span>                                                    right: Literal(\n<\/span><span>                                                        <\/span><span style=\"color:#b57614;\">String<\/span><span>(\n<\/span><span>                                                            LiteralString {\n<\/span><span>                                                                value: <\/span><span style=\"color:#79740e;\">&quot;&#39;hellworld&#39;&quot;<\/span><span>,\n<\/span><span>                                                                span: Span {\n<\/span><span>                                                                    line: <\/span><span style=\"color:#8f3f71;\">10<\/span><span>,\n<\/span><span>                                                                    column: <\/span><span style=\"color:#8f3f71;\">30<\/span><span>,\n<\/span><span>                                                                    position: <\/span><span style=\"color:#8f3f71;\">198<\/span><span>,\n<\/span><span>                                                                },\n<\/span><span>                                                            },\n<\/span><span>                                                        ),\n<\/span><span>                                                    ),\n<\/span><span>                                                },\n<\/span><span>                                            ),\n<\/span><span>                                            ending: Semicolon(\n<\/span><span>                                                Span {\n<\/span><span>                                                    line: <\/span><span style=\"color:#8f3f71;\">10<\/span><span>,\n<\/span><span>                                                    column: <\/span><span style=\"color:#8f3f71;\">41<\/span><span>,\n<\/span><span>                                                    position: <\/span><span style=\"color:#8f3f71;\">209<\/span><span>,\n<\/span><span>                                                },\n<\/span><span>                                            ),\n<\/span><span>                                        },\n<\/span><span>                                    ),\n<\/span><span>                                ],\n<\/span><span>                                right_brace: Span {\n<\/span><span>                                    line: <\/span><span style=\"color:#8f3f71;\">11<\/span><span>,\n<\/span><span>                                    column: <\/span><span style=\"color:#8f3f71;\">5<\/span><span>,\n<\/span><span>                                    position: <\/span><span style=\"color:#8f3f71;\">215<\/span><span>,\n<\/span><span>                                },\n<\/span><span>                            },\n<\/span><span>                        },\n<\/span><span>                    ),\n<\/span><span>                    ConcreteMethod(\n<\/span><span>                        ConcreteMethod {\n<\/span><span>                            comments: CommentGroup {\n<\/span><span>                                comments: [],\n<\/span><span>                            },\n<\/span><span>                            attributes: [],\n<\/span><span>                            modifiers: MethodModifierGroup {\n<\/span><span>                                modifiers: [],\n<\/span><span>                            },\n<\/span><span>                            function: Span {\n<\/span><span>                                line: <\/span><span style=\"color:#8f3f71;\">13<\/span><span>,\n<\/span><span>                                column: <\/span><span style=\"color:#8f3f71;\">5<\/span><span>,\n<\/span><span>                                position: <\/span><span style=\"color:#8f3f71;\">222<\/span><span>,\n<\/span><span>                            },\n<\/span><span>                            ampersand: <\/span><span style=\"color:#b57614;\">None<\/span><span>,\n<\/span><span>                            name: SimpleIdentifier {\n<\/span><span>                                span: Span {\n<\/span><span>                                    line: <\/span><span style=\"color:#8f3f71;\">13<\/span><span>,\n<\/span><span>                                    column: <\/span><span style=\"color:#8f3f71;\">14<\/span><span>,\n<\/span><span>                                    position: <\/span><span style=\"color:#8f3f71;\">231<\/span><span>,\n<\/span><span>                                },\n<\/span><span>                                value: <\/span><span style=\"color:#79740e;\">&quot;test&quot;<\/span><span>,\n<\/span><span>                            },\n<\/span><span>                            parameters: FunctionParameterList {\n<\/span><span>                                comments: CommentGroup {\n<\/span><span>                                    comments: [],\n<\/span><span>                                },\n<\/span><span>                                left_parenthesis: Span {\n<\/span><span>                                    line: <\/span><span style=\"color:#8f3f71;\">13<\/span><span>,\n<\/span><span>                                    column: <\/span><span style=\"color:#8f3f71;\">18<\/span><span>,\n<\/span><span>                                    position: <\/span><span style=\"color:#8f3f71;\">235<\/span><span>,\n<\/span><span>                                },\n<\/span><span>                                parameters: CommaSeparated {\n<\/span><span>                                    inner: [\n<\/span><span>                                        FunctionParameter {\n<\/span><span>                                            comments: CommentGroup {\n<\/span><span>                                                comments: [],\n<\/span><span>                                            },\n<\/span><span>                                            name: SimpleVariable {\n<\/span><span>                                                span: Span {\n<\/span><span>                                                    line: <\/span><span style=\"color:#8f3f71;\">13<\/span><span>,\n<\/span><span>                                                    column: <\/span><span style=\"color:#8f3f71;\">19<\/span><span>,\n<\/span><span>                                                    position: <\/span><span style=\"color:#8f3f71;\">236<\/span><span>,\n<\/span><span>                                                },\n<\/span><span>                                                name: <\/span><span style=\"color:#79740e;\">&quot;$a&quot;<\/span><span>,\n<\/span><span>                                            },\n<\/span><span>                                            attributes: [],\n<\/span><span>                                            data_type: <\/span><span style=\"color:#b57614;\">None<\/span><span>,\n<\/span><span>                                            ellipsis: <\/span><span style=\"color:#b57614;\">None<\/span><span>,\n<\/span><span>                                            default: <\/span><span style=\"color:#b57614;\">None<\/span><span>,\n<\/span><span>                                            ampersand: <\/span><span style=\"color:#b57614;\">None<\/span><span>,\n<\/span><span>                                        },\n<\/span><span>                                    ],\n<\/span><span>                                    commas: [],\n<\/span><span>                                },\n<\/span><span>                                right_parenthesis: Span {\n<\/span><span>                                    line: <\/span><span style=\"color:#8f3f71;\">13<\/span><span>,\n<\/span><span>                                    column: <\/span><span style=\"color:#8f3f71;\">21<\/span><span>,\n<\/span><span>                                    position: <\/span><span style=\"color:#8f3f71;\">238<\/span><span>,\n<\/span><span>                                },\n<\/span><span>                            },\n<\/span><span>                            return_type: <\/span><span style=\"color:#b57614;\">None<\/span><span>,\n<\/span><span>                            body: MethodBody {\n<\/span><span>                                comments: CommentGroup {\n<\/span><span>                                    comments: [],\n<\/span><span>                                },\n<\/span><span>                                left_brace: Span {\n<\/span><span>                                    line: <\/span><span style=\"color:#8f3f71;\">13<\/span><span>,\n<\/span><span>                                    column: <\/span><span style=\"color:#8f3f71;\">22<\/span><span>,\n<\/span><span>                                    position: <\/span><span style=\"color:#8f3f71;\">239<\/span><span>,\n<\/span><span>                                },\n<\/span><span>                                statements: [\n<\/span><span>                                    Return(\n<\/span><span>                                        ReturnStatement {\n<\/span><span>                                            <\/span><span style=\"color:#9d0006;\">return<\/span><span>: Span {\n<\/span><span>                                                line: <\/span><span style=\"color:#8f3f71;\">14<\/span><span>,\n<\/span><span>                                                column: <\/span><span style=\"color:#8f3f71;\">7<\/span><span>,\n<\/span><span>                                                position: <\/span><span style=\"color:#8f3f71;\">247<\/span><span>,\n<\/span><span>                                            },\n<\/span><span>                                            value: <\/span><span style=\"color:#b57614;\">Some<\/span><span>(\n<\/span><span>                                                Literal(\n<\/span><span>                                                    Integer(\n<\/span><span>                                                        LiteralInteger {\n<\/span><span>                                                            value: <\/span><span style=\"color:#79740e;\">&quot;1&quot;<\/span><span>,\n<\/span><span>                                                            span: Span {\n<\/span><span>                                                                line: <\/span><span style=\"color:#8f3f71;\">14<\/span><span>,\n<\/span><span>                                                                column: <\/span><span style=\"color:#8f3f71;\">14<\/span><span>,\n<\/span><span>                                                                position: <\/span><span style=\"color:#8f3f71;\">254<\/span><span>,\n<\/span><span>                                                            },\n<\/span><span>                                                        },\n<\/span><span>                                                    ),\n<\/span><span>                                                ),\n<\/span><span>                                            ),\n<\/span><span>                                            ending: Semicolon(\n<\/span><span>                                                Span {\n<\/span><span>                                                    line: <\/span><span style=\"color:#8f3f71;\">14<\/span><span>,\n<\/span><span>                                                    column: <\/span><span style=\"color:#8f3f71;\">15<\/span><span>,\n<\/span><span>                                                    position: <\/span><span style=\"color:#8f3f71;\">255<\/span><span>,\n<\/span><span>                                                },\n<\/span><span>                                            ),\n<\/span><span>                                        },\n<\/span><span>                                    ),\n<\/span><span>                                ],\n<\/span><span>                                right_brace: Span {\n<\/span><span>                                    line: <\/span><span style=\"color:#8f3f71;\">15<\/span><span>,\n<\/span><span>                                    column: <\/span><span style=\"color:#8f3f71;\">5<\/span><span>,\n<\/span><span>                                    position: <\/span><span style=\"color:#8f3f71;\">261<\/span><span>,\n<\/span><span>                                },\n<\/span><span>                            },\n<\/span><span>                        },\n<\/span><span>                    ),\n<\/span><span>                ],\n<\/span><span>                right_brace: Span {\n<\/span><span>                    line: <\/span><span style=\"color:#8f3f71;\">17<\/span><span>,\n<\/span><span>                    column: <\/span><span style=\"color:#8f3f71;\">3<\/span><span>,\n<\/span><span>                    position: <\/span><span style=\"color:#8f3f71;\">266<\/span><span>,\n<\/span><span>                },\n<\/span><span>            },\n<\/span><span>        },\n<\/span><span>    ),\n<\/span><span>]\n<\/span><\/code><\/pre>\n<p>We will be finding the four common mistakes I defined before by navigating the tree. Let\u2019s start with finding the first mistake:<\/p>\n<pre data-lang=\"php\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-php \"><code class=\"language-php\" data-lang=\"php\"><span> &lt;?php\n<\/span><\/code><\/pre>\n<p>According to the PSR-2 coding standard, the PHP opening tag should always be at the beginning of the file. When you don\u2019t\ndo this, the white space will be sent to the client before executing your PHP code. Resulting in the <code>header already sent<\/code> error. This mistake will be easy to find in the AST. We can iterate through the items in the vector and use pattern matching to find the <code>FullOpeningTag<\/code> statement.<\/p>\n<pre data-lang=\"rust\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-rust \"><code class=\"language-rust\" data-lang=\"rust\"><span>  <\/span><span style=\"color:#9d0006;\">for<\/span><span> statement <\/span><span style=\"color:#b23c15;\">in<\/span><span> statements {\n<\/span><span>        <\/span><span style=\"color:#9d0006;\">match<\/span><span> statement {\n<\/span><span>            Statement::FullOpeningTag(tag) <\/span><span style=\"color:#b23c15;\">=&gt;<\/span><span>  project.<\/span><span style=\"color:#b57614;\">opening_tag<\/span><span>(tag.span, file),\n<\/span><span>        }\n<\/span><span>    }\n<\/span><\/code><\/pre>\n<p>As you can see in the AST, the information we need is stored in the struct <code>Span<\/code>.<\/p>\n<pre style=\"background-color:#fcf0ca;color:#282828aa;\"><code><span> FullOpeningTag(\n<\/span><span>        Span {\n<\/span><span>            line: 1,\n<\/span><span>            column: 1,\n<\/span><span>            position: 0,\n<\/span><span>        },\n<\/span><span>    ),\n<\/span><\/code><\/pre>\n<p>We only need to check if the field line and column are higher than 0. If they are, it means the opening tag is not in the correct position, and we will <code>push<\/code> a suggestion into the field <code>suggestion<\/code> of the <code>file<\/code> parameter that is being passed to the <code>opening_tag<\/code> function.<\/p>\n<pre data-lang=\"rust\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-rust \"><code class=\"language-rust\" data-lang=\"rust\"><span> <\/span><span style=\"color:#9d0006;\">pub fn <\/span><span style=\"color:#407959;\">opening_tag<\/span><span>(<\/span><span style=\"color:#b23c15;\">&amp;<\/span><span style=\"color:#9d0006;\">mut <\/span><span style=\"color:#282828;\">self<\/span><span>, <\/span><span style=\"color:#282828;\">span<\/span><span>: Span, <\/span><span style=\"color:#282828;\">file<\/span><span>: <\/span><span style=\"color:#b23c15;\">&amp;<\/span><span style=\"color:#9d0006;\">mut<\/span><span> File) -&gt; <\/span><span style=\"color:#b23c15;\">&amp;<\/span><span style=\"color:#9d0006;\">mut<\/span><span> Project {\n<\/span><span>        <\/span><span style=\"color:#9d0006;\">if<\/span><span> span.line <\/span><span style=\"color:#b23c15;\">&gt; <\/span><span style=\"color:#8f3f71;\">1 <\/span><span>{\n<\/span><span>            file.suggestions.<\/span><span style=\"color:#b57614;\">push<\/span><span>(\n<\/span><span>                Suggestion::from(\n<\/span><span>                    <\/span><span style=\"color:#79740e;\">&quot;The opening tag &lt;?php is not on the right line. This should always be the first line in a PHP file.&quot;<\/span><span>.<\/span><span style=\"color:#b57614;\">to_string<\/span><span>(),\n<\/span><span>                    span\n<\/span><span>                ))\n<\/span><span>        }\n<\/span><span>\n<\/span><span>        <\/span><span style=\"color:#9d0006;\">if<\/span><span> span.column <\/span><span style=\"color:#b23c15;\">&gt; <\/span><span style=\"color:#8f3f71;\">1 <\/span><span>{\n<\/span><span>            file.suggestions.<\/span><span style=\"color:#b57614;\">push<\/span><span>(Suggestion::from(\n<\/span><span>                <\/span><span style=\"color:#b57614;\">format!<\/span><span>(\n<\/span><span>                    <\/span><span style=\"color:#79740e;\">&quot;The opening tag doesn&#39;t start at the right column: <\/span><span style=\"color:#282828;\">{}<\/span><span style=\"color:#79740e;\">.&quot;<\/span><span>,\n<\/span><span>                    t.column\n<\/span><span>                )\n<\/span><span>                .<\/span><span style=\"color:#b57614;\">to_string<\/span><span>(),\n<\/span><span>                span,\n<\/span><span>            ));\n<\/span><span>        }\n<\/span><span>        <\/span><span style=\"color:#282828;\">self\n<\/span><span>    }\n<\/span><span>\n<\/span><\/code><\/pre>\n<p><em>I won\u2019t explain how to navigate to the correct statement in the AST for the rest of the mistakes.<\/em><\/p>\n<h3 id=\"class-name-that-starts-in-lowercase\"><a class=\"zola-anchor\" href=\"#class-name-that-starts-in-lowercase\" aria-label=\"Anchor link for: class-name-that-starts-in-lowercase\">\ud83d\udd17<\/a>Class name that starts in lowercase<\/h3>\n<pre data-lang=\"php\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-php \"><code class=\"language-php\" data-lang=\"php\"><span>class uTesting extends FakeClass\n<\/span><\/code><\/pre>\n<p>When you do this, it\u2019s harder to distinguish a class between a variable and a method.<\/p>\n<p>I need to find out if the first letter of the name of the class is capitalized. The <code>String<\/code> type has a method <code>chars<\/code> that can convert the string into an iterator containing all the letters. You can grab the first character with the <code>next()<\/code> function. The <code>char<\/code> type has some valuable methods. The one we need is <code>is_uppercase()<\/code>.<\/p>\n<pre data-lang=\"rust\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-rust \"><code class=\"language-rust\" data-lang=\"rust\"><span style=\"color:#9d0006;\">pub fn <\/span><span style=\"color:#407959;\">has_capitalized_name<\/span><span>(<\/span><span style=\"color:#282828;\">name<\/span><span>: String, <\/span><span style=\"color:#282828;\">span<\/span><span>: Span) -&gt; <\/span><span style=\"color:#b57614;\">Option<\/span><span>&lt;Suggestion&gt; {\n<\/span><span>    <\/span><span style=\"color:#9d0006;\">if <\/span><span style=\"color:#b23c15;\">!<\/span><span>name.<\/span><span style=\"color:#b57614;\">chars<\/span><span>().<\/span><span style=\"color:#b57614;\">next<\/span><span>().<\/span><span style=\"color:#b57614;\">unwrap<\/span><span>().<\/span><span style=\"color:#b57614;\">is_uppercase<\/span><span>() {\n<\/span><span>        <\/span><span style=\"color:#b57614;\">Some<\/span><span>(Suggestion::from(\n<\/span><span>                <\/span><span style=\"color:#b57614;\">format!<\/span><span>(<\/span><span style=\"color:#79740e;\">&quot;The class name <\/span><span style=\"color:#282828;\">{}<\/span><span style=\"color:#79740e;\"> is not capitalized. The first letter of the name of the class should be in uppercase.&quot;<\/span><span>, name).<\/span><span style=\"color:#b57614;\">to_string<\/span><span>(),\n<\/span><span>                span\n<\/span><span>            ));\n<\/span><span>    }\n<\/span><span>\n<\/span><span>    <\/span><span style=\"color:#b57614;\">None\n<\/span><span>}\n<\/span><\/code><\/pre>\n<h3 id=\"lowercase-constants\"><a class=\"zola-anchor\" href=\"#lowercase-constants\" aria-label=\"Anchor link for: lowercase-constants\">\ud83d\udd17<\/a>Lowercase constants<\/h3>\n<pre data-lang=\"php\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-php \"><code class=\"language-php\" data-lang=\"php\"><span>    const I_ = null;\n<\/span><span>    const hello = null;\n<\/span><\/code><\/pre>\n<p>Similar to the capitalized class name, it\u2019s easier to distinguish a normal variable from a constant if the constant is in uppercase.<\/p>\n<p>I assume the constant is already upper cased, so I initialize the variable <code>is_uppercase = true<\/code>. When iterating through all of the letters, if I see a letter that is not in uppercase, I set the <code>is_uppercase = false<\/code>.<\/p>\n<pre data-lang=\"rust\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-rust \"><code class=\"language-rust\" data-lang=\"rust\"><span style=\"color:#9d0006;\">pub fn <\/span><span style=\"color:#407959;\">uppercased_constant_name<\/span><span>(<\/span><span style=\"color:#282828;\">entry<\/span><span>: ConstantEntry) -&gt; <\/span><span style=\"color:#9d0006;\">bool <\/span><span>{\n<\/span><span>    <\/span><span style=\"color:#9d0006;\">match<\/span><span> entry {\n<\/span><span>        ConstantEntry {\n<\/span><span>            name,\n<\/span><span>            equals,\n<\/span><span>            value,\n<\/span><span>        } <\/span><span style=\"color:#b23c15;\">=&gt; <\/span><span>{\n<\/span><span>            <\/span><span style=\"color:#9d0006;\">let mut<\/span><span> is_uppercase <\/span><span style=\"color:#b23c15;\">= <\/span><span style=\"color:#8f3f71;\">true<\/span><span>;\n<\/span><span>            <\/span><span style=\"color:#9d0006;\">for<\/span><span> l <\/span><span style=\"color:#b23c15;\">in<\/span><span> name.value.<\/span><span style=\"color:#b57614;\">to_string<\/span><span>().<\/span><span style=\"color:#b57614;\">chars<\/span><span>() {\n<\/span><span>                <\/span><span style=\"color:#9d0006;\">if<\/span><span> l.<\/span><span style=\"color:#b57614;\">is_uppercase<\/span><span>() <\/span><span style=\"color:#b23c15;\">== <\/span><span style=\"color:#8f3f71;\">false <\/span><span style=\"color:#b23c15;\">&amp;&amp;<\/span><span> l.<\/span><span style=\"color:#b57614;\">is_alphabetic<\/span><span>() {\n<\/span><span>                    is_uppercase <\/span><span style=\"color:#b23c15;\">=<\/span><span> l.<\/span><span style=\"color:#b57614;\">is_uppercase<\/span><span>()\n<\/span><span>                }\n<\/span><span>            }\n<\/span><span>\n<\/span><span>            <\/span><span style=\"color:#9d0006;\">return<\/span><span> is_uppercase;\n<\/span><span>        }\n<\/span><span>    }\n<\/span><span>}\n<\/span><\/code><\/pre>\n<h3 id=\"defining-parameters-without-a-type\"><a class=\"zola-anchor\" href=\"#defining-parameters-without-a-type\" aria-label=\"Anchor link for: defining-parameters-without-a-type\">\ud83d\udd17<\/a>Defining parameters without a type<\/h3>\n<p>I strongly advocate always defining the type for every parameter you declare. You need to define the type to avoid opening the gates to a bad interpretation of your code and introducing unnecessary bugs. In the AST, the <code>FunctionParameter<\/code> contains the parameter. We can pattern match the <code>data_type<\/code> field and the arm that has the <code>None<\/code> will need to return true. We will return the false for the <code>Some(_)<\/code> arm.<\/p>\n<pre data-lang=\"rust\" style=\"background-color:#fcf0ca;color:#282828aa;\" class=\"language-rust \"><code class=\"language-rust\" data-lang=\"rust\"><span style=\"color:#9d0006;\">pub fn <\/span><span style=\"color:#407959;\">function_parameter_without_type<\/span><span>(<\/span><span style=\"color:#282828;\">parameter<\/span><span>: FunctionParameter) -&gt; <\/span><span style=\"color:#9d0006;\">bool <\/span><span>{\n<\/span><span>    <\/span><span style=\"color:#9d0006;\">match<\/span><span> parameter {\n<\/span><span>        FunctionParameter {\n<\/span><span>            comments,\n<\/span><span>            name,\n<\/span><span>            attributes,\n<\/span><span>            data_type,\n<\/span><span>            ellipsis,\n<\/span><span>            default,\n<\/span><span>            ampersand,\n<\/span><span>        } <\/span><span style=\"color:#b23c15;\">=&gt; <\/span><span style=\"color:#9d0006;\">match<\/span><span> data_type {\n<\/span><span>            <\/span><span style=\"color:#b57614;\">None <\/span><span style=\"color:#b23c15;\">=&gt; <\/span><span style=\"color:#9d0006;\">return <\/span><span style=\"color:#8f3f71;\">true<\/span><span>,\n<\/span><span>            <\/span><span style=\"color:#b57614;\">Some<\/span><span>(<\/span><span style=\"color:#b23c15;\">_<\/span><span>) <\/span><span style=\"color:#b23c15;\">=&gt; <\/span><span style=\"color:#9d0006;\">return <\/span><span style=\"color:#8f3f71;\">false<\/span><span>,\n<\/span><span>        },\n<\/span><span>    }\n<\/span><span>}\n<\/span><\/code><\/pre>\n<h1 id=\"conclusion\"><a class=\"zola-anchor\" href=\"#conclusion\" aria-label=\"Anchor link for: conclusion\">\ud83d\udd17<\/a>Conclusion<\/h1>\n<p>In part <a href=\"https:\/\/denzyl.io\/blog\/write-your-own-static-analyzer-for-php\/.\/docs\/blogs\/phanalist\/How_I_made_impossible_to_write_spaghetti_code.md\">2<\/a>, I will show how to calculate the cyclomatic complexity of an example code.<\/p>\n<p>If you are a PHP developer, you know that a developer can make many more mistakes in PHP. In the future, this list will continue to grow into something more useful.<\/p>\n<p>Thanks for reading!<\/p>\n<p>Contribution is always welcome if you have a mistake you would like to add to <a rel=\"noopener\" target=\"_blank\" href=\"https:\/\/github.com\/denzyldick\/phanalist\">phanalist<\/a>.<\/p>\n"}]}