Loading...

Follow Exakat - Turn PHP into Analytics on Feedspot

Continue with Google
Continue with Facebook
or

Valid
Classic Code Review for PHP Classes

Classes help organise the code by breaking it into smaller components, that combined together to build powerful applications. Property definitions, abstract classes, local variables and identical methods are all code smells that evolve directly inside large repositories with many classes. 

Here some common code smells that arise in OOP PHP code. They all may be spotted with Exakat, the static analysis engine for PHP. 

Define All the Properties

PHP is flexible as ever, and there is no need to declare a property before using it. 

Yet, it helps PHP to know in advance that a property will be used. It takes advantage of it by pre-allocating memory, and reusing it faster. The property is ready as soon as it is needed. Compare that to the fallback behavior, where PHP has to search for the property, fail to find it, then allocate the memory. This also helps reuse the memory for new objects, as they now have a comparable and predictable footprint. 

Quick benchmarks will show that defined properties are 50% faster than undefined properties. It is a micro-optimisation, as accessing a property is very fast, but given the amount of usage of properties, including in loops, this is usually worth the work. 

As a common rule, make sure all your properties are defined. As a side note, it also helps your analysis tools.

In fact, as an extra tip, you can add the following __get() and __set() to all your classes, including the one which are totally defined and don’t use magic functions. With them, when an unknown property is called during execution, the magic methods are called, and will act as canaries to warn you about a typo or a mis-target. Use them during development and testing phase, then remove them for production. 


<?php

trait NoUnefinedProperties {
    function __get($name) {
        assert(false, "Attempt to read the $name property, on the class ".__CLASS__;
    }

    function __set($name, $value) {
        assert(false, "Attempt to read the $name property, on the class ".__CLASS__;
    }
}

?>
Could Be Abstract Class

An abstract class is a class that can’t be instantiated. It must be a parent of a concrete class, which may be instantiated. Besides holding static methods and class constants, this is the only option for it to be useful. 

So how do you call a class which is extended and never instantiated directly? Well, that looks like a template for the inheriting classes, and may actually be marked as such by using the abstract keyword

<?php

// This class is never instantiated
class Money {
    function __construct() { }  
}

class Euro   extends Money {}
class Dollar extends Money {}
class Yuan   extends Money {}


?>

This will actually prevent the class to be instantiated, yet have a constructor. Note that there is no need for any method to be abstract : the whole class may be abstract, implement interfaces, and yet, have no abstract methods.

Abstract classes won’t be tested, at least directly. When you want to keep those tests, extend this abstract class into an empty concrete class. Then, test this class. The behavior will be the same, but now, there is a special class, distinct from any implementation. 

<?php

// This class is tested with Rawmoney
abstract class Money {
    function __construct() { }  
}

class Euro     extends Money { /* more code */ }
class Dollar   extends Money { /* more code */ }
class Yuan     extends Money { /* more code */ }
class Rawmoney extends Money {}

?>
Property Could Be Local

What is the family relationship between a property and a local variable ? Both can hold values, but the scope is different. A local variable is restricted to a method scope, while a property is available within a class, across several methods (let’s omit the public properties for a moment).

<?php

// This class is tested with Rawmoney
class Foo {
    private $property = 1;
    private $property2 = 1;
    
    function Bar($arg) {
        $this->property = $arg + 4 + $this->property2;
        $this->property2 = $this->property * 2;
    }   
    
    function BarBar() {
        return $this->property2;
    }
}

?>

With those definitions, local variables and properties are similar but different. In fact, the only moment when they are identical is when they cumulate the constraints : a property that is used in only one method

Such property could be turned into a local variable, without impacting the rest of the class. 

The property may be used across several calls to the same method : in that case, it may be interesting to move it to a static variable. 

There is also another interesting situation : a local variable that is available in multiple methods. To achieve this, the local scope must transmit the local variable to another scope by calling another method as an argument. This is how variables that are local start appearing in multiple methods signatures, until one realize it could be upgraded to a property, and removed from those signatures.

Identical Methods In A Class Tree

It is usually easy to spot identical methods in one class : the name itself is usually enough to yield a « Fatal error ». On the other hand, identical methods in a class tree is harder to find.

That is, harder to find for us, humans. The same method, available in both the parent class and the child class, is strangely difficult to spot. They look the same, and they also belong to different files, while serving the same purpose. If one overwrites the other, it may be bad luck.

<?php

// This class is tested with Rawmoney
class Foo {
    protected function bar() { /**/ }
}

class Foo2 extends Foo {
    // Same as above
    protected function bar() { /**/ }
    protected function barfoo() { /**/ }
}

?>

Identical methods in a class tree is a copy/paste code smell. One of the classes was copied from the other during its creation, or some generalizing refactoring stopped short, and left methods in multiple position. 

The good aspect is that it is easy for static analysis to find them. As long as they are identical, and not modified. 

The choice of the remaining method may be tricky : is it a parent method, available to other children ? Or is it a child’s specific method ? Or even, should the child method overwrite the parent on purpose, to cancel it? 

Could Use Self

Usually, classes are identified with their fully qualified name, such as \X, \A\B\C\MyClass, or even an alias MyClass. And just like anything that is hardcoded, it is hard to change it without refactoring all its instances. 

<?php

// This class is tested with Rawmoney
class Foo {
    protected const A = 1;
    
    function bar() {
        // Static FQN
        return Foo::A;

        // Adaptable FQN
        return self::A;

        // For LSB users
        return static::A;
    }
}

?>

Whenever the class references itself with a FQN, the special name ‘self’ (or its close cousin ‘static’ for Late State Binding), should be used. It keeps the FQN relative to the class, and it is still readable. It makes any refactoring or renaming easier. 

Note that self also represents any parent class, so you may use it even when referencing a structure defined in parents. 

<?php

// This class is tested with Rawmoney
class Foo {
    protected const A = 1;
}

class FooBar extends Foo {
    function bar() {
        // Return Foo::A
        return self::A;

        // For LSB users : here, self === static
        // as A is defined above only
        return static::A;
    }
}

?>
Disconnected Classes

Let’s finish with a special structure : the disconnected classes. This happens in class hierarchies, when a class extends another class. The situation is that both classes keep living their life, separated : they never call the other one.

<?php

class Foo {
    protected const A = 1;
}

class FooFoo extends Foo {
    function bar() {
        return 1;
    }
}

?>

One extreme case is when the parent class provide support for the child class. This usually saves repeating code, provide formal structure and help plug the child class in a larger framework. In this case, the child class make use of the parent class. 

The other extreme case is when the parent classes act as a template for child classes, which provides specialisation, such as methods or properties. The parent has some generic code that is configured thanks to the child configuration. The parent class calls the child.

The general case is a hybrid version of the two above, where parent and children exchange calls to each other. In the end, this build one integrated class, that is a subtle mix of both initial classes. This almost sounds like genetics.

<?php

abstract class Foo {
    protected const A = 1;

    function foo2() {
        return $this->bar();
    }
    
    abstract function bar();
}

class FooFoo extends Foo {
    function bar() {
        return self::A;
    }
}

?>

So, what happens when two classes have an extends relationship, but keep from calling each other ? This ends as a code smell, where one of the classes is trying to fulfill a mission in the wrong place of the code. It is a good start for a refactorisation.

Happy Code Review

Most of those patterns happen with the organic evolution of the code. They are the reason why code review is important in the first place : it takes some experience and time to read the code base and spot strange construct in the classes or in the control flow.

All those errors are available in the ‘Class Review‘ rule set, in the Exakat engine. Exakat is a static analysis tool, that review PHP code for code quality and self-improvement. It is open source, easy to install and may run on any PHP code base.

The post Classic Code Review for PHP Classes appeared first on Exakat.

  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
Exakat 1.8.8 Review

Exakat 1.8.8 is out. There are numerous improvements under the hood, and significant work during the testing phase. All this new ground will be useful in the upcoming versions, so just listen and get ready for new features. The speed improvements are massive for the smaller codebase : anything smaller than WordPress will benefit from a 50% speed increase. Then, phpdocs are now loaded with the rest of the code, for further treatment. And the reports have been refactored : they are configurable with a Yaml file, so you can now tailor your HTML report to your needs. The best time to do a code review as yesterday. The second best time is today, with the Exakat 1.8.8 review. 

Speed up 50% with tinkergraph engine

Exakat runs with a graph database engine at its core. It is the gremlin server, from the apache software foundation

In the gremlin server, Gremlin is the navigation language. The server is tinkerpop. The server itself is the host of the gremlin language, and it delegates the storage work to engines. There are a lot of engines nowadays, and Exakat uses two of them : tinkergraph and neo4j. 

Neo4j is well suited for large code base, and offer good reliability when it comes to storing the nodes and link on the disk. 

Tinkergraph, on the other hand, is a memory only engine. It store all its data in memory. This is a much faster option than the disk based version, since Exakat has no major constraints on data persistence : in case of crashes, it is safer to restart than to fix the data.

Configure tinkergraph or neo4j

To take advantage of the tinkergraph, you have to update the config/exakat.ini file. This file should be in the same directory as the Exakat binary. If you haven’t created it yourself, Exakat has done it for you, at the first call to doctor. In particular, Exakat detected which engine is available, between neo4j and tinkergraph, and used by default neo4j. 

; use tinkergraph or gsneo4j
graphdb = 'tinkergraph';

Configure tinkergraph by using the tinkergraph, or gsneo4j to use the neo4j plugin. 

In case the neo4j plugin is not installed, you can use the optional part of the installation in the Manual to finish the installation.

New engines coming ?

There is a third engine available, called ‘nogremlin’ : it provided a valid driver to gremlin, when no gremlin is installed. This is useful for development purposes, or when Exakat is used only to produce reports from audits. There is always a usage for the null pattern object.

Besides this engine, we have room to use other engines, such as JanusgraphAmazon Neptune or Orientdb. Get in touch with us if you want to extend the support of Exakat to those engines, so we can help you too. 

PHPDoc Support

Since Exakat 1.8.8, phpdocs comments are now loaded in the graph database and are available to support analysis. 

Until now, they were ignored like any other comment. Yet, many frameworks and tools use them to annotate the code, extends PHP typing system, or document it. 

PHPdoc comments are now loaded with namespaces, classes, traits, interfaces, methods, properties and constants. Other instances, like a phpdocs next to a value or an expression, are ignored. If you have actual usage of such comments, please, send us examples so we can upgrade the support. 

At the moment, phpdocs are added to the engine, and are available for manipulation with regex. They will be added to analysis, in particular extension’s analysis, whenever they add details to the audits.

New report : Emissary

Exakat 1.8.8 added a new report : Emissary. This is a report from the Ambassador family : human readable report, with faceted engine, multiple sections and subsections. In fact, other reports, like Diplomat or Owasp, which are based on Ambassador, use the same template, yet display a specific selection of results and metrics.

It is actually a new version of Ambassador, with a special added value : Emissary menu and its content, may be configured. Sections and subsections are available, and may be titled one wishes.

We are currently working on the documentation for this feature. 

Adopt an Array_* Function Today

PHP has a long list of Array functions : array_columnarray_chunkarray_combinearraydiffuassoc, just for my own favorites.

There are many situations where one of those native function may replace a whole loop. For example, imagine the following loop : 

<pre class="wp-block-syntaxhighlighter-code">
&amp;lt;?php

$valid = [];
foreach($array as $a) {
    if (check($a)) {
        $valid[] = $a;
    }
}

?&gt;
</pre>

You can read, without any code knowledge, that this loop is selecting the valid values, thanks to the check() function. The valid values are collected in a new array, with an append : $valid.

This whole loop may be easily replaced with a call to array_filter, which applies a callback to each element of an array, and build a new array with the values that satisfy the callback : in a word, the callback is returning true. 

Moving to PHP native functions is a smart move : those functions are often faster than writing a whole loop, and they are also requiring less code to type. Less code, fewer bugs. 

In the long term, such code compacting help with multiple usage : here, check() may be used again, in another loop. New comers will find it easier to understand, and reuse in their own code. And, last but not least, it keeps the loop focused on one operation : too often, a loop will grow, and get supplementary expressions, until it cannot be broken into smaller pieces. 

This analysis covers the following methods :

  • array_push() : use array_merge()
  • array_slice() : use array_chunk()
  • index access : use array_column()
  • append []: use array_merge()
  • addition : use array_sum()
  • multiplication : use array_product()
  • concatenation : use implode()
  • if then : use array_filter()
The Weekly Audits: 2019, Week #26

Exakat includes a ‘weekly’ report: this report is built with a selection of five analyses. This means a short audit report, with few issues to review. This is not a lot to read them, and review them in your code. Everyone in the PHP community can focus on one of the classic coding problems and fix it. Talk about the weekly audit around you: you’ll find programmers facing the same challenges.

To obtain the ‘weekly’ audit, run an audit, and request the ‘Weekly’ report.

# Init the project (skip when it is already done)    
php exakat.phar init -p <yourproject> -R https://github.com/Seldaek/monolog.git -git 

# Run the project (skip when it is already done)    
php exakat.phar project -p <yourproject> 

# Export the weekly project (every monday)    
php exakat.phar report -p <yourproject> -format Weekly 

# Open projects/<yourproject>/weekly/index.html in your browser    

Every week, you can find here 5 new analysis to review in your code. In fact, when your code is clean, you can also take a quick look at the upcoming analysis. 

Weekly recommendations for PHP code review : 2019, week 2019-29

Happy PHP Code Reviews 

All the 360 analyzers are presented in the docs, including the vicious :
Silently Cast Integer:: Those are integer literals that are cast to a float when executing PHP.

This is a rare bug, with fewer than 3% of chance to appear, but it stings. 

You can check all of the Exakat reports at the gallery: exakat gallery.

Download Exakat on exakat.io, install it with Docker, upgrade it with ‘exakat.phar upgrade -u’ and like us on github.

The post Exakat 1.8.8 Review appeared first on Exakat.

  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
Exakat 1.8.6 Review

Exakat 1.8.6 is a performance version. First, Exakat moved to Tinkergraph 3.4.2, using the latest and brightest of the graph database. Several analyses were refactored for faster processing, then the Query engine was optimized to skip side queries when possible. And finally, we’re working on loading time, both directly and with the advent of an incremental load. The more I know people, the more I like the Exakat 1.8.6 review. 

Upgrade to Tinkergraph 3.4.2

The Exakat engine now makes use of Tinkergraph 3.4.2. This is important in keeping updated with Exakat’s related technology, such as PHP or Tinkergraph. It had some impact on the internal : as Gremlin, the navigation language, evolves, some of the queries had to be rewritten. Others have been spotted as in need of updates, and that will be done along the way. 

New installations are documented with this new version, and it is recommended to upgrade to a more recent version of Tinkergraph, so as to take advantage of bug fixes and better stability. 

You may upgrade the database without upgrading Exakat.

Upgrading to Tinkergraph 3.4.2

The upgrading steps are similar to the installation, let alone stopping the database first. When no audit is running, the database is not used. 

> php exakat.phar cleandb -stop 
> rm -rf tinkergraph
> curl -o apache-tinkerpop-gremlin-server-3.4.2-bin.zip http://dist.exakat.io/apache-tinkerpop-gremlin-server-3.4.2-bin.zip
> unzip apache-tinkerpop-gremlin-server-3.4.2-bin.zip
> mv apache-tinkerpop-gremlin-server-3.4.2 tinkergraph
> rm -rf apache-tinkerpop-gremlin-server-3.4.2-bin.zip

> cd tinkergraph
> ./bin/gremlin-server.sh install org.apache.tinkerpop neo4j-gremlin 3.3.7
> cd ..
> php exakat.phar project -p <my project>
Upgrading to Exakat 1.8.6

To upgrade Exakat to the latest version, you should use the upgrade command.

exakat upgrade -u

-u option actually makes the upgrade. Without it, exakat only makes a dry run for the upgrade. 

Possible infinite recursion

A new analysis targets infinite recursion. This happens when a recursive function has no termination condition. The first situation is a direct call to self, without condition.

&lt;?php

function foo($a) {
    foo($a);
}

?&gt;

Subtler is the call to the same method, without changing the arguments. Same entry, same result : this is the base recipe of an infinite recursion. In the example below, a test is made on the incoming arguments, but the same arguments are provided again.

&lt;?php

class x {
    function foo(X $a, $b, $c) {
        if ($a-&gt;toInt() &gt; $b + $c) {
            return 1;
        }
        return $a-&gt;foo($a, $b, $c);
    }
}

?&gt;

Note that in the case of methods, it is possible to detect recursive methods call with the help of type hints : $a is an object of class X, and this makes foo a recursive method. It is not detected as such without the typehint, as the $a argument may then call another class.

Dependant Traits and Abstract Classes

Dependant Trait has been extended to handle Dependant Abstract Classes in the same manner.

A dependant trait, or abstract class, is a trait that makes use of undefined properties, methods or constants. Since a trait is not used by itself, this means that the host class must provide this structure for the trait to run. 

Yet, there is not indication, except by reading the code, that the trait is imposing this definition to the host class. It will probably be discovered later, during execution time. 

&lt;?php

trait t {
    function foo($a) {
        // can't use trait in a class without bar() method
        return $this-&gt;bar();
    }
}

class x {
    use t;
    
    function bar() {}
}

?&gt;

It is recommended making traits autonomous : this means that they only make usage of local methods and properties. This way, the trait may now be added or removed to a class without long-time consequence.

Exakat Engine Speedup

The Exakat engine has received two special patches : one optimization for the queries, and one for the loading engine.

Query optimisation

The Query engine checks the side queries, and detect those that won’t need processing, based on Atom availability. Since Exakat hold a cache of all the Atoms available in the graph, it is possible to stop a filter that depends on those Atoms, or skip a side query that checks their absence. This leads to entire queries to be skipped. 

Analysis refactorisation

Analyses are monitored for speed. The slowest queries are rewritten to take advantage of the recent upgrade on the AST. In particular, variables, properties and methods are often linked to their definition, cutting the number of steps between a variable usage and its definition or other usages. 

Loading phase

With the previous optimization in place, the whole run is now 10% faster than previously. This makes the slowest part of the audit the loading phase. This phase takes the code and load it up in the graph database, adding several key pieces of information along the way. It is both crucial, and constrained by the load speed into the database. 

We have started work on an incremental load of the code : this will keep a previously loaded code and AST in the graph database, and only refresh it with the modified files, read in the VCS diff. This will cut down the loading from ‘whole repository’ to ‘a few files’. The main challenge is then to detect which analysis needs to be rerun. 

As for that, we added a result count in the graph, that keeps tracks of previously found issues. With the update of a few files, this count will not be in sync anymore, and easily detectable. This detects immediately analysis for which issues have been corrected. We now have to figure out where new issues have been created. 

More to come in the following weeks!

The Weekly Audits: 2019, Week #26

Exakat includes a ‘weekly’ report: this report is built with a selection of five analyses. This means a short audit report, with few issues to review. This is not a lot to read them, and review them in your code. Everyone in the PHP community can focus on one of the classic coding problems and fix it. Talk about the weekly audit around you: you’ll find programmers facing the same challenges.

To obtain the ‘weekly’ audit, run an audit, and request the ‘Weekly’ report.

# Init the project (skip when it is already done)    
php exakat.phar init -p <yourproject> -R https://github.com/Seldaek/monolog.git -git 

# Run the project (skip when it is already done)    
php exakat.phar project -p <yourproject> 

# Export the weekly project (every monday)    
php exakat.phar report -p <yourproject> -format Weekly 

# Open projects/<yourproject>/weekly/index.html in your browser    

Every week, you can find here 5 new analysis to review in your code. In fact, when your code is clean, you can also take a quick look at the upcoming analysis. 

Weekly recommendations for PHP code review : 2019, week 2019-27

  • Inclusion Wrong Case : Inclusion should follow exactly the case of included files and path.
  • Cast To Boolean : This expression may be reduced by casting to boolean type.
  • Switch To Switch : The following structures are based on if / elseif / else.
  • Unused Arguments : Those arguments are not used in the method or function.
  • Should Use Constants : The following functions have related constants that should be used as arguments, instead of scalar literals, such as integers or strings.
Happy PHP Code Reviews 

All the 360 analyzers are presented in the docs, including the realistic :
Unset In Foreach: Unset applied to the blind variables of a foreach loop are useless, as they are copies and not the actual value.

This is a common source of bug in source code (34%). 

You can check all of the Exakat reports at the gallery: exakat gallery.

Download Exakat on exakat.io, install it with Docker, upgrade it with ‘exakat.phar upgrade -u’ and like us on github.

The post Exakat 1.8.6 Review appeared first on Exakat.

  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
Exakat 1.8.5 Review

Exakat 1.8.4 and 5 are maintenance version, that focus on fixing edge cases and speeding up analysis. In particular, several analyses have taken advantage of the constant resolution system, to apply checks on literal and constants alike. We also included a new analysis that checks if literal could be replaced by an existing constant. And the Ambassador report now includes the configuration file of the current audit, to configure another repository. I can’t change the Exakat 1.8.5 review, but I can adjust my code to always reach my destination.

Constant resolutions

The Exakat engine keeps track of constants, and their definition. It covers classic constants, with define() or const, but also class constants. This means that the actual value of a constant, when defined in the code, is used wherever the constant is used.

<?php

const MY_FORMAT = "[%s]\n";

printf(MY_FORMAT, $s, $t); // Too many parameters provided

?>

While constants are a formidable tool to federate literals, and have a central point to update them, they also tend to hide the actual value behind a name. This is the case above, where MY_FORMAT is not telling about the actual format, but about the author of the format. As such, resolving the constant, and finding its actual literal value help find bugs that are not obvious.

Note that Exakat also resovles static constant expressions, so if MY_FORMAT is a concatenation, and still statically resolvable, the engine will resolve the constant correctly.

Literal Could Be Constant

With the idea to promote more constant usage, as seen above, a new ‘Suggestions’ has been added : it reports Literal Values that could be replaced by an actual constant.

<?php

const MY_CONSTANT = "abc";

$a = 'abc';

?>

Here, $a is initialized with ‘abc’, while there is already a constant which holds this value. If this applies, it is recommended using the constant for the initialization. Later, it will help update the value from ‘abc’ to another value, without proof-reading the whole application.

Special values like true, false, 0, and 1 are ignored. While they may very well end up being constant, for the same reasons as above, they are usually too often used, and yields a huge amount of false positive. Or real issues, which are all interlaced. This doesn’t help.

As a suggestion, it is worth avoiding those special values, and use other literals for simple comparisons. This usually helps creating lists of special values, and then, pave the way to replacing them by constants.

Could Use Trait

Could Use Trait is a close cousin to Could Use Interface : it detects a class, which has the same methods as a specific trait, yet doesn’t use that trait. Look at this academic example :

<?php

trait t {
    function foo($a) { return ++$a;}
    function foo1($a) {return ++$a;}
}
class x {
    function foo($a) { return ++$a;}
    function foo1($b) {return ++$b;}
    function bar() {}
    function bar1() {}
}

?>

In the example above, foo and foo1 are defined in the x class. They are also defined in the t trait, and they are actually identical. This way, class x could be simplified, and make use of use t;.

Exakat has a clone type 1 representation of each method, and use them to compare the methods between the trait and the class. A clone type 1 is a clone based on tokens : the tokens are the same in both methods, and in the same order. Yet, the value of the token may differ. For example, note that foo1 in class x uses a $b as argument, while it is a $a in trait t.

In another analysis, Exakat reports interfaces that may be used to characterise a class, but which has not been added with the implements keyword.

Export Used Configuration

The Ambassador report includes a new item in the Annex section : the Audit Configuration presents the configuration used to create the current audit. They are in INI and YAML format, which are the two formats used by Exakat.

You can copy/paste those configuration in your config.ini or .exakat.yaml files, in another repository. This is convenient to spread the same configuration across multiple code repositories, in the same company.

The Weekly Audits: 2019, Week #26

Exakat includes a ‘weekly’ report: this report is built with a selection of five analyses. This means a short audit report, with few issues to review. This is not a lot to read them, and review them in your code. Everyone in the PHP community can focus on one of the classic coding problems and fix it. Talk about the weekly audit around you: you’ll find programmers facing the same challenges.

To obtain the ‘weekly’ audit, run an audit, and request the ‘Weekly’ report.

# Init the project (skip when it is already done) php exakat.phar init -p <yourproject> -R https://github.com/Seldaek/monolog.git -git # Run the project (skip when it is already done) php exakat.phar project -p <yourproject> # Export the weekly project (every monday) php exakat.phar report -p <yourproject> -format Weekly # Open projects/<yourproject>/weekly/index.html in your browser

Every week, you can find here 5 new analysis to review in your code. In fact, when your code is clean, you can also take a quick look at the upcoming analysis.

Weekly recommendations for PHP code review : 2019, week 2019-24

Happy PHP Code Reviews 

All the 360 analyzers are presented in the docs, including the hideous :
: Multiple Type Variable: avoid using the same variable with different types of data. It makes it difficult to keep track with the value itself.

This is a common source of bug in source code (43%).

You can check all of the Exakat reports at the gallery: exakat gallery.

Download Exakat on exakat.io, install it with Docker, upgrade it with ‘exakat.phar upgrade -u’ and like us on github.

The post Exakat 1.8.5 Review appeared first on Exakat.

  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
Exakat 1.8.3 Review

Exakat 1.8.3 has been refactoring a lot of property and method infrastructure. We are now quite satisfied with the new handling of properties, even if some unit tests are still not passing. In the meantime, we added new tactical checks : how to speed up usage of magic properties, by choosing the best one to cache; one silly trick with auto-appending arrays and even more in the Changelog. Find joy in everything you code, for the rest, check the Exakat 1.8.3 review.

SARB : Static Analysis Results Baseliner

When starting with Exakat, the best report to use is the Ambassador report : it is the most extensive report, and its GUI interface is suited for discovery. It is a great first step.

After working with Exakat for a while, it is important to set up a baseline. A baseline is the concept than the tare : it is the weight of the container, so you can deduce the weight of the substance from the total weight. Applied to static analysis, the baseliner creates a list of results, and remove those results from the current audit, leaving only the new one. This leads to a much smaller result set, and shows only the new detected code smells.

SARB is the Static Analysis Results Baseliner. It creates the baseline, then weed out the old issues in the next audits. The synopsis is straightforward : 

  • Run Exakat, and produce the Sarb report. Keep the ‘exakat.sarb.json’ file handy.
  • Create the SARB baseline : 
    vendor/bin/sarb create-baseline \
    projects/my_project/exakat.sarb.json \
    reports/sarb_baseline.json \
    exakat-json
  • Update your code, and run again exakat, with the ‘SARB’ report.
  • Use the SARB to remove the baseline results
    vendor/bin/sarb remove-baseline-results \
    reports/exakat.sarb.json \
    reports/sarb_baseline.json \
    reports/issues_since_baseline.json

With the baseline, you may now make your code better on a daily basis : new issues are easy to identify, and should be worked upon immediately. This keeps them from coming back, or even entering the code. 

The history, or the baseline, is still here. You may then work on it as time permits, reducing technical debt each time. 

SARB authored by Dave Liddament and is currently in Beta version. You can visit the home repository to use it and help with its development.

Performance : from Magic to Concrete property

Magic properties are the magic properties which doesn’t exist, and are managed by four PHP magic methods : __get, __set, __unset and __isset. 

Magic properties are convenient when the actual list of properties is not known until execution time. For example, rows from a database, or properties in a JSON file. 

<?php

class x {
    function __get($a) {
        return 'a'; // simplistic magic method
    }
}

$x = new x();
echo $x->y.$x->z; // display 'aa'

?>

Magic properties are convenient when the actual list of properties is not known until execution time. For example, rows from a database, or properties in a JSON file. 

Magic properties are also quite slow, compared to their traditional version. Indeed, magic properties turn a simple property access into a functioncall, with context switching and typehint checks. When the property access has a very simple logic, this may slow down the script from 100% to 400%. This may easily get worse as soon as extra checks are added (existence). 

At that point, it is difficult to suggest avoiding magic methods altogether. First, when properties are dynamic, they are quite helpful. Secondly, this is a micro-optimisation : there needs to be several millions of hits on the property to reach one second slow down. 

With magic method being very convenient, they are used. And, as soon as they are part of the developer tool belt, there is an unbalanced usage of properties. Some are seldom used, some are used very often. In fact, if you’re using all of them, in the same way, you’ll probably have made them concrete, not magic. 

Exakat helps you refine your property usage with two interesting cases. Choosing the concrete properties in the class, and memoizing the values. 

Choosing concrete properties

Properties that are commonly used in the code base should be turned into a concrete property. As long as they are used dynamically, there is no way to prepare for them, but once we can spot multiple usage of the same name, and yet can’t find a definition, this should be a property.

<?php

class x {
    function __get($a) {
        return 'a'; // simplistic magic method
    }
}

function foo() {
    $x = new x();
    $a = $x->a;   // get $x-&gt;a from the object
    echo $a * $a; // use the local cache

    echo $x->b * $x->b;    // calling the class twice
}

?>

In the example above, y is used in two different context, foo and foo2. This is now a common usage of a property, which also relies on the __get method in class x. On the other hand, a and z are used once only in the code, and may stay totally magic, just like $b, for which we have no information. 

Exakat reports that y should be turned into a concrete property.

Memoizing the property

The other potential cache we can use is in the context itself. Requesting the property is a costly expression, so the first access should be put into a variable, and then reused, instead of requesting again the value from the object.

<?php

class x {
    function __get($a) {
        return 'a'; // simplistic magic method
    }
}

$x = new x();
echo $x->y.$x->z; // display 'aa'

?>

You may parameter this analysis with the magicMemberUsage parameter. By default it is 1, so any double call to the same property from the same context triggers the analysis. Add the following section to your config/exakat.ini or projects/<my_project>/config.ini. 

[Classes/MakeMagicConcrete]
  magicMemberUsage = 3;

Avoid very long recursion with appends

Last week, a small typo was the starting point of a long head-scratching problem. The code is summarized here, and you’ll probably find the flaw immediately : 

 
<?php 

$results = [];
foreach($array as $result) {
    // More code
    $results[] = $results;
}

?>

So, $array is built into $results, via $result, and with some extra logic. The //more code comment doesn’t do justice the piece of code here : it was a lot more distracting. In the end, the resulting array is appended to the current list, though a typo prevented this : the same array was added to itself.

A quick look make you understand that the array will double each loop, and it will probably never reach the 100th iteration without exhausting the memory. With names so close, results and result, and no error except a surprisingly very long to execute script, it took us way too long to spot. 

This is now an Exakat analysis. It may pass unnoticed when the loop is small enough, or if the append is out of any loop, but it will probably bite you some day. So, now, it is under control. 

The Weekly Audits: 2019, Week #24

Exakat includes a ‘weekly’ report: this report is built with a selection of five analyses. This means a short audit report, with few issues to review. This is not a lot to read them, and review them in your code. Everyone in the PHP community can focus on one of the classic coding problems and fix it. Talk about the weekly audit around you: you’ll find programmers facing the same challenges.

To obtain the ‘weekly’ audit, run an audit, and request the ‘Weekly’ report.

# Init the project (skip when it is already done)    
php exakat.phar init -p <yourproject> -R https://github.com/Seldaek/monolog.git -git 

# Run the project (skip when it is already done)    
php exakat.phar project -p <yourproject> 

# Export the weekly project (every monday)    
php exakat.phar report -p <yourproject> -format Weekly 

# Open projects/<yourproject>/weekly/index.html in your browser    

Every week, you can find here 5 new analysis to review in your code. In fact, when your code is clean, you can also take a quick look at the upcoming analysis. 

Weekly recommendations for PHP code review : 2019, week 2019-24

  • Useless Brackets : Standalone brackets have no use.
  • Typehint Must Be Returned : When using a typehint for a method, it is compulsory to use a at least one return in the method’s body.
  • Failed Substr Comparison : The extracted string must be of the size of the compared string.
  • Incompilable Files : Files that cannot be compiled, and, as such, be run by PHP.
  • Use Constant : The following functioncall have a constant equivalent, that is faster to use than calling the functions.
Happy PHP Code Reviews 

All the 360 analyzers are presented in the docs, including the hideous :
Only Variable Returned By Reference: Function can’t return literals by reference. This is a rare bug in source code (3%). 

You can check all of the Exakat reports at the gallery: exakat gallery.

Download Exakat on exakat.io, install it with Docker, upgrade it with ‘exakat.phar upgrade -u’ and like us on github.

The post Exakat 1.8.3 Review appeared first on Exakat.

  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
Exakat 1.8.2 Review

Exakat 1.8.2 starts a growth cycle with the internal engine. New relations are being built across the code base, to create a shorter path between related pieces of code. In the meantime, we collect three pieces of wisdom last week : infinite foreach() loops, too much of get_class() and identical inherited methods. There is nothing permanent, except the Exakat 1.8.2 review.

Exakat engine extension

Two important experiments are being run with the core of the Exakat engine. Default values for all variables, and property definitions.

default values for all variables

Properties have a chance to get default values. At definition time, it is possible to specify a literal value, or even an expression. This will save the same assignation later, in the constructor. The same is true for static variables (not properties). Rather strangely, not for global variables.

<pre class="wp-block-syntaxhighlighter-code"> &amp;lt;?php

class x {  
  private $property = 1;
}

// works with static variables 
static $s = 2;

// won't works with static variables 
//global $g = 3;
//syntax error, unexpected '=', expecting ',' or ';'

// works with local variables 
$v = 4;

?&gt;
 </pre>

Local variables don’t get a definition, so we have to rely on a simple assignation to do so. This way, it actually looks like a local variable definition is another piece of code. In fact, it is a definition, but without any keyword. 

Also, properties cannot get assigned a default value when they have to store a dynamic resource, such as a resource, a callable or an object. Since those structures are only available at execution time, the default value is often set at constructor’s call, or later, when other prerequisites are met. For example, the path for the log. 

Since static analysis is not the same as executing PHP, Exakat is now building a direct link between the property definition and the first assignations that appear in the code. For example, in the following code, the real default value of $property is, in fact, the stdClass object.

<pre class="wp-block-syntaxhighlighter-code"> &amp;lt;?php

class x {  
  private $property = null;

  function __construct() {   
    $this-&gt;property = new stdClass();
  }
}
?&gt;
 </pre>

With this link, we have a better knowledge of the actual usage of the property, and may even add a typehint for the property, just like in the upcoming PHP 7.4. 

As usual, such description may not apply to some of the code, including the classic struggle with dynamic code, and multi-assignation for a single property. We’ll have to skip a few of them, until we find a better way to handle them. In fact, this may end up as a recommendation for writing code. 

Where are the properties defined

Here is a classic situation where a property is defined in a parent class. $property is set in x, and then, used in y1 and y2. 

<pre class="wp-block-syntaxhighlighter-code"> &amp;lt;?php

class x {  
  protected $property;
}

class y1 extends x {  
  function foo() {   $this-&gt;property = 1;  } 
}

class y2 extends x {  
  function foo() {   $this-&gt;property = 'a'; } 
}

?&gt;
 </pre>

Currently, the definition of the property is held in x, and the usage is defined as a link between the property definition and Member, throughout the code. Since $property is defined in the parent class, it is conceptually shared between the two classes. 

Yet, the usage of this property is strictly segregated. The $property in y1 has no way to leak into y2, and vice-versa. When instantiated, those properties will all have distinct memory spaces, and processes. 

As an upgrade from the current mechanism, the property definitions are now replicated down the class hierarchy, and set, virtually, where are actually used. This helps separate property spread between the child classes, even if there is only one definition. Later, we’ll avoid false positive, such as ‘inconsistent property usage’ : here, with two distinct definitions for property, we should not report that it is used with incompatible functions. In fact, $property in y1 and $propertyin y2 are totally different properties. 

<pre class="wp-block-syntaxhighlighter-code"> &amp;lt;?php

class x {  
  protected $property;
}

class y1 extends x {  
  // virtual property, copied from above  
  protected $property;

  function foo() {   
    $this-&gt;property = 1;
  } 
}

class y2 extends x {  
  // virtual property, copied from above  
  protected $property;

  function foo() {   
    $this-&gt;property = 'a';
  }
}
?&gt;
 </pre>
Working hard on the next version of Exakat

Some progress is already available, and more refactoring will go on in the next versions. We’ll keep you updated with the coming versions. 

Report identical inherited methods

Sometimes, in class hierarchies, the same method is defined both in a parent class and a child class. In this case, the method is not simply overwritten by a child class : it is a plain copy from the parent class.

<pre class="wp-block-syntaxhighlighter-code"> &amp;lt;?php

class x {  
  public function foo() {     
    return rand(0, 10);
  } 
}

class y extends x {  
  public function foo() {     
    return rand(0, 10);
  } 
}

?&gt;
 </pre>

There are multiple fixes for this situation. The parent method may be removed, leaving the child method. When other siblings also use the same method, they should then get their definition for the method. 

The child method may be removed, and this is the simplest modification. In fact, the child is often created from the parent, and this is a dead code removal.

The method may be moved to a separate class or trait, for reuse. 

Identical methods is also part of the Class review ruleset. This rule set checks for weird structure in class structures. 

At the moment, abstract methods are also reported. This is fixed next week, in version 1.8.3.

Avoid infinite loop in foreach()

Code inspirator Frederic Bouchery tested our knowledge with this question : ‘What will this code return?’.

<pre class="wp-block-syntaxhighlighter-code"> &amp;lt;?php $a = [1];
foreach($a as $v) {    
  $a[] = $v + 1; 
}
print_r($a);
?&gt;
 </pre>

Foreach loops through the $a array, and each time, adds a new value to the source array. The trick is that foreach() doesn’t work the same way with a reference or without a reference. 

Without a reference, as shown here, foreach() works on a copy of the original array. Thus, adding new elements, or modifying those elements, during the loop has no effect on the execution. In this case, it ends with two elements in $a.

With a reference, not as shown here, foreach() works on the original array. Thus, adding a new element during the loop, with append, $a[], also includes the element in the loop. So, adding one element means that $a is longer, so it loops again, and adds one element, and is longer, and loops, and adds… This is an infinite loop.

A simple configuration on the blind variable may have tremendous impact on the execution. 

No need for get_class()

We ran into this code : it dynamically access a static variable. The manipulated class is provided as the class of an object, so the code relies on get_class() to find that name. 

<pre class="wp-block-syntaxhighlighter-code"> &amp;lt;?php

// This is too much code 
get_class($a-&gt;b)::$c

?&gt;
 </pre>

In fact, PHP is able to find the class of an object. It is often possible to use an object to represent a class, and PHP will do the interpretation on its own. Here are other examples: 

<pre class="wp-block-syntaxhighlighter-code"> &amp;lt;?php

// Accessing a static property from an object 
$a-&gt;b::$property

// Accessing a static constant from an object 
$a-&gt;b::CONSTANT

// Accessing a static method from an object 
$callback = array($a-&gt;b, 'method')

// Calling a static method from an object 
// May yield a warning
$a-&gt;b-&gt;static_method()

?&gt;
 </pre>
The Weekly Audits: 2019, Week #22

Exakat includes a ‘weekly’ report: this report is built with a selection of five analyses. This means a short audit report, with few issues to review. This is not a lot to read them, and review them in your code. Everyone in the PHP community can focus on one of the classic coding problems and fix it. Talk about the weekly audit around you: you’ll find programmers facing the same challenges.

To obtain the ‘weekly’ audit, run an audit, and request the ‘Weekly’ report.

# Init the project (skip when it is already done)    
php exakat.phar init -p <yourproject> -R https://github.com/Seldaek/monolog.git -git 

# Run the project (skip when it is already done)    
php exakat.phar project -p <yourproject> 

# Export the weekly project (every monday)    
php exakat.phar report -p <yourproject> -format Weekly 

# Open projects/<yourproject>/weekly/index.html in your browser    

Every week, you can find here 5 new analysis to review in your code. In fact, when your code is clean, you can also take a quick look at the upcoming analysis. 

Weekly recommendations for PHP code review : 2019, week 2019-23

  • Multiply By One : Multiplying by 1 is a fancy type cast.
  • No Hardcoded Port : When connecting to a remove server, port is an important information.
  • Var Keyword : Var was used in PHP 4 to mark properties as public.
  • Can’t Extend Final : It is not possible to extend final classes.
  • Use const : The const keyword may be used to define constant, just like the define() function.
Happy PHP Code Reviews 

All the 359 analyzers are presented in the docs, including the outrageous :  Used Once Variables: variables should be used at least twice! One for writing, one for reading. Recycle your variable, if you want a metaphor! This is a plague in source code (87%). 

You can check all of the Exakat reports at the gallery: exakat gallery.

Download Exakat on exakat.io, install it with Docker, upgrade it with ‘exakat.phar upgrade -u’ and like us on github.

The post Exakat 1.8.2 Review appeared first on Exakat.

  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
Add Exakat To Your CI Pipeline

The Continuous Integration pipeline builds your code automatically, and runs a large number of checks. When those checks fail, the build of the application is cancelled, and the development team have a change to square everything again. 

With more consistent checks, continuous integration leads to higher code quality. Exakat is a natural part of the CI pipeline : it automates highly sophisticated code reviews, and report them directly to the CI. 

To integrate Exakat in your CI pipeline, Exakat has to be configured with a .exakat.ini or .exakat.yml file. These files configure the engine with the requested rules to pass over the code. Put one of them at th root of your repository, next to composer.json, for example.

With this set up, Exakat may be used in gitlabbitbuckettravis-cijenkinscircleci.

Configuring Exakat For CI

Traditionally, Exakat manages all code and audits in separate folders, all put away in projects. Each folder contains the configuration file, called config.ini, the last audits and various temporary files, used for analysing and auditing the code. There is also the ‘code’ repository, which hosts the code itself. This way, Exakat always kept code and audits separated, so as to keep the source code intact.

When running Exakat for a CI, such organization is not pragmatic. Usually, only the code folder is available, and there is little access to anything else. The audit and its configuration have to happen in the same folder. 

To run Exakat directly from the code folder, there must be at least one configuration file. There are two options for this file : either .exakat.ini, or .exakat.yaml. The first one is simpler to set up and has precedence over the YAML version, but also has more limited features. The Yaml version is very similar, and provides more features. It is recommended to set up the INI first, then move to the YAML version when advanced features are needed. 

.exakat.ini

‘.exakat.ini’ is the alter ego of the ‘config.ini’, that is produced with the traditional Exakat installation. It uses the INI file format. You have to put it at the root of the code source. It is recommended storing it in the VCS repository.

Your code repository may look like this : 

.exakat.yml
.git
.gitignore
/app
/src
/web
composer.json   
...

Here is a simple configuration file : 

project      = 'angie-project';
project_name = 'angie, the audit'

project_reports[] = 'Text';

project_ruleset[] = 'Security';

  • project : This is the name of the project. Use a simple yet telling name, with letters, figures, underscores and dash. This is compulsory. It is used internally, by exakat, for identification. 
  • project_name : this is the name used when building reports. It has fewer constraints than the project entry, and in case any special character is used, enclose the name in quotes. This is compulsory. You will find it in audits, as the title of HTML pages, for example.
  • project_reports is an array that contains the expected reports. By default, Exakat will produce the Text report, and display it to the standard output. This is suitable for CI. If you want other reports, for example Ambassador, add them here, one by line. All the reports are available in the Manual
  • project_themes is an array that contains the expected rule sets. By default, Exakat will run the Analyze. If you want more analysis to be run, Security, add them here, one by line. All the standard Exakat rule sets are available in the Manual. It is not possible to configure a customized rule set with the .exakat.ini configuration file.

Once the configuration file is stored, at the root of the code repository, you may call the doctorcommand to check the installation.

cd /path/to/code
php /path/to/exakat.phar doctor 

Note that this command has no option -p. If all is well configured, it is not necessary. In fact, there should be a section describing the project, with the project name. 

/// More lines before this section
project : 
    name                 : angie, the audit
    url                  : 
    phpversion           : 7.3
    reports              : Text
    themas               : Security
    included dirs        : 
    ignored dirs         : /test, /tests, /Tests, /Test, /example, /examples, /docs, /doc, /tmp, /version, /vendor, /js, /lang, /data, /css, /cache, /vendor, /assets, /spec, /sql
    file extensions      : php, php3, inc, tpl, phtml, tmpl, phps, ctp, module
/// More lines after this section

In particular, the .exakat.ini file may be ignored, fully or partially, if it is not a valid .INI file. When nothing appears in the project section, check your syntax.

.exakat.yaml

.exakat.yaml offers a higher level of configuration than the .exakat.ini file. It is based on the YAML format, and the same directive as the previous configuration file.

Note than when both .exakat.ini and .exakat.yaml are provided, Exakat selects first the .exakat.ini file, unless it cannot be parsed.

Here is an example of configuration, using YAML and the same values as the previous section : 

project: angie-project
project_name: angie, the audit
project_reports:
    - Text
project_themes:
    - Security
ignore_dirs:
  - /assets
  - /vendor
  - /var
  - /web
rulesets:
    My_Rules: 
         "Adding Zero": Structures/AddZero
         "Multiply By One": Structures/MultiplyByOne
         "Concat Empty String": Structures/ConcatEmpty
    My_Rules2:  [Structures/AddZero, Structures/MultiplyByOne, Structures/ConcatEmpty]
    

  • project : This is the name of the project. Use a simple yet telling name, with letters, figures, underscores and dash. This is compulsory. It is used internally, by exakat, for identification. 
  • project_name : this is the name used when building reports. It has fewer constraints than the project entry, and in case any special character is used, enclose the name in quotes. This is compulsory. You will find it in audits, as the title of HTML pages, for example.
  • project_reports is an array that contains the expected reports. By default, Exakat will produce the Text, and output it to the standard output. This is suitable for CI. If you want other reports, for example Ambassador, add them here, one by line. All the reports are available in the Manual
  • project_themes is an array that contains the expected rule sets. By default, Exakat will run the Analyze. If you want more analysis to be run, Security, add them here, one by line. All the standard Exakat rule sets are available in the Manual. It is not possible to configure a customized rule set in this file.
  • rulesets is an array of rule sets. Each ruleset is defined by its unique name, and a list of analysis to run. Here, you can findd the My_Rules rule set, which contains three analyses. Each analysis is configured with an optional property name, and its analysis identifiers. The property name is optional, as long as it is unique. The property names used in this example were produced with the ExakatYaml report, and include both the human readable title for the configured analysis, and their analysis identifier. Only the analysis identifier is used during execution, and the property names are here for documentation. 

Analysis identifiers are available in the online Manual, and they all have a distinct name. You will also find them in the documentation. 

Testing Exakat Like CI direct installation

The direct installation is the same as previously, whatever the usage of Exakat. You can find the Installation instruction in the manual. Let’s assume that the path of the installation of Exakat is /usr/local/sbin, and that the Gremlin database is functional. 

After having configured Exakat as mentioned in the previous sections, you can do the following : 

> cd /path/to/code
> php /usr/local/sbin/exakat.phar project 

Exakat finds the .exakat.* file, and runs the audit, and displays the result in stdout or in the same folder. 

docker usage

Exakat runs also with a docker container. First, pull the image : 

docker pull exakat/exakat:latest

Once the image is downloaded, and the configuration file ready, you can use the following command : 

> cd /path/to/code
> docker run -it --rm -w /src -v $(pwd):/src --entrypoint "/usr/src/exakat/exakat.phar" exakat/exakat:latest project

Exakat finds the .exakat.* file, and runs the audit, and displays the result in stdout or in the same folder. 

Configuring Exakat for various CI

In the following section, we’ll describe how to configure exakat to run on the following Continuous Integration systems : 

If your favorite CI system is not available, check if some of the instructions below are not applicable. You may also join the Exakat slack

Configuring Exakat for Gitlab CI

Gitlab runs its CI pipeline, and take advantage of docker containers. Here is an exakat stage for your .gitlab-ci.yml file. 

stages:
  - lint
  - exakat
  - build
  - test

exakat:
  stage: exakat
  image: exakat/exakat:latest
  script:
    - exakat project 

The stages list may include any other stage. The exakat stage is based on the Exakat Docker image, and it is publicly available. It is updated with every new version. 

The Exakat binary is already configured in this container : the invocation is very short. If any issue is spotted, Exakat exits with code 1, and displays the found issues. If no issue was spotted, Exakat exits with 0, and displays nothing. 

Configuring Exakat for Bitbucket Cloud

Bitbucket Cloud runs its CI pipeline, and take advantages of docker container. Here is an exakat step for your bitbucket-pipelines.yml file. 

image: exakat/exakat:latest

pipelines:
  default:
    - step:
       script: 
        - echo 'I start Exakat's Code Review'
        - exakat project

The steps may include any other step to be processed in your CI. The exakat step is based on the Exakat Docker image, and it is publicly available. It is updated with every new version. 

The Exakat binary is already configured in this container : the invocation is very short. If any issue is spotted, Exakat exits with code 1, and displays their issue found. If no issue was spotted, Exakat exits with 0, and no display. 

Exakat results at Bitbucket Cloud

The config file used is .exakat.ini or .exakat.yaml located at the root of your path/to/code.

Configuring Exakat for Travis-ci

Travis-ci works with docker images, with a service aptly named docker and one line of installation. 

language: php

services:
  - docker

before_install:
  - docker pull exakat/exakat:latest

script:
  - docker run -it --rm -w /src -v $(pwd):/src --entrypoint "/usr/src/exakat/exakat.phar" exakat/exakat:latest  project
Exakat results at Travis-ci.org

The docker command is long, and quite standard. -w sets the working directory, to be the source directory. The src directory is set as the current directory, and then exakat is called with the command project. Then, the .exakat.yml or .exakat.ini is used. 

Configuring Exakat for Jenkins

Jenkins is another popular CI server where the use case is to run your CI process inside your own infrastructure to avoid to expose your very secret code on the Cloud. 

Our use case is based to the following approach :

  • Jenkins is installed on premise on your server
  • Exakat is installed on premise on the same server
    • See the Installation for more details to install Exakat Engine on your server
  • The .exakat.ini or .exakat.yaml config file is located in your /path/to/code repository

In your Jenkins project, Build section :

  • add a new step to your build
  • select the Execute shell script on remote host using ssh step type
  • define the following command lines
Exakat Step in Jenkins Build
cd /path/to/exakat
php exakat.phar upgrade -u
cd /path/to/code
php /var/www/exakat/exakat.phar project
  • exakat.phar upgrade -u : This command update Exakat Engine to the latest release
  • exakat.phar project : This command launch the analyse base on the .exakat.ini or .exakat.yaml config file. By the way, all the options of the project command keep allowed.

Then launch a build …

Exakat results in Console Output with Jenkins Configuring Exakat for CircleCI

Circleci requires a .circleci/config.yml. The following code is a job that runs Exakat on the code. You have to add this job to your workflow to make it run.

version: 2.0

jobs:
  exakat:
    docker:
      - image: exakat/exakat:latest
    steps:
    - checkout
    - run:
        command: exakat project
Customize Your Coding Reference

Including Exakat in your CI is a great way to monitor closely your code. Adding the .exakat.yml file allows you to configure the analysis to run, and the CI will apply systematically the checks before the code is pushed to production. 

There are standard list of analysis, available in Exakat : SecurityPerformancesMigration 7.4Classreview, etc. They are ready to use, and require no configuration.

With experience, you’ll find important to tailor that list to meet your local standard. Some analysis are important for your code base, but others are less critical, and may be omitted reasonably. For that, use the rule set configuration, and build your list incrementally. You may also take a look at the ‘ExakatYaml‘ report, which lists the analysis that yielded no results in the previous audit : this is a good start to make a selection.

The post Add Exakat To Your CI Pipeline appeared first on Exakat.

  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
Exakat 1.8.1 Review

Exakat 1.8.1 brings several new reports formats for a better bug hunt. This week, we introduce the Top 10 reports, the Yaml and the ExakatYaml reports. Plus Json, Text and XML got upgraded with extra new fields. The Exakat 1.8.1 review is all in the reports! 

Start collecting your own success

The ExakatYaml report was created to help select the analysis that you want to apply to your code base. 

Initially, Exakat comes with several practical rulesets, such as ‘Analyze‘, ‘Classreview‘, ‘Security‘, ‘Performances‘, etc. They are convenient, and used by the distribution reports, so you don’t have to configure anything until you are more experienced with the engine.

As Exakat becomes more familiar, it becomes necessary to tailor the list of analysis to run to your particular coding style. This means cherry-picking a solid list of rules out of the few hundreds available. This is a lot.

To get you started, the ExakatYaml report is here to help you. It reviews the last reports, and provides the list of analysis, ready to use in the configuration file, and sorted by the number of issues that were found. This looks like this : 

rulesets:     ruleset_0: # 0 errors found
"Avoid option arrays in constructors":               Classes/AvoidOptionArrays
"Bad Constants Names":                               Constants/BadConstantnames
"Can't Count Non-Countable":                         Structures/CanCountNonCountable
"Can't Extend Final":                                Classes/CantExtendFinal
"Can't Throw Throwable":                             Exceptions/CantThrow
"Cant Inherit Abstract Method":                      Classes/CantInheritAbstractMethod
"Cant Instantiate Class":                            Classes/CantInstantiateClass     ruleset_1: # 1 errors found
"$this Belongs To Classes Or Traits":                Classes/ThisIsForClasses
"Assign And Compare":                                Structures/AssigneAndCompare
"Avoid set_error_handler $context Argument":         Php/AvoidSetErrorHandlerContextArg
"Callback Needs Return":                             Functions/CallbackNeedsReturn
"Could Use str_repeat()":                            Structures/CouldUseStrrepeat
"Don't Change Incomings":                            Structures/NoChangeIncomingVariables
"Don't Echo Error":                                  Security/DontEchoError     ruleset_2: # 2 errors found
"Casting Ternary":                                   Structures/CastingTernary
"Could Use Short Assignation":                       Structures/CouldUseShortAssignation
"Empty Try Catch":                                   Structures/EmptyTryCatch     ruleset_3: # 3 errors found
"Else If Versus Elseif":                             Structures/ElseIfElseif
"If With Same Conditions":                           Structures/IfWithSameConditions
"Multiple Constant Definition":                      Constants/MultipleConstantDefinition     ruleset_4: # 4 errors found
"Direct Injection":                                  Security/DirectInjection
"Don't Unset Properties":                            Classes/DontUnsetProperties     ruleset_5: # 5 errors found
"No Substr Minus One":                               Php/NoSubstrMinusOne
"Undefined Class Constants":                         Classes/UndefinedConstants     ruleset_6: # 6 errors found
"Avoid sleep()/usleep()":                            Security/NoSleep 

One rule set is created for all the rules that returns currently no results : this is ruleset_0. Then, there is ruleset_1, which collects all rules that reported only one result, and ruleset_2, which collects all rules that reported only two results, etc. 

Each list is configured with the documentation name of the rule, on the left. For example, "Avoid option arrays in constructors": Classes/AvoidOptionArrays. The title itself is easier for us, humans, to read the configuration, and the important part for Exakat is the right side, the rule ID. Here, it is Classes/AvoidOptionArrays.

This report is in Yaml format, so you can edit it as you like before putting it in the configuration file .exakat.yml. 

Top 10 Classic PHP Traps

If you have been to PHP Serbia, in English, or AFUP Marseille, in French, you may have listened to the popular Top 10 Classic PHP Traps (slides), with a wide selection of little-known features and sneaky bugs that come with using PHP. They do have their own dedicated report, so you can à your code for them, right after listening to the presentation. The top 10 includes a dashboard with grades applied to each participant of the top 10. 

Some of the entries are actually spread over several analyses. For example, ‘No arraymerge in loops’ is actually checking for arraymerge, but also for fputcsv() or concatenations in loops, which may be speeding up significantly, as explained in the presentation. All are documented directly in the report. 

The top 10 is usually included in many other reports, so you may also access it, even after running an audit, with the following command : 

php exakat.phar report -p <my_project> -format Top10 

Yaml report, and upgrade for Text

The Yaml report is a new report with Exakat 1.8.1. It is from the same family as TextJson, or XML

Those reports are machine-oriented reports : they are meant to be an exchange format with other software, may it be CI, dashboards, command line scripts or spreadsheets. They are convenient when you need to reworks Exakat’s massive information database, and only need a specific part of it. 

/repository/Templates/helpers/breadcrumb.php:8 Functions/AvoidBooleanArgument Use Named Boolean In Argument Definition public function __invoke($showCurrentItem = true) { /**/ }  
/repository/Listener/QuoteListener.php:51 Classes/WeakType Weak Typing if($page !== null) { /**/ }  
/repository/Command/FakeDataCommand.php:168 Performances/PrePostIncrement Pre-increment $i++ 

With those reports, you can specify a list of rules to extract, using two options. -T expects a rule set, such as Analyze or Security. -P expects a rule Id, such as Performances/PrePostIncrement, or Functions/AvoidBooleanArgument. It is possible to use multiple -P options, but not multiple -T options. 

> php exakat.phar  report -p <myproject> -P Functions/AvoidBooleanArgument -P Performances/PrePostIncrement -format Json -file stdout

> php exakat.phar  report -p <myproject> -T Security -format Text

Depending on the report’s default, the result may be written to the disk, or to stdout. This is controlled with the -file option. It accepts either stdout, for display to the command line, and otherwise, a file name. The file will be located in projects/<my_project>/, with its own extension. 

The Weekly Audits: 2019, Week #22

Exakat includes a ‘weekly’ report: this report is built with a selection of five analyses. This means a short audit report, with few issues to review. This is not a lot to read them, and review them in your code. Everyone in the PHP community can focus on one of the classic coding problems and fix it. Talk about the weekly audit around you: you’ll find programmers facing the same challenges.

To obtain the ‘weekly’ audit, run an audit, and request the ‘Weekly’ report.

# Init the project (skip when it is already done)    
php exakat.phar init -p <yourproject> -R https://github.com/Seldaek/monolog.git -git 

# Run the project (skip when it is already done)    
php exakat.phar project -p <yourproject> 

# Export the weekly project (every monday)    
php exakat.phar report -p <yourproject> -format Weekly 

# Open projects/<yourproject>/weekly/index.html in your browser    

Every week, you can find here 5 new analysis to review in your code. In fact, when your code is clean, you can also take a quick look at the upcoming 

Weekly recommendations for PHP code review : 2019, week 2019-22

Happy PHP Code Reviews 

All the 357 analyzers are presented in the docs, including the grand :  Redefined Class Constants. Unlike global constants, class constants may be redefined by a child class, leading to multiple values for the same syntax. It is an unusual bug (15%).

You can check all of the Exakat reports at the gallery: exakat gallery.

Download Exakat on exakat.io, install it with Docker, upgrade it with ‘exakat.phar upgrade -u’ and like us on github.

The post Exakat 1.8.1 Review appeared first on Exakat.

  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
Exakat 1.8.0 Review Exakat 1.8.0 review

Exakat 1.8.0 main new feature is the support for ‘in-code review’ : using .exakat.yml, you may run an audit from within the repository. This is particularly useful for CI. More PHP 7.4 support was added, with the upcoming change of precedence with addition and concatenation. For the current versions, Exakat is now reporting useless arguments in methods, and validation mistakes with functions returning -1. This is all you ever wanted to know about the Exakat 1.8.0 review! 

Support for PHP 7.4

PHP 7.4 is packing up a lot of new features, and that will last until July 18th. This is the date of the feature freeze, where all expected features will be known, and all other features will be pushed to PHP 8.0, the following year. We are also seeing the first incompatibility with PHP 7.4 forming, so it is time to get prepared. 

In particular, addition and concatenation are now of different precedence, while ternary operators are requiring parenthesis usage. This may affect your code.

Addition, concatenation precedence

Until PHP 7.3, addition and subtraction, had the same precedence than concatenation. That is, higher than comparison, but lower than multiplication. At least, that doesn’t change.

On the other hand, addition and concatenation have the same precedence, so their order of application depends on the order of writing. For example : 

<?php   
  $a = 1;
  $b = 2;
  echo '$a + $b = ' . $a + $b;
?>

This displays 2. In fact, PHP finds the concatenation . first, and concatenate '$a + $b = ' with 1 first. This leads to a first string, '$a + $b = 1', which is then added to the variable $b. Since the first string can’t be turned into an integer, it is then turned into 0, with a nice warning : PHP Warning: A non-numeric value encountered. Eventually, 2 is displayed.

As humans, we’d like to read that $a + $b is computed first, then concatenated to the string, which acts as a label. This would be the case with parentheses : 

<?php   
  $a = 1;
  $b = 2;
  echo '$a + $b = ' . ($a + $b);
?>

PHP 7.4 changes the precedence for concatenation and addition, leaving addition with a higher precedence. The previous code will then work without the parenthesis. 

Until then, it is important to always add the parenthesis. It will also be important to keep those parenthesis when backward compatibility is important.

A new analysis ‘Php/ConcatAndAddition’ was added to Exakat to cover those situations. It reports any mix of ., + and - operators that are lacking parenthesis. 

This analysis applies to every PHP version. This is not common, as such migration analysis are usually targeting one specific version, or a range of version. Yet, the problem of precedence may affect any piece of code, and it is recommended to check them, whatever the version.

Useless Arguments

Arguments may be useless for two reasons : they are never used inside the function (or method), or they are always the same. 

Unused Arguments

Unused argument is bad practice. They must be provided at a function call, but later, they are not used. This is a waste of argument, and a pain for any API user. You can find those in your code with the Unused arguments rule. 

  
<?php   
  function diviser($a, $b, $c) {  
    return intdiv($a, $c);
  }
?>

Arguments are not considered unused if they are enforced by an interface or an abstract method. Those are compulsory, and require update of the parent, and may be, the sister classes.

Always The Same Argument

Now, consider the following code : 

<?php   
  function foo($a, $b) {  
    return intdiv($a, $b);
  }

  foo($a, 2);
  foo(100, 2);
  foo(201, 2);
?>

This piece of code is seriously academic, but the content is the following : one function definition, with 2 arguments; three usages of the function, where the second argument is always the same, 2. This is a strange piece of code, but it serves our purpose, and there is no point in displaying 3 pages of code, just to hide the calls to foo.

So, function foo was defined with 2 arguments, but the second argument is always the same. This leads to consider that this argument is actually useless. Think that if it is moved inside the function, and hard-coded, that will require fewer arguments. 

This example illustrates the difference between planning and application. The foo function was built to return the remainder of the division of $a by $b. It does make sense assuming that a large range of values could be used with this function, and indeed, the native PHP function intval()does accept a lot of values (although a check on 0 would be nice here).

On the other hand, every call to this function uses the same second argument. The function may be simplified by reducing the number of arguments, and the number of decisions to make when calling it. 

Keeping the arguments is a bet on the future : it may be useful later. Removing it is a check on the past : we haven’t used this. Depending on how the feature is perceived, you will be able to decide for your own code. 

Validation mistakes

Where is this going wrong? 

  
<?php   
  if (openssl_verify($data, $signature, $public_key)) {  
    user_login($user);
  }
?>

The variables are not important here, as the problem lies with openssl_verify and its usage. openssl_verify checks a signature for some data, with a public key. It return 1 in case of success, and 0 in case of failure. Since 1 is true for PHP, and 0 is false, then the condition above applies.

The trouble is that openssl_verify() returns -1 in case of error. For example, when the key is not a valid public key. This means that the previous condition is now returning -1, and in PHP, -1 is true. To gain access to the user, one simply has to botch the signature, and the error will grant way. 

This problem is similar to the infamous Strpos()-like Comparison, where the absence of result (false) is mistaken with a value found on the first offset(0). Here, success and errors are the same. 

The safe way with this function is to compare it to the actual return value, either 0 or 1. openssl_verify() return integers. This will ensure that 1 and -1 are not mistaken one for another.

There are another 13 native PHP functions that return -1 in case of error, such as pgfieldnumpcntl_waitpid, and several openssl functions, like opensslpkcs7verify(), opensslx509checkpurpose(). Avoid using them as strait conditions, and always compare their result to a value. 

Thanks to RIPS for raising awareness about this security problem, with their very challenging series of tweet : Can you spot the vulnerability? (openssl_verify). The problem has been at large for a while now : Incorrect Signature Verification.

The Weekly Audits: 2019, Week #21

Exakat includes a ‘weekly’ report: this report is built with a selection of five analyses. This means a short audit report, with few issues to review. This is not a lot to read them, and review them in your code. Everyone in the PHP community can focus on one of the classic coding problems and fix it. Talk about the weekly audit around you: you’ll find programmers facing the same challenges.

To obtain the ‘weekly’ audit, run an audit, and request the ‘Weekly’ report.

# Init the project (skip when it is already done)    
php exakat.phar init -p <yourproject> -R https://github.com/Seldaek/monolog.git -git 

# Run the project (skip when it is already done)    
php exakat.phar project -p <yourproject> 

# Export the weekly project (every monday)    
php exakat.phar report -p <yourproject> -format Weekly 

# Open projects/<yourproject>/weekly/index.html in your browser    

Every week, you can find here 5 new analysis to review in your code. In fact, when your code is clean, you can also take a quick look at the upcoming 

Weekly recommendations for PHP code review : 2018, week 2019-21

Happy PHP Code Reviews 

All the 352 analyzers are presented in the docs, including the grand :  Test Then Cast: A test is run on the cast value, but the raw value is later used. It is a common bug (32%) 

You can check all of the Exakat reports at the gallery: exakat gallery.

Download Exakat on exakat.io, install it with Docker, upgrade it with ‘exakat.phar upgrade -u’ and like us on github.

The post Exakat 1.8.0 review appeared first on Exakat.

  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
Exakat 1.7.9 Review

Exakat 1.7.9 is bringing a wide range of updates and upgrades. First, support for PHP 7.4 is growing, with arrow functions and spread operators in arrays, and ffi extension. Then, we extended the nested ternary, in preparation for PHP 7.4’s non-nesting features. And finally, the Inventory report added the inclusions list, while Ambassador got an upgrade of the global inventory. You’ve got to keep moving forward to the Exakat 1.7.9 review! 

Exakat 1.7.9 review
Support for PHP 7.4 syntax

PHP 7.4 is still a few months away (December 2019), but the list of upgrade recommendations is already available. In particular, PHP 7.4 will introduce new syntax, such as arrow functions and spreads in array. Exakat is already supporting those new features! 

Arrow functions

Arrow functions are a new and shorter way to write a closure. Closure is already a lesser version of a function, without a name, and with more context integration. Arrow functions are an even shorter version. 

Taken from the RFC, here is the same code, written in two different versions : 

<?php    
function array_values_from_keys($arr, $keys) {      
   return array_map(function ($x) use ($arr) { return $arr[$x]; }, $keys); 
}
?>
<?php 
function array_values_from_keys($arr, $keys) {
     return array_map(fn($x) => $arr[$x], $keys);
}
?>

Both code applies a function to the array $arr, to extract a specific set of values, based on a set of keys. Note how the second syntax is much shorter. 

First, PHP 7.4 introduces the fn keyword. This keyword introduces the new syntax, and helps disambiguate the code from arrays and yield, which are also depending on the => operator. This also means that the code can’t use fn as a class or function name. This was checked, and it is extremely rare. 

Secondly, there are no curly brackets, and no return statement : after the double arrow =>, there is only one expression. There is no room for a block with multiple expressions. Arrow functions are for short expressions that need to be repeated or moved around. If the need emerges, more expression may be added, but it is not the case at the moment.

Arrow function will cut down on boiler plate code, and keep the code short. 

Support for the arrow functions was added to Exakat. It is now able to compile and manipulate arrow functions, just like closures and methods. The engine has been tested with arrow functions, and the analysis is upgraded to handle them too. 

Spread operator

Also known as variadic or ellipsis, the spread operator turns an array of array into distinct arguments. 


<?php 
$array = [[1,2,3],[4,5,6],[7,8,9]]; $list = array_merge(...$array); 
?>

Here, array_merge accepts an arbitrary number of arguments, and the ... operator spreads the elements from the $array array into distinct arguments, leading to the merge of all elements in one call. This is a great speed up. 

Strangely enough, the ... operator is not allowed in arrays themselves. While it is possible to use array_merge to combine multiple arrays into one, it could also be efficient to merge arrays together to form a new array. This is the case with PHP 7.4, since 2019-05-13 (that is yesterday, for those who read this in the future).

<?php 
   $list = [...[1,2,3], ...[4,5,6], ...[7,8,9]]; 
?>

The spread operator was already supported by the Exakat engine. In fact, it is interpreted just like any other call to a spread operator in a function or method call. Exakat first tokenize the code with PHP itself, and since PHP itself yielded a Fatal error, those files were not available for analysis. PHP 7.4 now accepts them and so is Exakat. 

We’ll be adding spread operator specific analysis in the future. 

FFI extension

The FFI extension is the Foreign Function Interface. It is an experimental function that “allows the loading of shared libraries (.DLL or .so), calling of C functions and accessing of C data structures in pure PHP, without having to have deep knowledge of the Zend extension API, and without having to learn a third “intermediate” language. ” You may learn more about FFI on Anthony Ferrara’s A PHP Compiler, aka The FFI Rabbit Hole blog post.

Unrelated to PHP 7.4, the UUIDpasswordzend monitor and svm, for Support Vector Machine Library, extensions were added to the list of supported extensions. Do not confuse this last one with the SVN extension. 

Nested Ternaries Gets A Facelift

Nested ternaries are getting a facelift, both in Exakat and PHP. 

First, in Exakat, nested ternaries are now taking into account parentheses. Until now, only directly nested ternaries were reported, while now, even the one written in parentheses are added. 

Nested ternaries, with or without a parenthesis, are reported for poor readability. Two are immediately difficult to read, and the author has experienced a 6-level ternary monster expression. 

<?php
// nested and unreadable  
$a = $b ? $c ? $d : $e : $f;

// nested, unreadable and parenthesed  
$a = $b ? ($c ? $d : $e) : $f;

?>

In PHP 7.4, ternary operators are also getting a facelift. Since almost all other languages have a right associative ternary operator, it is confusing when switching from one language to the next. Since it would break too much code by switching the precedent from left to right, any ambiguous ternary operator will be flagged with a PHP Deprecation Warning.

<?php   
$a = $b ? $c ? $d : $e : $f ? $g : $h ;

//PHP Deprecated:  Unparenthesized `a ? b : c ? d : e` is deprecated. Use either `(a ? b : c) ? d : e` or `a ? b : (c ? d : e)`   
?>

// Note that the variable names are missing the initial $ : this is probably a development artefact. 

Not every nested ternary expressions will be flagged : only the one that are ambiguous, and may yield an different result than the one written. 

This feature is backward compatible. Simply, the code will need an update before moving to PHP 7.4. According to the EPIC (Exakat PHP Index of Coding, 12,2% of PHP code has to be upgraded.

Inclusion inventories

The Exakat report called ‘Inventory’ was upgraded with two new reports : inclusion list and global variable list.

The Inventory report collects all sorts of assets from the code, and deliver them as csv files. For example, you may review all your regex or variable names, gathered in the same place.

The csv format makes it easy to import those inventories into another data manipulation tool, such as Open Office spreadsheets, so that you may apply your own transformations before reporting them.

The inclusions list

This list collect all the inclusion calls, which are include, require, includeonce and requireonce, with their actual argument. The second column holds the name of the calling file. 

/tbl_select.php,"require_once ROOT_PATH . 'libraries/common.inc.php'" 
/tbl_select.php,"require_once ROOT_PATH . 'libraries/tbl_common.inc.php'"
 /error_report.php,"require_once ROOT_PATH . 'libraries/common.inc.php'"
 /db_multi_table_query.php,"require_once ROOT_PATH . 'libraries/common.inc.php'"

Inclusions have a few dedicated analysis in Exakat : Inclusion Wrong Case and Missing includecome to mind. 

Yet, the rules to build an inclusion path may be complex, and guessing them is out of the scope of Exakat. This is where inventories are a great start : all the occurrences of inclusion have been collected and gathered in one place. Add your own magic, and check if any of those inclusion are wrong or not.

Global Variables

Global variables were also added to the inventories system. They are also upgraded in the Ambassador report : 

Globals are now grouped by name, so you may have a better view over their location. Here, we can spot that most global variables are only used in one file, which reduces the risk of contagion.

Then, the second column indicates the type of global : it may be one of ‘implilcit’, ‘global’ or ‘$GLOBALS’, depending on the origin. ‘global’ means that the variable was explicitly declared, $GLOBALS means that it is accessed via the supreglobal $GLOBALS, and ‘implicit’ means that it is in the global space, and it is never explicitly made global, though PHP will make it global by default. 

The next column mentions if the variable is read R or modified W. This is interesting, since the example used here show some global variables such as $children or $createMisc which are written and read : this is the best combination, as it shows that the variable is both assigned and used. Yet, there are other variables which are read only, such as $productType. There are also situations where the variable usage is split over multiple files, or written only. 

With such an overview of the global variables, it is now easy to review them, and start removing them, or moving them to other storage locations. In particular, this is mostly useful when the global usage is spread across multiple files.

The Weekly Audits: 2019, Week #20

Exakat includes a ‘weekly’ report: this report is built with a selection of five analyses. This means a short audit report, with few issues to review. This is not a lot to read them, and review them in your code. Everyone in the PHP community can focus on one of the classic coding problems and fix it. Talk about the weekly audit around you: you’ll find programmers facing the same challenges.

To obtain the ‘weekly’ audit, run an audit, and request the ‘Weekly’ report.

# Init the project (skip when it is already done)    
php exakat.phar init -p <yourproject> -R https://github.com/Seldaek/monolog.git -git 

# Run the project (skip when it is already done)    
php exakat.phar project -p <yourproject> 

# Export the weekly project (every monday)    
php exakat.phar report -p <yourproject> -format Weekly 

# Open projects/<yourproject>/weekly/index.html in your browser    

Every week, you can find here 5 new analysis to review in your code. In fact, when your code is clean, you can also take a quick look at the upcoming 

Weekly recommendations for PHP code review : 2019, week 2019-20

  • Parent First : When calling parent constructor, always put it first in the __constructmethod.
  • Substring First : Always start by reducing a string before applying some transformation on it.
  • Aliases Usage : PHP manual recommends to avoid function aliases.
  • Logical Mistakes : Avoid logical mistakes within long expressions.
  • Use List With Foreach : Foreach() structures accepts list() as blind key.
Happy PHP Code Reviews 

All the 352 analyzers are presented in the docs, including the grand : Could Use str_repeat(): Use strrepeat() or strpad() instead of making a loop.

It is still an unusual suggestion (12%), though it is nice to review one’s code and upgrade it with it! 

You can check all of the Exakat reports at the gallery: exakat gallery.

Download Exakat on exakat.io, install it with Docker, upgrade it with ‘exakat.phar upgrade -u’ and like us on github.

[]

The post Exakat 1.7.9 Review appeared first on Exakat.

Read for later

Articles marked as Favorite are saved for later viewing.
close
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

Separate tags by commas
To access this feature, please upgrade your account.
Start your free month
Free Preview