This article is part of my #100DaysOfCode and #100DaysOfBlogging challenge. R1D8

This is part one of a series of articles about the PHP Version Switcher.


Most of our costumers provide Windows Servers for the PHP applications we implement and maintain for them. Although it has become much easier to get a PHP running under Windows than ten years ago, it’s still not the choice environment for a typical PHP web application.

Last year a co-worker and I discussed the possibility of providing each project with a Vagrant box for development purposes that runs a comparable setup as the production environment. Until then each developer had his own WAMP setup and most likely non looked like any other development or production environment. I had a Linux machine in mind. Making the transition from Windows to Linux and providing the necessary infrastructure is not done in just one day.

In the discussion I addressed the laborious manual process of switching in-between PHP versions. Then it dawned on me that by using symlinks, it might be possible to easily switch to another PHP version. Later on, I started working on the setup and wrote a batch file - and surely it worked! 🙌😊

Lately I have become fond of PowerShell. Today I want to start rewriting that batch file of the PHP version switcher into a PowerShell module. For now, I am starting with a PowerShell Module. Tomorrow I continue with the rewrite. An additional feature is a PHP version manager, which would allow the installing and removing PHP versions. I’ll see how far that can be automated on another day.

Creating a PowerShell Module

The functionality of the PHP version switcher will be placed in a Cmdlet. The plan is to make the Cmdlet available through a Module and possibly publish it on PowerShell Gallery and/or chocolatey.

To create my first PowerShell module, I follow the article How to Write a PowerShell Script Module. Right now I only need steps 1 and 2. If you want to know more about the steps or further steps not mentioned here, head over to the referenced article.

1. Save PowerShell script with a .psm1 extension

Since I don’t have an existing PowerShell script and can’t just dump in the batch file, I am starting with a fresh function. For now, I just want to declare my function and parameters. Then give the user some output. The real functionality will be added later.

function Php-VersionSwitcher
{
    Param (
        [Parameter(Mandatory=$true, ValueFromPipeline=$true)] [Alias("v")] [String]$version
    )

    Write-Host "PHP Version Switcher 1.0.0 by Andi Rückauer" -ForegroundColor Blue
    Write-Host ""
    Write-Host "Switching to version: $version..." -ForegroundColor DarkCyan
    Write-Host ""
}

I save this to the file Php-VersionSwitcher.psm1.

2. Export-ModuleMember

The function would be exposed by default. It is recommended however, to explicitly declare functions one wants to expose. Here it goes.

Export-ModuleMember -Function Php-VersionSwitcher

Create PowerShell Module Manifest

Next, I follow the instructions found in How to Write a PowerShell Module Manifest. I’ll go with option 1.b. and create the Manifest with the New-ModuleManifest cmdlet.

New-ModuleManifest .\Php-VersionSwitcher.psd1 -ModuleVersion 1.0 -Author "Andi Rückauer"

I open the Php-VersionSwitcher.psd1 and update necessary and removing unnecessary information. This is what it looks like now.

@{

    # Die diesem Manifest zugeordnete Skript- oder Binärmoduldatei.
    RootModule          = 'Php-VersionSwitcher.psm1'

    # Die Versionsnummer dieses Moduls
    ModuleVersion       = '1.0.0'

    # ID zur eindeutigen Kennzeichnung dieses Moduls
    GUID                = '69305790-69cd-4ffe-af1c-f7ec6e486d13'

    # Autor dieses Moduls
    Author              = 'Andi Rückauer'

    # Unternehmen oder Hersteller dieses Moduls
    CompanyName         = 'Unbekannt'

    # Urheberrechtserklärung für dieses Modul
    Copyright           = '(c) 2019 Andi Rückauer. Alle Rechte vorbehalten.'

    # Beschreibung der von diesem Modul bereitgestellten Funktionen
    Description         = 'Switching PHP versions on Windows made easy'

    # Die für dieses Modul mindestens erforderliche Version des Windows PowerShell-Moduls
    PowerShellVersion   = '5.0'

    # Aus diesem Modul zu exportierende Funktionen. Um optimale Leistung zu erzielen, verwenden Sie keine Platzhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Funktionen vorhanden sind.
    FunctionsToExport   = @('Php-VersionSwitcher')

    # Aus diesem Modul zu exportierende Cmdlets. Um optimale Leistung zu erzielen, verwenden Sie keine Platzhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Cmdlets vorhanden sind.
    CmdletsToExport     = @()

    # Die aus diesem Modul zu exportierenden Variablen
    VariablesToExport   = '*'

    # Aus diesem Modul zu exportierende Aliase. Um optimale Leistung zu erzielen, verwenden Sie keine Platzhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Aliase vorhanden sind.
    AliasesToExport     = @()

    # Die privaten Daten, die an das in "RootModule/ModuleToProcess" angegebene Modul übergeben werden sollen. Diese können auch eine PSData-Hashtabelle mit zusätzlichen von PowerShell verwendeten Modulmetadaten enthalten.
    PrivateData = @{

        PSData = @{

            # 'Tags' wurde auf das Modul angewendet und unterstützt die Modulermittlung in Onlinekatalogen.
            Tags         = @('php', 'version')

            # Eine URL zur Lizenz für dieses Modul.
            LicenseUri   = 'https://github.com/arueckauer/Php-VersionSwitcher/blob/master/LICENSE.txt'

            # Eine URL zur Hauptwebsite für dieses Projekt.
            ProjectUri   = 'https://github.com/arueckauer/Php-VersionSwitcher'

            # Eine URL zu einem Symbol, das das Modul darstellt.
            # IconUri = ''

            # 'ReleaseNotes' des Moduls
            ReleaseNotes = 'https://github.com/arueckauer/Php-VersionSwitcher/blob/master/CHANGELOG.md'

        }

    }

}

Giving the module a new home

Since I am using a custom PowerShell profile and posh-git, I do already have a WindowsPowerShell folder in my user’s documents path (C:\Users\<Username>\Documents\WindowsPowerShell). If you’re using a machine, where you don’t have that folder, have a look at the Import-Module might help you getting there.

I am moving the two created files Php-VersionSwitcher.psm1 and Php-VersionSwitcher.psd1 to a new home for my custom module: C:\Users\Rueckauer\Documents\WindowsPowerShell\Modules\Php-VersionSwitcher\1.0.0.

Import-Module

In my PowerShell profile (C:\Users\Rueckauer\Documents\WindowsPowerShell\profile.ps1) I add a line to import my new module.

Import-Module Php-VersionSwitcher

Test it

Now I power up a new PowerShell and try to access the Php-VersionSwitcher function.

Hm, I do get a warning. 🤔

WARNUNG: Die Namen einiger importierter Befehle auf Modul “Php-VersionSwitcher” enthalten nicht genehmigte Verben, sodass deren Auffindbarkeit erschwert werden kann. Wenn Sie die Befehle mit nicht genehmigten Verben finden möchten, führen Sie den Import-Module-Befehl erneut mit dem Verbose-Parameter aus. Sie können durch Eingeben von “Get-Verb” eine Liste der genehmigten Verben anzeigen.

Something is not right with the module name. I need to figure that out later. Let’s see, if it works despite the warning.

Execution of Php-VersionSwitcher

Yes, neat! 💪🏻

Okay, that’s it for today. Next time I will breath some life into that function.