<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Peter Fox</title>
    <description>The latest articles on DEV Community by Peter Fox (@peter_fox).</description>
    <link>https://dev.to/peter_fox</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F141551%2Fd3d1ea66-b7ec-4393-a2f0-15d0171d2c86.jpg</url>
      <title>DEV Community: Peter Fox</title>
      <link>https://dev.to/peter_fox</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/peter_fox"/>
    <language>en</language>
    <item>
      <title>Mastering PHP: Type Hinting techniques</title>
      <dc:creator>Peter Fox</dc:creator>
      <pubDate>Fri, 27 Sep 2024 17:01:44 +0000</pubDate>
      <link>https://dev.to/peter_fox/mastering-php-type-hinting-techniques-3g8e</link>
      <guid>https://dev.to/peter_fox/mastering-php-type-hinting-techniques-3g8e</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AGSzo9f-SElYUUjrJ" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AGSzo9f-SElYUUjrJ"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by 𝓴𝓘𝓡𝓚 𝕝𝔸𝕀 on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Type hinting is considered by some to be the holy grail of features. One that all programming languages must have. PHP for the longest time didn’t have such a system but has now been adopted widely by most developers.&lt;/p&gt;

&lt;p&gt;That said, PHP’s type system doesn’t go as far as other languages. Many implement what are known as Generics. This is the ability to enforce a type among structures and Collections. For instance, in Java we can specify that Arrays must only contain items of a certain type, for example, an Array of Strings.&lt;/p&gt;

&lt;p&gt;Maybe someday we’ll have this functionality in PHP as well, but until then we can actually solve this with a few different techniques. For a lack of a better description, I refer to these as &lt;em&gt;Soft Type hints&lt;/em&gt; and &lt;em&gt;Runtime hints&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Type Hints
&lt;/h3&gt;

&lt;p&gt;The first and most obvious type hints are the ones introduced in PHP 7 and are still being added to PHP. Type-hinted constants were only added in PHP 8.3.&lt;/p&gt;

&lt;p&gt;Type hints are useful to help convey what needs to be passed to a method or function as a parameter or what that method will return. Type hints are going to affect the signatures of any classes they use them with as extending a class with type hints already established will mean they can’t be overridden.&lt;/p&gt;

&lt;p&gt;An example of a class that makes full use of types would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

class Foo
{
    public function bar(array $strings): \Closure
    {
       return function (string $string) use ($strings): bool {
           return in_array($string, $strings);
       };
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are, of course, limitations in our type hints because as previously mentioned, we can’t conform an array to be all of the same type and instead we must just use array . We also can’t constrain numbers to being only positive or within a certain range.&lt;/p&gt;

&lt;p&gt;Another one can be Closures as there’s no way to describe anonymous functions within PHP’s native types. Instead, we must either use \Closure or callable . Often callable isn’t allowed to be used as a type as well.&lt;/p&gt;

&lt;p&gt;Luckily, there’s still a way to describe these more complicated scenarios with type hints.&lt;/p&gt;

&lt;h3&gt;
  
  
  Soft Type Hints
&lt;/h3&gt;

&lt;p&gt;Our next kinds of type hints are supplied via PHPDocs. While native types will throw exceptions during run time if a method is passed or returns the wrong type, PHPDoc type hints have no effect on the runtime of the application.&lt;/p&gt;

&lt;p&gt;Instead, soft type hints help us purely when we’re using an IDE such as VS Code or PHPStorm, which will detect those types for us. The other use case is with static analysis tools like PHPStan and subsequently Rector.&lt;/p&gt;

&lt;p&gt;The biggest advantage of using soft types is that it allows you to describe with more precision the type of any parameters, properties, etc. For instance, we can take the previous class and make it easier to understand the arrays or closures used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

class Foo
{
    /**
     * @param string[] $strings
     * @return \Closure(string): bool
     */
    public function bar(array $strings): \Closure
    {
       return function (string $string) use ($strings): bool {
           return in_array($string, $strings);
       };
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The best way to make sure all your type usage is correct is to install PHPStan. From there you’ll likely need to use at least level 5. This can then be enforced through continuous integration steps that check the type hinting is correct.&lt;/p&gt;

&lt;p&gt;There’s actually a list you can use if you want to use the correct soft type hint. Even better, there’s a PHPStan tool you can use to test if all the type hinting it correct per PHPStan if you’re unsure and want to run a quick test.&lt;/p&gt;

&lt;h3&gt;
  
  
  Runtime Hints
&lt;/h3&gt;

&lt;p&gt;Our next way of supporting types is to use runtime hints. What this actually means is executing our own code to check the types from parameters. For instance, we can check if an array only contains a particular type of object. If it doesn’t, then we throw an InvalidArgumentException.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

/**
 * @param string[] $foo
 */
function bar(array $foo) {
    foreach ($foo as $string) {
        if (! is_string($string)) {
            throw new \InvalidArgumentException('foo contains non-string value');
        }
    }

    // rest of the code
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the way, this technique is sometimes referred to as defensive programming. Looking at the code example, this is pretty cumbersome. It’s a lot of code just to simply check if an array is correct. That’s why we often resort to a library instead, in this case webmozart/assert .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require webmozart/assert
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now with this package installed we can shorten this down to a simple one-liner.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

use Webmozart\Assert;

/**
 * @param string[] $foo
 */
function bar(array $foo) {
    Assert::allStrings($foo);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One of the great things about this library is if you add the Assert extension to PHPStan, this will help your type coverage when the code is analysed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In conclusion, mastering type hinting in PHP is an essential skill for developers looking to write clean, maintainable, and reliable code. While PHP’s type system still lacks some features found in other languages, such as generics, there are multiple strategies available to enforce stricter typing — whether through native type hints, PHPDoc annotations, or runtime checks. Leveraging tools like PHPStan and libraries like Assert can help you ensure type safety, even in complex scenarios. By integrating these techniques into your development workflow, you’ll be better equipped to handle PHP’s dynamic nature with confidence and precision.&lt;/p&gt;

&lt;p&gt;I’m Peter Fox, a software developer in the UK who works with Laravel. Thank you for reading my article, I’ve got many more to read at &lt;a href="https://articles.peterfox.me/" rel="noopener noreferrer"&gt;https://articles.peterfox.me&lt;/a&gt;. I’m also now &lt;a href="https://github.com/sponsors/peterfox?frequency=one-time&amp;amp;sponsor=peterfox" rel="noopener noreferrer"&gt;Sponsorable on GitHub&lt;/a&gt;. If you’d like to encourage me to write more articles like this please do consider dropping a small one-off donation.&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>symfony</category>
      <category>wordpress</category>
    </item>
    <item>
      <title>PHP Upgrades: Block regressions with PHPStan</title>
      <dc:creator>Peter Fox</dc:creator>
      <pubDate>Tue, 17 Sep 2024 22:17:58 +0000</pubDate>
      <link>https://dev.to/peter_fox/php-upgrades-block-regressions-with-phpstan-13ae</link>
      <guid>https://dev.to/peter_fox/php-upgrades-block-regressions-with-phpstan-13ae</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ATiIw-xp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AbXQ8YdUPEAfE9vcn" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ATiIw-xp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AbXQ8YdUPEAfE9vcn" width="800" height="534"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Ron McClenny on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Often when people think of PHPStan they typically think of improving Type Coverage. That is really only a small part of what PHPStan is capable of. In this article we’ll learn how to use it to stop upgrade regressions.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is an upgrade regression?
&lt;/h3&gt;

&lt;p&gt;An upgrade regression is when you have functionality in your application that you wish to move away from. This could be code within your application or code within a dependency you’ve installed.&lt;/p&gt;

&lt;p&gt;Often when trying to perform upgrades we can’t do it all in one go. Instead we have to make small incremental changes. Equally as we do this we don’t want other developers to continue to use deprecated methods and properties. In this situation those new method calls etc. are regressions in your progress to upgrade your application.&lt;/p&gt;
&lt;h3&gt;
  
  
  Installing PHPStan and the Deprecation Rules extension
&lt;/h3&gt;

&lt;p&gt;To start tackling upgrade regressions, the first step is to install PHPStan if you haven’t already. You can install it via Composer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require --dev phpstan/phpstan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, you’ll want to add the Deprecation Rules extension, which specifically helps track the usage of deprecated methods, properties, and classes in your codebase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require --dev phpstan/phpstan-deprecation-rules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once installed, you can configure PHPStan to use the deprecation rules by adding it to your &lt;em&gt;phpstan.neon&lt;/em&gt; configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;includes:
    - vendor/phpstan/phpstan-deprecation-rules/rules.neon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running PHPStan with this setup will now flag any deprecated methods, properties, or classes in your codebase. This is an essential step in preventing upgrade regressions as you’ll be notified when deprecated code is used. You can then refactor those instances to ensure your application moves towards newer, supported functionality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Go further with the Disallowed Calls extension
&lt;/h3&gt;

&lt;p&gt;While the Deprecation Rules extension catches deprecated code, the &lt;em&gt;Disallowed Calls&lt;/em&gt; extension offers a way to block specific function calls, method calls, or even entire classes that you no longer want to allow in your codebase. This is particularly useful for more fine-grained control over your code such as code that does not have a deprecation warning.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require --dev spaze/phpstan-disallowed-calls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After installation, you’ll need to configure it in your phpstan.neon file. Here’s an example of how you can disallow certain method calls or functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;includes:
    - vendor/phpstan/phpstan-deprecation-rules/rules.neon
    # add the extension
    - vendor/spaze/phpstan-disallowed-calls/extension.neon

parameters:
    # You can see more example at https://github.com/spaze/phpstan-disallowed-calls/blob/main/docs/custom-rules.md
    disallowedMethodCalls:
        -
            method: 'PotentiallyDangerous\Logger::log()' # `function` is an alias of `method`
            message: 'use our own logger instead'
            errorTip: 'see https://our-docs.example/logging on how logging should be used'Begin writing your own rules
    disallowedFunctionCalls:
        -
            function: 'var_dump()' # `method` is an alias of `function`
            message: 'use logger instead'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This extension is pretty comprehensive meaning you’ll be able to cover the majority of scenarios. Of course there might be some situations that don’t work and for that the best thing is to start learning to write your own rules.&lt;/p&gt;

&lt;p&gt;This is something we’ll get into in another article.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Using PHPStan to catch upgrade regressions is a smart way to make the upgrade process easier, especially in large development teams. Applying PHPStan to your continuous integration setup&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>softwareengineering</category>
      <category>php</category>
      <category>symfony</category>
    </item>
    <item>
      <title>Fix your Type Hints with Configurable Rules and PHP Rector</title>
      <dc:creator>Peter Fox</dc:creator>
      <pubDate>Mon, 02 Sep 2024 16:31:22 +0000</pubDate>
      <link>https://dev.to/peter_fox/fix-your-type-hints-with-configurable-rules-and-php-rector-2agi</link>
      <guid>https://dev.to/peter_fox/fix-your-type-hints-with-configurable-rules-and-php-rector-2agi</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tC54E4ic--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AzgskZvqOHtsHNmwi" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tC54E4ic--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AzgskZvqOHtsHNmwi" width="800" height="425"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Conny Schneider on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Making your own rules to work with Rector PHP can be a bit of a learning curve. That said we don’t have to create new rules to have a big impact on our code. Some rules in the Rector ecosystem can even be configured to make our code base better with minimal effort, you’ll begin to wonder how you could have ever lived without it.&lt;/p&gt;
&lt;h3&gt;
  
  
  Swapping out a Class Type hint for another
&lt;/h3&gt;

&lt;p&gt;In this article I’m going to show you with one rule how you can fix a ridiculously common problem when using the &lt;a href="https://carbon.nesbot.com/docs/" rel="noopener noreferrer"&gt;PHP Package Carbon&lt;/a&gt;. Carbon is kind of the defacto Date Time library for the PHP language.&lt;/p&gt;

&lt;p&gt;Now most people will instantly type hint everything in their applications as \Carbon\Carbon because that’s the class type. It’s how you create instances most of the time, it’s also the main type. If you didn’t know though there is also \Carbon\CarbonImmutable which is also a class type but both behave differently. I won’t get into the whole different of mutable and immutable, googling it will help you understand that better. The point is you might want to swap between Carbon and CarbonImmutable at some point in the future as often CarbonImmutable is less problematic.&lt;/p&gt;

&lt;p&gt;So let’s now look at how we can swap between the two versions using Rector. Please note I won’t explain how to setup Rector here. I have &lt;a href="https://articles.peterfox.me/code-refactoring-using-rector-php-20ca17c71e20" rel="noopener noreferrer"&gt;another article&lt;/a&gt; for that.&lt;/p&gt;

&lt;p&gt;We’ll add the &lt;a href="https://getrector.com/rule-detail/rename-class-rector" rel="noopener noreferrer"&gt;RenameClassRector&lt;/a&gt; rule to our Rector config. Rather than use the withRules() method we’ll instead use the withConfiguredRule() method. This allows us to supply an array to the rule, specifying the fully qualified names that we want to find and what to replace it with. We can see how that comes together in the config file below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// rector.php
&amp;lt;?php

use Rector\Config\RectorConfig;
use Rector\Renaming\Rector\Name\RenameClassRector;

return RectorConfig::configure()
    -&amp;gt;withConfiguredRule(RenameClassRector::class, [
        'Carbon\\Carbon' =&amp;gt; 'Carbon\\CarbonImmutable',
    ]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then once we’ve run the rector command we can see what’s been affected. Hopefully you have an output that’s updated all instances. This is great! But actually, we can improve this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-function now(): \Carbon\Carbon
+function now(): \Carbon\CarbonImmutable
{
- return new \Carbon\Carbon();
+ return new \Carbon\CarbonImmutable();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Swapping out a Class Type hint for an Interface
&lt;/h3&gt;

&lt;p&gt;If you know the Carbon package well enough there’s actually a \Carbon\CarbonInterface and both \Carbon\Carbon and \Carbon\CarbonImmutable implement this. Well we can actually use this rule with interfaces as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// rector.php
&amp;lt;?php

use Rector\Config\RectorConfig;
use Rector\Renaming\Rector\Name\RenameClassRector;

return RectorConfig::configure()
    -&amp;gt;withConfiguredRule(RenameClassRector::class, [
        'Carbon\\Carbon' =&amp;gt; 'Carbon\\CarbonInterface',
        'Carbon\\CarbonImmutable' =&amp;gt; 'Carbon\\CarbonInterface',
    ]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The RenameClassRector rule is actually incredibly clever and will only update the parts that can be changed to an interface. For instance, no name changes should occur with the new keyword.&lt;/p&gt;

&lt;p&gt;Again we can run the Rector command and hopefully it all works as expected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-function now(): \Carbon\Carbon
+function now(): \Carbon\CarbonInterface
{
    return new \Carbon\Carbon();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In conclusion, configuring rules with PHP Rector provides a powerful and efficient way to manage type hints and other code transformations in your project. By leveraging configurable rules like RenameClassRector, you can seamlessly swap out class type hints, or even replace them with interfaces, all with minimal effort. This not only improves your codebase’s flexibility but also ensures consistency across your project. Adding Rector to your Continuous Integration setup with these rules can have a huge impact on your development styles.&lt;/p&gt;

&lt;p&gt;If you want to see more configurable rules I suggest looking at the &lt;a href="https://getrector.com/find-rule?rectorSet=core-type-declarations" rel="noopener noreferrer"&gt;Type Declaration&lt;/a&gt; at &lt;a href="https://getrector.com/" rel="noopener noreferrer"&gt;getrector.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’m Peter Fox, a software developer in the UK who works with Laravel. Thank you for reading my article, I’ve got many more to read at &lt;a href="https://articles.peterfox.me/" rel="noopener noreferrer"&gt;https://articles.peterfox.me&lt;/a&gt;. I’m also now &lt;a href="https://github.com/sponsors/peterfox?frequency=one-time&amp;amp;sponsor=peterfox" rel="noopener noreferrer"&gt;Sponsorable on GitHub&lt;/a&gt;. If you’d like to encourage me to write more articles like this please do consider dropping a small one-off donation.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>symfony</category>
      <category>php</category>
      <category>wordpress</category>
    </item>
    <item>
      <title>Mastering Code Refactoring: A Complete Guide to Using Rector PHP</title>
      <dc:creator>Peter Fox</dc:creator>
      <pubDate>Thu, 22 Aug 2024 15:01:42 +0000</pubDate>
      <link>https://dev.to/peter_fox/mastering-code-refactoring-a-complete-guide-to-using-rector-php-hp1</link>
      <guid>https://dev.to/peter_fox/mastering-code-refactoring-a-complete-guide-to-using-rector-php-hp1</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AsmEzTTn3uD-XEe29" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AsmEzTTn3uD-XEe29"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Matteo del Piano on Unsplash&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Introduction to Rector PHP
&lt;/h3&gt;

&lt;p&gt;In the ever-evolving world of PHP development, keeping your codebase clean, up-to-date, and efficient is crucial. This is where Rector PHP comes into play. If you’ve been wondering how to use Rector PHP, how to install it, or what exactly Rector PHP is, this comprehensive guide is for you. We’ll walk you through the basics, provide a detailed Rector PHP tutorial, and offer insights on PHP Rector and how to use it effectively. By the end of this article, you’ll have a solid grasp of Rector PHP and how it can enhance your development workflow.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is Rector PHP?
&lt;/h3&gt;

&lt;p&gt;Rector was started in 2020, but only got it’s 1.0 release in 2024. It’s a command line tool that performs a static analysis of a code base. From that analysis changes can be applied. I guess a good example of this would be what if your code base was riddled with array() calls when this is now considered an old practise, now replaced by the [] short array syntax.&lt;/p&gt;

&lt;p&gt;Going through a code base to replace this is tedious. We could use a simple find and replace tool but what if there were an array() encapsulated a string or inside a comment that shouldn’t be changed? Now we’re having to check every instance we’re replaced.&lt;/p&gt;

&lt;p&gt;This kind of problem is what Rector excels at. Instead Rector is able to look at the code and know definitively if it’s an array to be replaced.&lt;/p&gt;

&lt;p&gt;You might be asking, PHP CS Fixer can also do this, which is true. But Rector also has PHPStan working under the hood to not only recognise syntax but to also analyse types. This means Rector can detect when a Class has a particular parent class, when a variable is a particular type or what the expected return type of a function. Giving it a far bigger scope for making changes on mass to a codebase.&lt;/p&gt;
&lt;h3&gt;
  
  
  How to Install Rector PHP
&lt;/h3&gt;

&lt;p&gt;This might seem obvious to experienced PHP developers but there’s two primary ways and it really depends how you want to use Rector.&lt;/p&gt;

&lt;p&gt;If you want to use Rector as part of continuous integration it makes sense to install Rector different into your projects through composer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require --dev rector/rector
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But if you were wanting to experiment with Rector on a single or multiple projects to perform upgrades, you might be better off by installing Rector globally by using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer global require rector/rector
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which ever step you chose, the next step will be to create a config in the root directory for a project and include all the folders containing PHP code that you wish to upgrade. That doesn’t include the vendor folder of course as we don’t want to modify that.&lt;/p&gt;

&lt;p&gt;This is what a config for say a Laravel project might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Rector\Config\RectorConfig;
use Rector\Php71\Rector\List_\ListToArrayDestructRector;

return RectorConfig::configure()
    -&amp;gt;withPaths([__DIR__. '/config', __DIR__. '/src', __DIR__. '/tests', __DIR__. '/routes'])
    -&amp;gt;withImportNames(removeUnusedImports: true);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  PHP Rector: How to Use It Effectively
&lt;/h3&gt;

&lt;p&gt;Like in the last section, using Rector can be determined by how you want to use it. Rector applies changes through the selections of Rules. This is the same as PHP CS Fixer. These rules will both detect the issue and then try to fix the problem they’re designed to solve.&lt;/p&gt;

&lt;p&gt;If we wish to use Rector in a continuous integration manner, because we want to make use all of code is as optimised as best as possible as we develop it, we might use only a particular set of rules.&lt;/p&gt;

&lt;p&gt;Rector has sets of rules, often described as Dead Code or Code Quality, which removes code or enhances and optimises respectively. It’s quite advantagous to stick to just these sets as we can be confident they work most of the time. But you should absolutely be aware that the way Rector writes code is never perfect. Often when rules are written they may cover the typical scenarios and may miss some circumstances found it your code base. This could lead to broken code.&lt;/p&gt;

&lt;p&gt;In the event you want to use Rector, you should absolutely have tests written for your application. Without them Rector can easily lead to introducing bugs that you won’t discover until it’s a problem.&lt;/p&gt;

&lt;p&gt;Another thing to consider when using Rector is that you should use a linting tool like PHP CS Fixer. Rector doesn’t look at whitespace, the spaces and newlines between method calls and it’s arguments etc. Using a linting tool should keep the code formatting to the standard you expect after Rector has applied it’s fixes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step-by-Step Rector PHP Tutorial
&lt;/h3&gt;

&lt;p&gt;Now we’re installed Rector and we’re ready to try it out, let’s try applying one rule. Let’s start by updating our config file we made earlier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Rector\Config\RectorConfig;
use Rector\Php71\Rector\List_\ListToArrayDestructRector;

return RectorConfig::configure()
    -&amp;gt;withPaths([__DIR__. '/config', __DIR__. '/src', __DIR__. '/tests', __DIR__. '/routes'])
    -&amp;gt;withImportNames(removeUnusedImports: true)
    -&amp;gt;withRules([
        ListToArrayDestructRector::class,
    ]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the case of this config we’re going to make a replacement of the use of listso that instead we use array restructuring. The changes we would expect to make are like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-list($a, $b) = ['a', 'b'];
+[$a, $b] = ['a', 'b'];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can test this config by performing a dry run of Rector.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rector --dry-run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything has been successful we should now see an output that contains a diff of all the changes to each file, with a list of the rules that made the changes. Our config only lists one rule so only one rule is applied but if more rules are added we’ll see a list of one or more here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzym5knw7z8phhogrme82.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzym5knw7z8phhogrme82.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is then a great time to review the changes and make sure the rule is performing as expected. Once we’re happy we can run Rector again. Without the dry run flag, changes will be written to the files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rector
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After it’s completed we should run our favourite linting tool and then run our tests. That’s it. We’ve now used Rector.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion: Boosting Your PHP Development with Rector
&lt;/h3&gt;

&lt;p&gt;Rector PHP is a powerful tool that can significantly enhance your PHP development workflow by automating code refactoring and ensuring your codebase remains clean and modern. By understanding what Rector PHP is, learning how to install it, and mastering how to use it effectively, you can leverage its capabilities to streamline code updates, improve code quality, and reduce the risk of code feeling like a “legacy” project. Whether you’re integrating Rector into your continuous integration pipeline or using it for large-scale codebase upgrades, Rector is an indispensable asset for any PHP developer looking to maintain a high standard of code excellence.&lt;/p&gt;

&lt;p&gt;You can continue your Rector journey by learning about configurable Rector Rules in this follow up article, &lt;a href="https://articles.peterfox.me/fix-type-hints-configurable-rules-php-rector-1ef5fd1c4fac" rel="noopener noreferrer"&gt;Fix your Type Hints with Configurable Rules and PHP Rector&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to take you knowledge of Rector further I suggest going to &lt;a href="https://getrector.com/" rel="noopener noreferrer"&gt;https://getrector.com/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’m Peter Fox, a software developer in the UK who works with Laravel. Thank you for reading my article, I’ve got many more to read at &lt;a href="https://articles.peterfox.me/" rel="noopener noreferrer"&gt;https://articles.peterfox.me&lt;/a&gt;. I’m also now &lt;a href="https://github.com/sponsors/peterfox?frequency=one-time&amp;amp;sponsor=peterfox" rel="noopener noreferrer"&gt;Sponsorable on GitHub&lt;/a&gt;. If you’d like to encourage me to write more articles like this please do consider dropping a small one-off donation.&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>wordpress</category>
      <category>symfony</category>
    </item>
    <item>
      <title>PHP: Mocking Closures and performing assertions</title>
      <dc:creator>Peter Fox</dc:creator>
      <pubDate>Thu, 06 Jun 2024 13:02:15 +0000</pubDate>
      <link>https://dev.to/peter_fox/php-mocking-closures-and-performing-assertions-5cpl</link>
      <guid>https://dev.to/peter_fox/php-mocking-closures-and-performing-assertions-5cpl</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eg4JZa5O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2A3bsGv9fY1arLqp0l" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eg4JZa5O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2A3bsGv9fY1arLqp0l" width="800" height="534"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by rivage on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Testing is crucial to ensuring code quality and reliability in modern PHP development. One powerful technique in testing is mocking, which allows you to simulate and control the behaviour of dependencies. Mocking closures can be useful when verifying interactions with anonymous functions or passing them around as first-class callables. This article will explore how to mock or spy closures in PHP using the popular testing library, Mockery.&lt;/p&gt;
&lt;h3&gt;
  
  
  What does our class that needs testing look like
&lt;/h3&gt;

&lt;p&gt;For an example Class I will use a Laravel Validation rule. They’re simple classes that only implement one method, but the third argument for the method is for a Closure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

class Uppercase implements ValidationRule
{
    /**
     * Run the validation rule.
     */
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if (strtoupper($value) !== $value) {
            $fail('The :attribute must be uppercase.');
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How can we easily test this class? Let's make a closure that manipulates a boolean to set it as true if it has been called.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

class UppercaseTest extend TestCase
{
    public function testItFailsNonUppercaseValues()
    {
       $calledClosure = false;

       (new Uppercase)-&amp;gt;validate(
           '', 
           'lowercase',
           fn () =&amp;gt; $calledClosure = true
       );

       $this-&amp;gt;assertTrue($called);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That solution would be fine, but this might become difficult to manage for more complicated situations. For example, what if the Closure is called more than once? Or you want to check which parameters it’s received.&lt;/p&gt;

&lt;p&gt;This is where it’s great to use Mockery.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Mockery and ShouldHaveBeenCalled
&lt;/h3&gt;

&lt;p&gt;Solving this with mockery isn’t too obvious if you’ve looked through the documentation even. We can do it using the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

class UppercaseTest extend TestCase
{
    public function testItFailsNonUppercaseValues()
    {
       $closure = Mockery::mock(function () {
       });

       // we have to turn the mock into a Closure by using
       // a first-class callable
       (new Uppercase)-&amp;gt;validate('', 'lowercase', $closure(...));

       $closure-&amp;gt;shouldBeCalled()
          -&amp;gt;with('The :attribute must be uppercase.')
          -&amp;gt;once();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see in the example, we can now nicely check if the Closure has been called with a string for our validation message and we can check that it was only called once.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Mocking closures in PHP using Mockery provides a flexible and powerful way to test your code. By understanding and leveraging this technique, you can write more reliable tests and ensure your code behaves as expected in different scenarios. The provided code example demonstrates the basic steps to mock and assert closures, which you can adapt and expand upon in your projects.&lt;/p&gt;

&lt;p&gt;Remember, testing is not just about verifying correctness; it’s also about building confidence in your code. So, start incorporating mocking into your test suite and enjoy the benefits of more robust and maintainable PHP applications.&lt;/p&gt;

&lt;p&gt;If you’re struggling with using Mockery feel free to reach out as it’s personally a topic I enjoy talking about. Happy coding!&lt;/p&gt;

&lt;p&gt;I’m Peter Fox, a software developer in the UK who works with Laravel. Thank you for reading my article, I’ve got many more to read at &lt;a href="https://articles.peterfox.me/" rel="noopener noreferrer"&gt;https://articles.peterfox.me&lt;/a&gt;. I’m also now &lt;a href="https://github.com/sponsors/peterfox?frequency=one-time&amp;amp;sponsor=peterfox" rel="noopener noreferrer"&gt;Sponsorable on GitHub&lt;/a&gt;. If you’d like to encourage me to write more articles like this please do consider dropping a small one-off donation.&lt;/p&gt;

</description>
      <category>symfony</category>
      <category>laravel</category>
      <category>programming</category>
      <category>phpunit</category>
    </item>
    <item>
      <title>Laravel Scout: Eager loading models for indexing</title>
      <dc:creator>Peter Fox</dc:creator>
      <pubDate>Fri, 12 Apr 2024 20:02:04 +0000</pubDate>
      <link>https://dev.to/peter_fox/laravel-scout-eager-loading-models-for-indexing-19p5</link>
      <guid>https://dev.to/peter_fox/laravel-scout-eager-loading-models-for-indexing-19p5</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rQwxqGId--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AdV9ApD0k78Mlzs-u" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rQwxqGId--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AdV9ApD0k78Mlzs-u" width="800" height="532"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Maksym Kaharlytskyi on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you’re like me you want to get eager loading right from day one. One area that can initially seem difficult for this is when it comes to index models with Laravel Scout.&lt;/p&gt;

&lt;p&gt;This can be a real problem if you’re using relational attributes in your indexes. For example, imagine we have a Post model that we wish to index with information about the person who created the Post.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Post extends Model
{
    public function toSearchableArray(): array
    {
        return [
            'id' =&amp;gt; $this-&amp;gt;id,
            'content' =&amp;gt; $this-&amp;gt;content,
            'created_by' =&amp;gt; $this-&amp;gt;user-&amp;gt;name,
        ];
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we try to reindex the Post mode with this code we will end up with N+1 issues because the user will be loaded per Post method.&lt;/p&gt;

&lt;p&gt;Luckily there is a method for being able to do this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement MakeSearchableUsing
&lt;/h3&gt;

&lt;p&gt;Using the method makeSearchableUsing we can take the collection of models to be indexed and we can then use the eager load functionality to make use the users are loaded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Illuminate\Database\Eloquent\Collection;

class Post extends Model
{
    public function toSearchableArray(): array
    {
        return [
            'id' =&amp;gt; $this-&amp;gt;id,
            'content' =&amp;gt; $this-&amp;gt;content,
            'comments_count' =&amp;gt; $this-&amp;gt;comment_count,
            'created_by' =&amp;gt; $this-&amp;gt;user-&amp;gt;name,
        ];
    }

    public function makeSearchableUsing(Collection $models): Collection
    {
        return $models-&amp;gt;load('user')-&amp;gt;loadCount('comments');
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Often Laravel will have what you need. In the case of Laravel Scout, the documentation can be difficult to follow. While this feature is documented and mentions eager loading it can be difficult to find. It’s worth taking a deep dive into the source code and understanding what can and can’t be extended through models.&lt;/p&gt;

&lt;p&gt;I’m Peter Fox, a software developer in the UK who works with Laravel. Thank you for reading my article, I’ve got several more available at &lt;a href="https://articles.peterfox.me/" rel="noopener noreferrer"&gt;https://articles.peterfox.me&lt;/a&gt;. I’m also now &lt;a href="https://github.com/sponsors/peterfox?frequency=one-time&amp;amp;sponsor=peterfox" rel="noopener noreferrer"&gt;Sponsorable on GitHub&lt;/a&gt;. If you’d like to encourage me to write more articles like this please do consider dropping a small one-off donation.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>scout</category>
      <category>php</category>
    </item>
    <item>
      <title>Laravel Testing: Mocking static methods with the container</title>
      <dc:creator>Peter Fox</dc:creator>
      <pubDate>Mon, 01 Apr 2024 13:01:59 +0000</pubDate>
      <link>https://dev.to/peter_fox/laravel-testing-mocking-static-methods-with-the-container-31f7</link>
      <guid>https://dev.to/peter_fox/laravel-testing-mocking-static-methods-with-the-container-31f7</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bRDVpx9f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AaAPEcWu_QNS6xpCV" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bRDVpx9f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AaAPEcWu_QNS6xpCV" alt="" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by ShareGrid on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I came across a difficult challenge this week. How can I mock a static method being used? Ideally, static methods shouldn’t be used as factories, but sometimes you don’t want to go down that rabbit hole of having to refactor everything.&lt;/p&gt;
&lt;h3&gt;
  
  
  Example Problem
&lt;/h3&gt;

&lt;p&gt;Take the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Bar
{
    public function bar(mixed $bar): mixed
    {
        return Foo::foo($bar);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s simple enough, but what if we need to mock Foo::foo() for some particular reason, maybe it’s interacting with a database or something you don’t want to deal with in a continuous integration environment.&lt;/p&gt;

&lt;p&gt;Either way, this could be difficult to do.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Mockery Solution
&lt;/h3&gt;

&lt;p&gt;If you’re a regular test writer for your Laravel applications you likely know you can use Mockery. Mocks are typically used for instances, but you can mock static methods as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function test_it_works(): void
{
    Mockery::mock('alias:' . Foo::class)
        -&amp;gt;shouldReceive('bar')
        -&amp;gt;with('bar')
        -&amp;gt;andReturn('foo');

    $result = $bar-&amp;gt;bar('bar');
    $this-&amp;gt;assertSame('foo', $result);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works but if you dig into the alias functionality in Mockery, it can lead to issues where the library is unable to replace the existing class. This will cause the test to throw an exception.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Laravel Container Solution
&lt;/h3&gt;

&lt;p&gt;What you might not realise is that Laravel’s facades are a great way to get around this kind of problem. In this case we’ll be using the App facade.&lt;/p&gt;

&lt;p&gt;First we need to make a minor change to our original class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Bar
{
    public function bar(mixed $bar): mixed
    {
        return App::call(Foo::foo(...), [$bar]);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we have done is turn the static method into a closure and tell the container to execute the closure with the provided arguments.&lt;/p&gt;

&lt;p&gt;Now we’ve done this we can write a test that instead uses the facade to create a mock.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function test_it_works(): void
{
    App::shouldReceive('call')
        -&amp;gt;with(Mockery::type(\Closure), ['bar'])
        -&amp;gt;andReturn('foo');

    $bar = new Bar();
    $result = $bar-&amp;gt;bar('bar');
    $this-&amp;gt;assertSame('foo', $result);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that’s it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;I hope this has been a quick and helpful little article. I put this together mainly as a solution when you’re up against the clock. Obviously, I would advise against which kinds of static methods but it’s possible that sometimes you can’t get around it without lots of extra work. This small trick works great with that legacy code you’re still struggling with.&lt;/p&gt;

&lt;p&gt;I’m Peter Fox, a software developer in the UK who works with Laravel. Thank you for reading my article, I’ve got several more available at &lt;a href="https://articles.peterfox.me/"&gt;https://articles.peterfox.me&lt;/a&gt;. I’m also now &lt;a href="https://github.com/sponsors/peterfox?frequency=one-time&amp;amp;sponsor=peterfox"&gt;Sponsorable on GitHub&lt;/a&gt;. If you’d like to encourage me to write more articles like this please do consider dropping a small one-off donation.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>testing</category>
      <category>tdd</category>
    </item>
    <item>
      <title>PHP: 7 tricks to help with upgrading Composer packages</title>
      <dc:creator>Peter Fox</dc:creator>
      <pubDate>Tue, 13 Feb 2024 17:27:29 +0000</pubDate>
      <link>https://dev.to/peter_fox/php-7-tricks-to-help-with-upgrading-composer-packages-22c1</link>
      <guid>https://dev.to/peter_fox/php-7-tricks-to-help-with-upgrading-composer-packages-22c1</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SE-_VHEb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2An4fe5jEoIX1-KtpH" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SE-_VHEb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2An4fe5jEoIX1-KtpH" alt="" width="800" height="534"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by JESHOOTS.COM on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Recently I had the pleasure of taking an enterprise app and upgrading it from Laravel 9 to Laravel 10. Like a lot of applications we also had a good number of dependencies to upgrade. While I won’t go into any specifics of that upgrade I will point out some of the techniques I used to Composer, PHP’s package manager that allowed me to navigate some of the complexities.&lt;/p&gt;

&lt;p&gt;Often we think an upgrade is just typing out composer update and then seeing what needs fixing. Personally I think this is fine for an application without many decencies and has been around for a year or two but for many this is just going to be too broad and leave you struggling to debug issues. That’s why the first thing I will talk about is selective update.&lt;/p&gt;
&lt;h3&gt;
  
  
  Selective updates
&lt;/h3&gt;

&lt;p&gt;When using the update command it is possible to change just the composer.lock file for specific packages. When you do this you specify you only want to update that package. This might throw up some dependencies issues or just do nothing if you try to specify a version that doesn’t play nicely with other packages you have in your lock file.&lt;/p&gt;

&lt;p&gt;You’ll notice in the output below that for this Laravel project, we can specify package versions that are required. For any that are sub dependencies we can only allow the package to be updated unless we use the --with option.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer update \ 
laravel/framework:~10.0.0 \ # allows for specific versions 
spatie/laravel-ignition:^2.0 \ 
monolog/monolog \ # can only be a reference to allow an upgrade 
spatie/ignition \ # we'll use the --with option to set a specific version
symfony/http-foundation \ 
symfony/mailer \ 
nesbot/carbon \ 
symfony/mime \ 
spatie/flare-client-php \ 
spatie/laravel-package-tools \ 
spatie/laravel-activitylog \
--with spatie/ignition:1.11.3 # our specific version for a sub dependency
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A good example of why you might want to specify versions and increment them is finding bugs as you go. Myself when upgrading this work project to Laravel 10 found that installing just 10.0.3 there was only one bug but when it came to Laravel 10.43.0 I had multiple others to fix.&lt;/p&gt;

&lt;p&gt;I resolved this by simply finding which version of Laravel 10 caused the bug and fixing it by making educated guess from what was in the changelog for that version of the framework. Then I’d increment to the next version that had a bug until I reached the latest version.&lt;/p&gt;

&lt;p&gt;Such approaches might seem tedious but they can be pretty beneficial.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dry run
&lt;/h3&gt;

&lt;p&gt;Something that can be useful is simply to try commands with the dry-run option. This doesn’t help that much in the long run but it allows you to try things out without actually writing the changes to composer.json or composer.lock. This command option works with both require and update.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require php:^8.3 --dry-run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Find what depends on a package
&lt;/h3&gt;

&lt;p&gt;If you’re struggling to update a package and the output of that command update is confusing you can absolutely try using the depends command (also known as the whycommand). This can help you see if one of the sub packages is used by another package as a sub dependency.&lt;/p&gt;

&lt;p&gt;When using this command you should have a nice out like below that lists any conflicting dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;peterfox@Peters-MBP-2 project % composer depends nesbot/carbon  
laravel/framework v10.38.1 requires nesbot/carbon (^2.67)   
laravel/octane v2.2.4 requires nesbot/carbon (^2.66.0) 
laravel/pulse v1.0.0-beta10 requires nesbot/carbon (^2.67)   
spatie/flare-client-php 1.4.3 requires nesbot/carbon (^2.62.1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Find packages blocking updates
&lt;/h3&gt;

&lt;p&gt;Another command that you can use before getting started is simply the why-not command. It’s also called prohibits but honestly why-not just seems more memorable!&lt;/p&gt;

&lt;p&gt;Now Laravel 11 is literally days away so lets try seeing what it will take to get this current Laravel 10 project update to date.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;peterfox@Peters-MBP-2 project % composer why-not laravel/framework 11.0.0
Package "laravel/framework" could not be found with constraint "11.0.0", results below will most likely be incomplete.
laravel/laravel dev-main requires laravel/framework (^10.0)                              
laravel/fortify v1.19.1 requires illuminate/support (^8.82|^9.0|^10.0)                  
laravel/jetstream v4.2.0 requires illuminate/console (^10.17)                            
laravel/jetstream v4.2.0 requires illuminate/support (^10.17)                            
laravel/octane v2.2.4 requires laravel/framework (^10.10.1)                           
laravel/sanctum v3.3.2 requires illuminate/console (^9.21|^10.0)                       
laravel/sanctum v3.3.2 requires illuminate/contracts (^9.21|^10.0)                     
laravel/sanctum v3.3.2 requires illuminate/database (^9.21|^10.0)                      
laravel/sanctum v3.3.2 requires illuminate/support (^9.21|^10.0)                       
laravel/scout v10.6.1 requires illuminate/bus (^9.0|^10.0)                            
laravel/scout v10.6.1 requires illuminate/contracts (^9.0|^10.0)                      
laravel/scout v10.6.1 requires illuminate/database (^9.0|^10.0)                       
laravel/scout v10.6.1 requires illuminate/http (^9.0|^10.0)                           
laravel/scout v10.6.1 requires illuminate/pagination (^9.0|^10.0)                     
laravel/scout v10.6.1 requires illuminate/queue (^9.0|^10.0)                          
laravel/scout v10.6.1 requires illuminate/support (^9.0|^10.0)                        
laravel/slack-notification-channel v3.1.0 requires illuminate/http (^9.0|^10.0)                           
laravel/slack-notification-channel v3.1.0 requires illuminate/notifications (^9.0|^10.0)                  
laravel/slack-notification-channel v3.1.0 requires illuminate/support (^9.0|^10.0)                        
laravel/tinker v2.8.2 requires illuminate/console (^6.0|^7.0|^8.0|^9.0|^10.0)         
laravel/tinker v2.8.2 requires illuminate/contracts (^6.0|^7.0|^8.0|^9.0|^10.0)       
laravel/tinker v2.8.2 requires illuminate/support (^6.0|^7.0|^8.0|^9.0|^10.0)         
livewire/livewire v3.3.3 requires illuminate/database (^10.0)                            
livewire/livewire v3.3.3 requires illuminate/support (^10.0)                             
livewire/livewire v3.3.3 requires illuminate/validation (^10.0)                          
openai-php/laravel v0.4.3 requires laravel/framework (^9.46.0|^10.7.1)                    
spatie/laravel-ignition 2.3.2 requires illuminate/support (^10.0)                             
spatie/laravel-package-tools 1.16.1 requires illuminate/contracts (^9.28|^10.0)                     
spatie/laravel-ray 1.33.0 requires illuminate/contracts (^7.20|^8.19|^9.0|^10.0)          
spatie/laravel-ray 1.33.0 requires illuminate/database (^7.20|^8.19|^9.0|^10.0)           
spatie/laravel-ray 1.33.0 requires illuminate/queue (^7.20|^8.19|^9.0|^10.0)              
spatie/laravel-ray 1.33.0 requires illuminate/support (^7.20|^8.19|^9.0|^10.0)            
spatie/laravel-webhook-client 3.2.0 requires illuminate/bus (^8.50|^9.0|^10.0)                      
spatie/laravel-webhook-client 3.2.0 requires illuminate/database (^8.50|^9.0|^10.0)                 
spatie/laravel-webhook-client 3.2.0 requires illuminate/support (^8.50|^9.0|^10.0)                  
teamtnt/laravel-scout-tntsearch-driver v12.5.0 requires illuminate/bus (~5.4|^6.0|^7.0|^8.0|^9.0|^10.0)        
teamtnt/laravel-scout-tntsearch-driver v12.5.0 requires illuminate/contracts (~5.4|^6.0|^7.0|^8.0|^9.0|^10.0)  
teamtnt/laravel-scout-tntsearch-driver v12.5.0 requires illuminate/pagination (~5.4|^6.0|^7.0|^8.0|^9.0|^10.0) 
teamtnt/laravel-scout-tntsearch-driver v12.5.0 requires illuminate/queue (~5.4|^6.0|^7.0|^8.0|^9.0|^10.0)      
teamtnt/laravel-scout-tntsearch-driver v12.5.0 requires illuminate/support (~5.4|^6.0|^7.0|^8.0|^9.0|^10.0)    
Not finding what you were looking for? Try calling `composer require "laravel/framework:11.0.0" --dry-run` to get another view on the problem.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives us a nice list to work with that allows us to sign off which packages we might need to look at. Equally we can try upgrading these one by one until hopefully none of them show up anymore. For instance if I try just a slightly newer version of Laravel 10, here’s what I get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;peterfox@Peters-MBP-2 project % composer why-not laravel/framework 10.43.0
There is no installed package depending on “laravel/framework” in versions not matching 10.43.0
Not finding what you were looking for? Try calling `composer require “laravel/framework:10.43.0” — dry-run` to get another view on the problem.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There’s not issues so we’re ready to upgrade.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ignore platform dependencies
&lt;/h3&gt;

&lt;p&gt;This is also something worth knowing. We can actually ignore PHP platform dependencies when performing require or update commands. The reason you might want this is to ignore when a certain PHP extension isn’t install on your local machine but might be in production.&lt;/p&gt;

&lt;p&gt;This does work as well with PHP as a dependency itself. That’s right, even if you are working with PHP 8.1 but you want to install package that rely on newer PHP versions like 8.2 and 8.3 you can tell composer to just bypass this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer update laravel/framework --ignore-platform-reqs=php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a level of risk and I probably wouldn’t use this in production but it allows you to at least try out packages early without having to do anything overly hacky like downloading with one version to run with another.&lt;/p&gt;

&lt;p&gt;This is also just happy when working with static analysis tools as you can download dependencies for things like PHPStan or Rector when you don’t intend to run the code locally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Require across versions
&lt;/h3&gt;

&lt;p&gt;This is more of a tip that PHP package developers will know but others might not be aware of and that is you can specify different versions in composer.json allowing you to then run update to switch to a new version.&lt;/p&gt;

&lt;p&gt;For instance when upgrading to Laravel 10 from 9, you must also update spatie/laravel-ignition to version 2 or higher. The problem is you can’t do it in one command as one is a dev requirement and one is a production requirement but if you do them in seperate commands they will cause update issues to occur.&lt;/p&gt;

&lt;p&gt;Doing this allows you to specify a new version to work with while still keeping the possibility to install older ones using the update command as I mentioned earlier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require “laravel/framework:^9.0|~10.0.0”
composer require "spatie/laravel-ignition:^1.2|^2.0" --dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you’re happy with the upgrade you can now just require those fixed versions. Remember, if you’re using install and you’re keeping the composer.lock file under source control, the version in the lock file is what will be installed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use your own forks
&lt;/h3&gt;

&lt;p&gt;You might sometimes hit a hurdle that can be quite annoying. What do you do when a package isn’t updated to the latest framework or PHP version. A quick fix for yourself is to fork the source code. Most PHP packages are likely to be on github or another git based system. In the example below we can point a different repository for Laravel Framework allowing me to try out a fork without setting up anything in Packagist.&lt;/p&gt;

&lt;p&gt;Note with the following command I specify the laravel/framework and the url &lt;a href="https://github.com/peterfox/laravel-framework"&gt;https://github.com/peterfox/laravel-framework&lt;/a&gt; which where composer can find the forked code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer config repositories.laravel/framework vcs https://github.com/peterfox/laravel-framework
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we’ve done this, we can easily just require a particular branch. In this case the branch is my-upgrade-branch but to tell Composer it is a branch we put dev- before the name of the branch. With this, we have installed a forked branch of a popular package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require laravel-framework:dev-my-upgrade-branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can always remove the repository we added later on with the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer config — unset repositories.laravel/framework
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Thank you again for getting through all of these. I hope it will be useful in your larger projects where upgrading code is a complex mystery to unravel as it has often been for me. Remember you can learn more about these commands available in composer by running composer list.&lt;/p&gt;

&lt;p&gt;I’m Peter Fox, a software developer in the UK who works with Laravel. Thank you for reading my article, I’ve got several more available at &lt;a href="https://articles.peterfox.me"&gt;https://articles.peterfox.me&lt;/a&gt;. I’m also now also &lt;a href="https://github.com/sponsors/peterfox?frequency=one-time&amp;amp;sponsor=peterfox"&gt;Sponsorable on GitHub&lt;/a&gt;. If you’d like to encourage me to write more articles like this please do consider dropping a small one off donation.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>composer</category>
      <category>upgrades</category>
    </item>
    <item>
      <title>Laravel Feature Flags: Choosing a Package</title>
      <dc:creator>Peter Fox</dc:creator>
      <pubDate>Sun, 12 Feb 2023 11:06:52 +0000</pubDate>
      <link>https://dev.to/peter_fox/laravel-feature-flags-choosing-a-package-3m8m</link>
      <guid>https://dev.to/peter_fox/laravel-feature-flags-choosing-a-package-3m8m</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y_fDGwwG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AoPPZbzb5eYU_DRQj" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y_fDGwwG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AoPPZbzb5eYU_DRQj" alt="" width="800" height="434"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Vladislav Klapin on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/laravel/pennant"&gt;Laravel Pennant&lt;/a&gt; is now available (although, at the time of writing, Pennant &amp;amp; Laravel 10 do not have stable releases). This means that more and more people will be learning about the concept of Feature Flags and how they can improve the developer experience and product management of their Laravel applications.&lt;/p&gt;

&lt;p&gt;That said, the official package comes after several community-created packages that took different approaches to implement feature flags. In this article, I will briefly examine these popular packages, including the one I maintain, &lt;a href="https://github.com/ylsideas/feature-flags"&gt;Feature Flags for Laravel&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What problem does using Feature Flags solve?
&lt;/h3&gt;

&lt;p&gt;Feature Flags are a solution that is primarily aimed at those who are doing continuous integration.&lt;/p&gt;

&lt;p&gt;To explain, if you don’t know what continuous integration is, code is constantly merged into your main branch and regularly deployed to move quickly and avoid things like merge conflicts. Continuous integration typically requires that you have lots of automated tests, but you will soon find this isn’t enough. Instead, it would be best if you also began to build feature flags.&lt;/p&gt;

&lt;p&gt;Imagine this scenario. You’re building a new feature for your application, which requires communication of the end product with the users, training for your support team, and marketing, who wants to make a campaign to shout about the changes to customers. This is where feature flags come in. You will build your feature, merge it and deploy it but stop your end users from accessing it until your business is ready. Once everyone else has caught up, you change the application's state without merging or deploying new code, and now customers will have their shiny new feature to play with.&lt;/p&gt;

&lt;p&gt;All of this can be complex to reach. How do you start segregating the functionality you want to be used versus the functionality you don’t want to be available when deploying code changes?&lt;/p&gt;

&lt;p&gt;That’s where feature flags come in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do you even need a package for Feature Flags?
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Honestly?&lt;/em&gt; It’s &lt;em&gt;absolutely&lt;/em&gt; possible to implement feature flags using the mechanisms available in Laravel itself or with just small amounts of code. Laravel has something called Gates and Policies. These two together make it easy to control user activity in your Laravel app by calling the allows method on a Gate or a Policy. This will do what you want but will lead to more difficulties as your app scales.&lt;/p&gt;

&lt;p&gt;This approach will mean that you must create a persistence layer for features. If you decide on using a gate, you’ll have to determine how it will store the flags. For example, it could be in the config and models, but be wary that feature flags might be accessed multiple times per request in every request that occurs and become a bottleneck for performance.&lt;/p&gt;

&lt;p&gt;If this isn’t for you, you’d best look at one of the four following packages to help develop feature flags in your application.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Laravel Pennant Alternatives
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Spatie’s Flags Package
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/spatie/laravel-model-flags"&gt;GitHub - spatie/laravel-model-flags: Add flags to Eloquent models&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Spatie’s package is a relatively new entry to the Feature Flag space. The package itself is pretty simple and focuses on models completely. The implementation requires you to add and run a migration. Afterwards, you may use a provided trait on any models you have, allowing you to store boolean flags per model.&lt;/p&gt;

&lt;p&gt;This is mainly about having a superficial persistence layer to control feature sets for, say, your Users or if you implement a Team model. This is fine but requires you to rely on things like Gates and Policies to perform checks on the User.&lt;/p&gt;

&lt;p&gt;There’s no integration with the Laravel framework in any other sense, so you’ll need to create a Middleware or Blade directive to check if the user has the flags expected.&lt;/p&gt;

&lt;h4&gt;
  
  
  JustSteveKing’s Package
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/JustSteveKing/laravel-feature-flags"&gt;GitHub - JustSteveKing/laravel-feature-flags: A simple to use Feature Flag package for Laravel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This package is quite good in that, in the same way as the Spatie package, it interacts with the models, allowing you even to apply models to groups, something I’m sure many will want to do. You will need to add a migration to your app to install a persistence layer that your models can use with a trait.&lt;/p&gt;

&lt;p&gt;The package allows you to interact with blade templates to isolate sections based on the page. Steve King’s package can also let you apply middleware that restricts the routes, but that’s about as far as it goes into the Laravel framework itself.&lt;/p&gt;

&lt;p&gt;One of the neat features in JustSteveKing’s package is the TimeBomb feature. Something I can see many people wanting. TimeBomb allows you to throw an exception for a flag you no longer wish to exist in your app. Doing this means it’s easier to clean up your code as you decide to retire some flags.&lt;/p&gt;

&lt;h4&gt;
  
  
  ryangjchandler’s Package
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/ryangjchandler/laravel-feature-flags"&gt;GitHub - ryangjchandler/laravel-feature-flags: An opinionated feature flags package for Laravel.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I won’t waste a lot of time here. Ryan Chandler’s package is nearly identical to Steve King's. It equally allows for some integration with the framework via blade and middleware while also allowing you to manage the flags against models.&lt;/p&gt;

&lt;p&gt;That said, one bonus feature to using Ryan’s package is first-party support for a &lt;a href="https://github.com/ryangjchandler/filament-feature-flags"&gt;UI using Filaments&lt;/a&gt;. Filaments is a component framework for Laravel Livewire designed around building an admin dashboard. If you’re using Filaments, this might push you into choosing this package over the others.&lt;/p&gt;

&lt;h4&gt;
  
  
  YLS Ideas’ Package
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/ylsideas/feature-flags"&gt;GitHub - ylsideas/feature-flags: A Laravel package for handling feature flags&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unlike the other packages mentioned, this one works with a pipeline (in version 2, at least). This means you can be selective of which features are used and where the flags persist. Nothing is stored against models. Instead, by default, you may store flags in a table, Redis or PHP file or even use Laravel’s built-in gate system. You can even use all of these in the pipeline, allowing you to query different places. There is also a cache mechanism available to reduce the time taken to discover the flag state for apps built for large scale. This means you can’t store flags against a User, unlike the other three packages or Laravel Pennant, which use this as their primary mechanism.&lt;/p&gt;

&lt;p&gt;It is possible, though, to quickly implement your Gateway in this package if you wish to develop more complicated mechanisms, such as implementing Spatie’s package and using it to check if the user has a flag via a gate.&lt;/p&gt;

&lt;p&gt;One of the advantages is like JustSteveKing’s package in that there are integrations to Laravel itself with the YLS Ideas package. It can perform the same tricks with blade templates and middleware but extends this further with validation rules and task scheduling based on the flag's status. A recently added feature was for a maintenance mode driver that will appeal to many who wish to control how an application might display maintenance mode in a few different scenarios.&lt;/p&gt;

&lt;p&gt;If you want to use Feature Flags for Laravel, there is &lt;a href="https://dev.to/slyfirefox/implementing-feature-flags-267o"&gt;a tutorial for getting started&lt;/a&gt; and a &lt;a href="https://feature-flags.docs.ylsideas.co/"&gt;dedicated documentation website&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Laravel Pennant Itself
&lt;/h3&gt;

&lt;p&gt;It’s hard not to think that Laravel Pennant isn’t the best option, as the Laravel team will always maintain it. I’ve already tried it out, and it’s hard not to love it. The API for interacting with flags using different ‘Scopes’ (think Users or Teams) is cleverly simple.&lt;/p&gt;

&lt;p&gt;At the moment, Pennant only supports the Database for persistent storage, but additional drivers can be created, so I’m sure more will be available soon.&lt;/p&gt;

&lt;p&gt;One drawback for some is that you will need to use Laravel 10 to work with this package, but that likely won’t affect those starting new projects after this month.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;It’s certainly not easy to suggest one particular option over the other. You’ll often need to start by thinking about how you’d like such a system to work within your app and then go from there.&lt;/p&gt;

&lt;p&gt;While all of these packages are great, they need a well-thought-out and specifically designed user interface component to work in a more enterprise environment. This can make using feature flags challenging to scale. This is why I recently announced that I would work on something called Flagfox.&lt;/p&gt;

&lt;p&gt;Flagfox is a premium package for Laravel designed to provide the frontend and UI experience for managing feature flags so that non-developers can enable and disable functionality when needed without having to perform any new deployments.&lt;/p&gt;

&lt;p&gt;This will make the journey to having a full feature flagged application more straightforward than any current options available.&lt;/p&gt;

&lt;p&gt;The landing page for Flagfox is already up, and a &lt;a href="https://www.flagfox.dev/?utm_campaign=waitlist&amp;amp;utm_source=medium&amp;amp;utm_content=flags-packages#waitlist"&gt;waiting list is available&lt;/a&gt; to join.&lt;/p&gt;

&lt;p&gt;I’m Peter Fox, a UK software developer with a decade of experience with PHP and Laravel. I’ve started work on a new project. Flagfox for Laravel will build upon my established work creating open-source packages to help developers add feature flags to their applications. We currently have a &lt;a href="https://www.flagfox.dev/?utm_campaign=waitlist&amp;amp;utm_source=medium&amp;amp;utm_content=flags-packages#waitlist"&gt;waiting list&lt;/a&gt; for those interested in learning more.&lt;/p&gt;

</description>
      <category>laravelpennant</category>
      <category>flagfox</category>
      <category>darklaunching</category>
      <category>laravel</category>
    </item>
    <item>
      <title>Implementing Feature Flags</title>
      <dc:creator>Peter Fox</dc:creator>
      <pubDate>Wed, 18 Jan 2023 21:25:45 +0000</pubDate>
      <link>https://dev.to/peter_fox/implementing-feature-flags-267o</link>
      <guid>https://dev.to/peter_fox/implementing-feature-flags-267o</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2Auj0USqsz56eDKXKC" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2Auj0USqsz56eDKXKC" width="1024" height="683"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Glen Rushton on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Feature flags are not a new concept. You might already have what is effectively a feature flag within your application. One of the often most referenced pieces on Feature Flags is by Martin Fowler, written back in 2017.&lt;/p&gt;

&lt;p&gt;His article describes feature toggles, also known as feature flags. You wouldn’t be blamed for being confused looking at the contents and not understanding where to start.&lt;/p&gt;

&lt;p&gt;Several cloud services exist, but they’re not easy to start with. As an avid Laravel Developer, I decided to make a package in 2019 to solve many of those difficulties so you can quickly start building an application with feature flags.&lt;/p&gt;

&lt;p&gt;To get started, let’s cover some basics.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is a feature flag?
&lt;/h3&gt;

&lt;p&gt;A feature flag is no different from adding any other application functionality. The flag hides functionality until it’s ready for customers to use. Sometimes this is also known as a feature toggle.&lt;/p&gt;
&lt;h3&gt;
  
  
  What makes feature flags worthwhile?
&lt;/h3&gt;

&lt;p&gt;Feature flags help you separate feature development and feature deployment. When you build a feature and use source control, you will have to wait to merge new functionality until all parts of the new functionality are ready to be released to customers and visitors.&lt;/p&gt;

&lt;p&gt;This can be problematic and leads to large and complex pull requests. Then when you think you’re ready to merge, another pull request goes in first, causing a round of complex conflicts that need to be resolved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;That puts your plans to deploy on time at risk.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For many developers, this is just how it is, right? You make code and merge it when it’s ready for viewing eyes.&lt;/p&gt;

&lt;p&gt;This mindset, while understandable, needs to be revised for building modern web applications.&lt;/p&gt;

&lt;p&gt;Feature flags can change that. At the same time, they bring additional complexity once you try to implement them at scale. This was my reason for creating Feature Flags for Laravel to remove some of the upfront work required to avoid that complexity.&lt;/p&gt;
&lt;h3&gt;
  
  
  Using Feature Flags for Laravel
&lt;/h3&gt;

&lt;p&gt;I created a package for this back in 2019. You can manage feature flags very quickly by using Laravel’s configs. That said, it can become hard to manage and often to change an application’s environment variables to affect configs, which means you have to run a new deployment even if the code is the same.&lt;/p&gt;

&lt;p&gt;Instead, using the Laravel Feature Flags package, we can configure things to rely on the database and fall back to a config file. The package provides the API for making it easier to swap around persistence mechanisms with minimal fuss.&lt;/p&gt;
&lt;h3&gt;
  
  
  Installing and Configuring
&lt;/h3&gt;

&lt;p&gt;First, we’ll take a default app with the familiar Laravel Welcome page. We want to hide the application’s version number behind a flag. Doing this allows us to change the deployment of this vital information only when needed.&lt;/p&gt;

&lt;p&gt;To begin, we will install the package using composer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require ylsideas/feature-flags:^2.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, we need to publish a few files, and because we intend to store our flags in the database and a configuration file, we need to generate the migration for our flags table and a .features.php file. We can do that with the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# install the config to config/features.php
php artisan vendor:publish — provider=”YlsIdeas\FeatureFlags\FeatureFlagsServiceProvider” — tag=config
# install .features.php
php artisan vendor:publish — provider=”YlsIdeas\FeatureFlags\FeatureFlagsServiceProvider” — tag=inmemory-config
# install a migration to database/migrations
php artisan vendor:publish — provider=”YlsIdeas\FeatureFlags\FeatureFlagsServiceProvider” — tag=features-migration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s first edit our config/features.php config file and check that the pipeline is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;‘pipeline’ =&amp;gt; [‘database’, ‘in_memory’],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By choosing the following gateways, we’re telling the pipeline to look at the database and then the .features.php file as a backup.&lt;/p&gt;

&lt;p&gt;Now we need to check each gateway. For the in-memory gateway, the settings should be as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;‘in_memory’ =&amp;gt; [
 ‘file’ =&amp;gt; env(‘FEATURE_FLAG_IN_MEMORY_FILE’, ‘.features.php’),
 ‘driver’ =&amp;gt; ‘in_memory’,
],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’re going to change the database gateway and include some caching. A 2-minute cache should do, which is 120 seconds. This will mean that if a feature is accessed a few times within that time frame, the same result will be returned, saving our database from additional queries to run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;‘database’ =&amp;gt; [
 ‘driver’ =&amp;gt;’ database’,
 ‘cache’ =&amp;gt; [
 ‘ttl’ =&amp;gt; 120,
 ],
 ‘connection’ =&amp;gt; env(‘FEATURE_FLAG_DATABASE_CONNECTION’),
 ‘table’ =&amp;gt; env(‘FEATURE_FLAG_DATABASE_TABLE’, ‘features’),
],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As our backup, we will add a default flag value to our .features.php config.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

use Illuminate\Contracts\Foundation\Application;

/**
 * @returns array&amp;lt;string, bool&amp;gt;
 */
return static function (Application $app): array {
 return [
 ‘laravel.version’ =&amp;gt; true,
 ];
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are the values we can commit into our repository as defaults then.&lt;/p&gt;

&lt;p&gt;We quickly need to run the migrations for the database. If you’re working with a new Laravel app, we can use SQLite.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Let’s add a flag
&lt;/h3&gt;

&lt;p&gt;Now to keep things simple, let’s add our initial flag. For this, we’ll open up the welcome.blade.php file and edit the part showing the Laravel version.&lt;/p&gt;

&lt;p&gt;We can wrap the version in a blade directive made available by the package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@feature(‘laravel.version’)
&amp;lt;div class=”ml-4 text-center text-sm text-gray-500 sm:text-right sm:ml-0"&amp;gt;
 Laravel v{{ Illuminate\Foundation\Application::VERSION }} (PHP v{{ PHP_VERSION }})
&amp;lt;/div&amp;gt;
@endfeature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Doing so means the section will only show when the feature laravel.version is enabled.&lt;/p&gt;

&lt;p&gt;Let’s run the server using the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now, we can go to the default Welcome page to see if the version is missing. Success!&lt;/p&gt;

&lt;p&gt;Now we can run the following artisan command, again available from the package and see if it affects the Welcome page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan feature:on database laravel.version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We may have to wait for a second to see the result.&lt;/p&gt;

&lt;p&gt;We only need to run the command with the off value and disable the flag from running. Again this might take up to two minutes to show and change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan feature:off database laravel.version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Feature flags might not be necessary for those working on a product with one or two other people, but beyond that, they can become a critical tool in helping you deliver features on time.&lt;/p&gt;

&lt;p&gt;This only scratches the surface. The real power starts when you can begin building flags that will be turned on and off per user or team. Once we reach this point, we will need to start using the gate gateway in the package or build a custom gateway for Feature Flags for Laravel.&lt;/p&gt;

&lt;p&gt;This brings me to talking about the next step in my journey to helping others build with feature flags, a premium package to support managing the deployment and rollout of features to specific users and more.&lt;/p&gt;

&lt;p&gt;If you want to check out the finished code from this article, you can always check out &lt;a href="https://github.com/peterfox/laravel-with-fffl-demo" rel="noopener noreferrer"&gt;the demo on GitHub&lt;/a&gt;. You can find the repository for &lt;a href="https://github.com/ylsideas/feature-flags" rel="noopener noreferrer"&gt;Feature Flags for Laravel on GitHub&lt;/a&gt; and the dedicated &lt;a href="https://feature-flags.docs.ylsideas.co/" rel="noopener noreferrer"&gt;documentation website for FFfL&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’m Peter Fox, a UK software developer with a decade of experience with PHP and Laravel. I’ve started work on a new project. Flagfox for Laravel will build upon my established work creating open-source packages to help developers add feature flags to their applications. We currently have &lt;a href="https://www.flagfox.dev/?utm_campaign=waitlist&amp;amp;utm_source=medium&amp;amp;utm_content=feature-flags#waitlist" rel="noopener noreferrer"&gt;a waiting list&lt;/a&gt; for those interested in learning more.&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>featureflagging</category>
      <category>featureflags</category>
    </item>
    <item>
      <title>Laravel Tip: Store your test coverage with CodeCov</title>
      <dc:creator>Peter Fox</dc:creator>
      <pubDate>Sat, 03 Dec 2022 17:55:45 +0000</pubDate>
      <link>https://dev.to/peter_fox/laravel-tip-store-your-test-coverage-with-codecov-mbc</link>
      <guid>https://dev.to/peter_fox/laravel-tip-store-your-test-coverage-with-codecov-mbc</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2ARLpiHY11ptVR8JDJ" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2ARLpiHY11ptVR8JDJ"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Ricardo Resende on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Before getting started, I'd love for you to consider checking out my latest venture &lt;a href="https://www.flagfox.dev/?utm_campaign=waitlist&amp;amp;utm_source=devto&amp;amp;utm_content=codecov" rel="noopener noreferrer"&gt;FlagFox&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.flagfox.dev/?utm_campaign=waitlist&amp;amp;utm_source=devto&amp;amp;utm_content=codecov" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.flagfox.dev%2Fimg%2Fgithub-readme-image.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;If you’re not aware Laravel’s artisan test command has been able to generate code coverage reports in the console output for some time now. This is great, but receiving that output in the console only helps a little when you run many of your tests in continuous integration.&lt;/p&gt;

&lt;p&gt;This is where &lt;a href="https://about.codecov.io/" rel="noopener noreferrer"&gt;CodeCov&lt;/a&gt; comes up, a service for keeping track of your application's code coverage over time.&lt;/p&gt;

&lt;p&gt;This tutorial will cover Setting up CodeCov and creating a GitHub Action to store the results. Nothing is stopping you from using another CI service with CodeCov, but for publishing results, I'll be using specifically GitHub actions.&lt;/p&gt;
&lt;h3&gt;
  
  
  Create a CodeCov account
&lt;/h3&gt;

&lt;p&gt;This is straightforward as setups go. You can create an account via GitHub, which makes sense if you're already hosting your repo with GitHub.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AkOldAeVjyESa9EPc_UtB0Q%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AkOldAeVjyESa9EPc_UtB0Q%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At that point, you can search for the git repo you want to collect code coverage for, and upon selecting that repository, you'll see the following screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AMQz7aRxJV4OB44Au1xvIog%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AMQz7aRxJV4OB44Au1xvIog%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will stay blank until we start pushing any coverage reports. To do this, we need to create our testing action. On this page, you will see a Token that you'll need to copy if you're setting up a &lt;em&gt;private&lt;/em&gt; GitHub repository. Open-source projects can skip the token setup.&lt;/p&gt;
&lt;h3&gt;
  
  
  Creating a GitHub Action
&lt;/h3&gt;

&lt;p&gt;The first thing to do will be to set up a secret in your GitHub repository. This will be the safest place to keep the token so others won't be able to upload code reports to CodeCov.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AhXtlbAtJapN_lkfIehelUg%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AhXtlbAtJapN_lkfIehelUg%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You only need to create a new Actions Secret in the repository settings, copy the token into the Secret input, and then save it.&lt;/p&gt;

&lt;p&gt;The next part all occurs within our code.&lt;/p&gt;

&lt;p&gt;We need to add a .github/workflows/run-tests.yml file to our project's folder. It also should contain the following Yaml file.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Please note that sometimes your tests will have different requirements; you will need to make that work before sending coverage reports. What's important here is the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your PHP setup must have a code coverage driver. In the example, it's PCov which, at the moment, is considered the best option for running tests with speed.&lt;/li&gt;
&lt;li&gt;When we reach the code execution step, we're running PHPUnit (or, in this case, the Artisan Test command) with the coverage options and telling PHPUnit where to save the report.&lt;/li&gt;
&lt;li&gt;In the project, I've added a /storage/coverage folder and put a .gitignore file so that reports can be generated to that folder but will never be committed to the repository.&lt;/li&gt;
&lt;li&gt;We're using the &lt;a href="https://github.com/codecov/codecov-action" rel="noopener noreferrer"&gt;CodeCov Github Action&lt;/a&gt; they provide to use the token from the secrets we've configured, and we've told it the file we want to upload.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You’ll find that if you have set up the secrets or the actions wrong, the CodeCov upload step will fail silently and require you to look at the action's output to explain why it's failed.&lt;/p&gt;

&lt;p&gt;If you've been successful, your code coverage action will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Anv_nmwKwclYuIQVW5CyFhA%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Anv_nmwKwclYuIQVW5CyFhA%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now when we go to CodeCov, we should be able to see the output of our actions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AVoe9Yut73QMXDi9OH5CD-g%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AVoe9Yut73QMXDi9OH5CD-g%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://app.codecov.io/gh/peterfox/laravel-codecov-demo" rel="noopener noreferrer"&gt;browse the results on CodeCov&lt;/a&gt; directly for the &lt;a href="https://github.com/peterfox/laravel-codecov-demo" rel="noopener noreferrer"&gt;demo project&lt;/a&gt; I created.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding that coverage Badge
&lt;/h3&gt;

&lt;p&gt;Of course, what is the point of this all if you won't be showing off that (hopefully green) code coverage?&lt;/p&gt;

&lt;p&gt;To do this, we only need to go to the settings of our repo on CodeCov, and then we can copy the provided Markdown.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AQnKy2rd-CssYKGvp0ABJwQ%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AQnKy2rd-CssYKGvp0ABJwQ%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once we have this, we can paste it into our project's README.md file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Aea3fa4M89mO2w08L7Ywzvg%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Aea3fa4M89mO2w08L7Ywzvg%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once committed, we'll see the badge and click through to the report on Codecov.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2APaSml_kHK-Rca5iVxgRQkw%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2APaSml_kHK-Rca5iVxgRQkw%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Well, we can wrap this up quickly. Code coverage is a great metric to monitor, don't put too much faith in that 100% mark, instead treat the value as a way to track progress or regression. Suppose you find yourself starting with 50% or so. Then it would be best if you aimed to maintain or improve this value. If you see it dropping over the next few months, you can begin to question whether you need to evaluate why that is the case or not.&lt;/p&gt;

&lt;p&gt;Either way, I hope you'll have fun getting that feedback. Feel free to tweet me your code coverage on &lt;a href="https://twitter.com/SlyFireFox" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;; I'd love to hear what you got.&lt;/p&gt;

&lt;p&gt;Like Always, if you want to see all the code, you can &lt;a href="https://github.com/peterfox/laravel-codecov-demo" rel="noopener noreferrer"&gt;view the repository created on GitHub.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’m Peter Fox, a UK software developer with a decade of experience with PHP and Laravel. I’ve started work on a new project. Flagfox for Laravel will build upon my already established work creating open-source packages to help developers add feature flags to their applications. We currently have a &lt;a href="https://www.flagfox.dev/?utm_campaign=waitlist&amp;amp;utm_source=devt&amp;amp;utm_content=codecov#waitlist" rel="noopener noreferrer"&gt;waiting list&lt;/a&gt; for those interested in learning more.&lt;/p&gt;

</description>
      <category>php</category>
      <category>codecoverage</category>
      <category>laravel</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Laravel Tooling: 4 tools for static analysis</title>
      <dc:creator>Peter Fox</dc:creator>
      <pubDate>Sun, 20 Nov 2022 18:05:11 +0000</pubDate>
      <link>https://dev.to/peter_fox/laravel-tooling-4-tools-for-static-analysis-33d9</link>
      <guid>https://dev.to/peter_fox/laravel-tooling-4-tools-for-static-analysis-33d9</guid>
      <description>&lt;h3&gt;
  
  
  Laravel Tooling: 4 useful tools for static analysis
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2A2RUTEy8YajDOBdEF" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2A2RUTEy8YajDOBdEF" width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Isaac Smith on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I’ve learnt over the years to embrace the range of amazing tools you can use to develop PHP and Laravel Applications. I did a little tweet about this but it didn’t seem fair to not go into a bit of a wider explanation of &lt;em&gt;why&lt;/em&gt; I use these tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Peter Fox on Twitter: "As a PHP developer, there are a great number of static tools that you can use. Here are four off the top of my head that I regularly go to:#php #laravel 🧵 / Twitter"
&lt;/h3&gt;

&lt;p&gt;As a PHP developer, there are a great number of static tools that you can use. Here are four off the top of my head that I regularly go to:#php #laravel 🧵&lt;/p&gt;

&lt;h3&gt;
  
  
  What are static analysis tools?
&lt;/h3&gt;

&lt;p&gt;To put it as best as I can, a static analysis tool looks at code and makes determinations about what it sees. In this list, there will be tools that, grade performance, discover things like unused code, look at and improve the visual readability of code and even perform upgrades to the code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pint
&lt;/h3&gt;

&lt;p&gt;Technically Pint is fairly new as the official linting tool for Laravel. It can firstly be used in any PHP project despite being made for Laravel and is a little bit nicer than PHP CS Fixer which Pint uses under the hood. Linting is a common name for a static analysis tool which will format code and try to apply small changes to make code readable by a set of standards.&lt;/p&gt;

&lt;p&gt;As of writing most PHP code will be developed to what is known as the &lt;a href="https://www.php-fig.org/psr/psr-12/" rel="noopener noreferrer"&gt;PSR-12 standard&lt;/a&gt;, we’ve also had the &lt;a href="https://www.php-fig.org/psr/psr-1/" rel="noopener noreferrer"&gt;PSR-1&lt;/a&gt; and now deprecated &lt;a href="https://www.php-fig.org/psr/psr-2/" rel="noopener noreferrer"&gt;PSR-2&lt;/a&gt; standard.&lt;/p&gt;

&lt;p&gt;PSR coding standards don’t cover everything though so often it’s a good idea to &lt;a href="https://mlocati.github.io/php-cs-fixer-configurator/#version:3.13" rel="noopener noreferrer"&gt;look at what additional rules you might apply&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The key takeaway and benefits here are readability and collaboration. If you work by yourself it’s not necessarily going to bring huge improvements. If you work as a team and collaborate regularly, will be of great benefit to you all. Some PSR standards are as much there to help make sure code merges have fewer conflicts. Equally just establishing a set of rules shared between you means code will be written in ways your brain will look at and understand quicker from muscle memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  PHPStan (&amp;amp; Larastan)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://phpstan.org/" rel="noopener noreferrer"&gt;PHPStan&lt;/a&gt; is well-established as a useful tool for PHP developers the world over. The purpose of PHPStan is to look at how code interacts, for example, it can look at the usage of a variable and find if a string variable will be used with a function as an array argument. This of course would be an error at runtime if it were to happen. Likewise, PHPStan is capable of finding code that is no longer used.&lt;/p&gt;

&lt;p&gt;PHPStan is incredibly useful as many developers are looking to take advantage of the type hinting that PHP7 and PHP8 have pushed forward. This isn’t easy to do though without finding all the places in a project that aren’t type-hinted. PHPStan can do this by looking for where arguments or return types aren’t documented either by a type-hint or a PHPDoc tag.&lt;/p&gt;

&lt;p&gt;There’s even a great bit of functionality for creating what’s known as &lt;a href="https://phpstan.org/user-guide/baseline" rel="noopener noreferrer"&gt;a baseline&lt;/a&gt; if you wish to ignore past problems and only focus on not introducing new issues.&lt;/p&gt;

&lt;p&gt;If you’re developing a package or app that uses &lt;a href="https://github.com/nunomaduro/larastan" rel="noopener noreferrer"&gt;Larastan&lt;/a&gt; you’re going to want to install Larastan over PHPStan. This is because the extension will understand more of the magic that occurs within Laravel such as models having dynamic attributes and scopes.&lt;/p&gt;

&lt;p&gt;To summarise, the benefit here really just comes down to spotting mistakes early. The higher level you set with PHPStan, the more likely you will have removed silly mistakes you’ll find at run time and save yourself from painfully debugging problems in production.&lt;/p&gt;

&lt;h3&gt;
  
  
  PHPInsights
&lt;/h3&gt;

&lt;p&gt;I will say that overall this tool is handy but can be a bit overwhelming at first. A number of different static analysis things are at play here. &lt;a href="https://phpinsights.com/" rel="noopener noreferrer"&gt;Insights&lt;/a&gt; will provide you with 4 groups of scores, code, complexity, architecture, and style.&lt;/p&gt;

&lt;p&gt;I’ll start with the style insights first, this is essentially going to be exactly the same kind of processing as Pint, but it’s nice to at least have a scoring. It will also pick up a few other things that Pint won’t such as line counts.&lt;/p&gt;

&lt;p&gt;Complexity is purely cyclomatic complexity, which is a very simple way of saying how many branches occur within code. You might want to brush up on the concept. Personally, I find the default for this a bit low so I’ll typically pump it up. That said it’s a good metric for when classes become unwieldy.&lt;/p&gt;

&lt;p&gt;That goes onto the next category architecture. This covers a few things but is often just simple naming conventions or the length of functions or classes. Again I would normally bump up the length of classes allowed as I don’t like to be held to such a high standard I end up creating lots of classes just to encapsulate simple functionality right away.&lt;/p&gt;

&lt;p&gt;The final stat is code and really just follows a lot of the similar things that you might find with PHPStan or Pint. These might range from useless variables to avoiding using some functions due to the way they can be unpredictable. It can be a little opinionated at times so do remove some rules if they’re just generating more noise for you.&lt;/p&gt;

&lt;p&gt;Ultimately I would say Insights is interesting and is great as a tool for gauging code quality quickly and then using that initial score to see if you are moving in the right direction when refactoring code but you definitely need to take the time to form your own opinion on what rules are and aren’t used when generating such metrics.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rector
&lt;/h3&gt;

&lt;p&gt;So this tool is in many ways my new favourite toy within the static analysis tool kit. It’s built on top of components from PHPStan to be able to give you all of that type-hinting goodness but it goes further in that it can actually fix things. Unlike Pint which can lint code by looking at how the white space is structured in code, &lt;a href="https://getrector.org/" rel="noopener noreferrer"&gt;Rector&lt;/a&gt; can analyse more of the usage and also start to replace function calls or with new operators available in later PHP versions. It’s pretty marvellous and with more people using it, we could start to see fewer legacy burdens in the world.&lt;/p&gt;

&lt;p&gt;There’s a straightforward ruleset for things like PHP and even PHPUnit which are worth using but also there are rules to perform upgrades of Laravel code as well. Things like changing factories before PHP 7 into the newer style ones. One recent thing to point out is that if you are working with Laravel, the rules used to be installed with Rector but are now maintained in &lt;a href="https://github.com/driftingly/rector-laravel" rel="noopener noreferrer"&gt;their own package&lt;/a&gt; to install.&lt;/p&gt;

&lt;p&gt;It does all these things pretty well but I do suggest being somewhat careful with code bases are have a lot of legacy debt before running the fix command with everything. You can run the command with the dry-run option which only finds and displays problems, instead of applying the changes right away. It’s best to try one rule at a time when adding to an old codebase, review the changes and then continue. Some rules can have adverse effects such as the rule to upgrade json_encode and json_decode to throw exceptions.&lt;/p&gt;

&lt;p&gt;My personal feeling is Rector is a tool more PHP developers should be getting used to using in the future. It could make the difference between your developers using outdated operates and functions within PHP as well as making it easier to upgrade code bases that could do with some additional love.&lt;/p&gt;

&lt;h3&gt;
  
  
  One Last Thing…
&lt;/h3&gt;

&lt;p&gt;If you didn’t notice by now, there’s actually one thing that these PHP tools have in common and that is that 3 out of the 4 of these highly effective tools for Laravel developers are made by the well-known developer &lt;a href="https://github.com/nunomaduro" rel="noopener noreferrer"&gt;Nuno Maduro&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I know he accepts sponsorships via GitHub, please please, do consider giving a one-time donation. Equally consider looking at the developers of PHPStan, PHP CS Fixer and Rector who make these awesome tools possible.&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

&lt;p&gt;I’m Peter Fox, a software developer in the UK who works with Laravel among other things. Thank you for reading my article, If you’d like to encourage me to write more articles like this please do consider &lt;a href="https://github.com/sponsors/peterfox" rel="noopener noreferrer"&gt;dropping a small one-off donation&lt;/a&gt;! All my content is free to read and I hope to stay this way in the future.&lt;/p&gt;

</description>
      <category>linting</category>
      <category>php</category>
      <category>staticcodeanalysis</category>
    </item>
  </channel>
</rss>
