public/Install-Php.ps1
function Install-Php() { <# .Synopsis Installs PHP. .Description Download and installs a version of PHP. .Parameter Version Specify the PHP version to be installed. You can use the following syntaxes: - '7' will install the latest '7' version (for example: 7.2.4) - '7.1' will install the latest '7.1' version (for example: 7.1.16) - '7.1.15' will install the exact '7.1.15' version - '7RC' will install the latest release candidate for PHP 7 - '7.1RC' will install the latest release candidate for PHP 7.1 - '7.1.17RC' will install the latest release candidate for PHP 7.1.17 - '7.1.17RC2' will install the exact release candidate for PHP 7.1.17RC2 - '7.1snapshot' will install the exact release candidate for PHP 7.1.17RC2 - 'master' will install the very latest master snapshot .Parameter Architecture The architecture of the PHP to be installed (x86 for 32-bit, x64 for 64-bit). .Parameter ThreadSafe A boolean value to indicate if the Thread-Safe version should be installed or not. You usually install the ThreadSafe version if you plan to use PHP with Apache, or the NonThreadSafe version if you'll use PHP in CGI mode. .Parameter Path The path of the directory where PHP will be installed. .Parameter TimeZone The PHP time zone to configure if php.ini does not exist (if not specified: we'll use UTC). .Parameter AddToPath Specify if you want to add the PHP installation folder to the user ('User') or system ('System') PATH environment variable. Please remark that using 'System' usually requires administrative rights. .Parameter InitialPhpIni Specify to initialize the initial php.ini with the bundled php.ini-production ('Production') or with the bundled php.ini-development ('Development'). If you don't specify this value, an almost empty php.ini will be created. .Parameter InstallVC Specify this switch to try to install automatically the required Visual C++ Redistributables (requires the VcRedist PowerShell package, and to run the process as an elevated user). .Parameter Force Use this switch to enable installing PHP even if the destination directory already exists and it's not empty. #> [OutputType()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'ThreadSafe', Justification = 'False positive as rule does not know that Where-Object operates within the same scope')] # See https://github.com/PowerShell/PSScriptAnalyzer/issues/1472 param ( [Parameter(Mandatory = $true, Position = 0, HelpMessage = 'The PHP version to be installed')] [ValidatePattern('^(master|(\d+\.\d+snapshot)|(\d+(\.\d+)?(\.\d+)?((alpha|beta|RC)\d*)?))$')] [string] $Version, [Parameter(Mandatory = $true, Position = 1, HelpMessage = 'Architecture of the PHP to be installed (x86 for 32-bit, x64 for 64-bit)')] [ValidateSet('x86', 'x64')] [string] $Architecture, [Parameter(Mandatory = $true, Position = 2, HelpMessage = 'Install a Thread-Safe version?')] [bool] $ThreadSafe, [Parameter(Mandatory = $true, Position = 3, HelpMessage = 'The path of the directory where PHP will be installed')] [ValidateLength(1, [int]::MaxValue)] [string] $Path, [Parameter(Mandatory = $false, Position = 4, HelpMessage = 'The PHP time zone to configure if php.ini does not exist (if not specified: we''ll use UTC)')] [string] $TimeZone, [Parameter(Mandatory = $false, Position = 5, HelpMessage = 'Specify if you want to add the PHP installation folder to the user (''User'') or system (''System'') PATH environment variable')] [ValidateSet('User', 'System')] [string] $AddToPath, [Parameter(Mandatory = $false, Position = 6, HelpMessage = 'Specify to initialize the initial php.ini with the bundled php.ini-production (''Production'') or with the bundled php.ini-development (''Development''); if you don''t specify this value, an almost empty php.ini will be created')] [ValidateSet('Production', 'Development')] [string] $InitialPhpIni, [switch] $InstallVC, [switch] $Force ) begin { } process { if ($Architecture -eq 'x64' -and [System.IntPtr]::Size -lt 8) { throw 'The current operating system is not 64 bits: you can only install with the x86 architecture' } $Path = [System.IO.Path]::GetFullPath($Path) # Check existency if (Test-Path -Path $Path -PathType Leaf) { throw "The specified installation path ($Path) points to an existing file" } if (-Not($Force)) { if (Test-Path -Path $([System.IO.Path]::Combine($Path, '*'))) { throw "The specified installation path ($Path) exists and it's not empty (use the -Force flag to force the installation)" } } # Check $Version format if ($Version -eq 'master') { $searchReleaseStates = @($Script:RELEASESTATE_SNAPSHOT) $rxSearchVersion = '^master$' } else { $match = $Version | Select-String -Pattern "^(\d+\.\d+)snapshot$" if ($null -ne $match) { $searchReleaseStates = @($Script:RELEASESTATE_SNAPSHOT) $rxSearchVersion = "^$($match.Matches[0].Groups[1].Value -replace '\.', '\.')-dev$" } else { $match = $Version | Select-String -Pattern "^([1-9]\d*)(?:\.(\d+))?(?:\.(\d+))?(?:($Script:UNSTABLEPHP_RX)(\d*))?$" if ($null -eq $match) { throw "The specified PHP version ($Version) is malformed" } # Build the regular expression to match the version, and determine the list of release states $rxSearchVersion = '^' $rxSearchVersion += $match.Matches.Groups[1].Value + '\.' if ($match.Matches.Groups[2].Value -eq '') { $rxSearchVersion += '\d+\.\d+' } else { $rxSearchVersion += [string][int]$match.Matches.Groups[2].Value + '\.' if ($match.Matches.Groups[3].Value -eq '') { $rxSearchVersion += '\d+' } else { $rxSearchVersion += [string][int]$match.Matches.Groups[3].Value } } if ($match.Matches.Groups[4].Value -eq '') { $searchReleaseStates = @($Script:RELEASESTATE_RELEASE, $Script:RELEASESTATE_ARCHIVE) } else { $rxSearchVersion += $match.Matches.Groups[4].Value if ($match.Matches.Groups[5].Value -eq '') { $rxSearchVersion += '\d+' } else { $rxSearchVersion += [string][int]$match.Matches.Groups[5].Value } $searchReleaseStates = @($Script:RELEASESTATE_QA) } $rxSearchVersion += '$' } } # Filter the list of available PHP versions, and get the latest one $versionToInstall = $null foreach ($searchReleaseState in $searchReleaseStates) { $compatibleVersions = Get-PhpAvailableVersion -State $searchReleaseState | Where-Object { $_.FullVersion -match $rxSearchVersion -and $_.Architecture -eq $Architecture -and $_.ThreadSafe -eq $ThreadSafe } foreach ($compatibleVersion in $compatibleVersions) { if ($null -eq $versionToInstall) { $versionToInstall = $compatibleVersion } elseif ($compatibleVersions -gt $versionToInstall) { $versionToInstall = $compatibleVersion } } if ($null -ne $versionToInstall) { break } } if ($null -eq $versionToInstall) { throw 'No PHP version matches the specified criterias' } # Install the found PHP version Write-Verbose $('Installing PHP ' + $versionToInstall.DisplayName) Install-PhpFromUrl -Url $versionToInstall.DownloadUrl -Path $Path -PhpVersion $versionToInstall -InstallVCRedist $InstallVC # Initialize the php.ini $iniPath = [System.IO.Path]::Combine($Path, 'php.ini'); if ($null -ne $InitialPhpIni -and $InitialPhpIni -ne '') { $sourceIniPath = [System.IO.Path]::Combine($Path, 'php.ini-' + $InitialPhpIni.ToLowerInvariant()); Copy-Item -Path $sourceIniPath -Destination $iniPath -Force $initializePhpIni = $true } else { $initializePhpIni = -Not(Test-Path -Path $iniPath -PathType Leaf) } if ($initializePhpIni) { if ($null -eq $TimeZone -or $TimeZone -eq '') { $TimeZone = 'UTC' } Set-PhpIniKey -Key 'date.timezone' -Value $TimeZone -Path $iniPath Set-PhpIniKey -Key 'default_charset' -Value 'UTF-8' -Path $iniPath Set-PhpIniKey -Key 'extension_dir' -Value $([System.IO.Path]::Combine($Path, 'ext')) -Path $iniPath } if ($null -ne $AddToPath -and $AddToPath -ne '') { Edit-FolderInPath -Operation Add -Path $Path -Persist $AddToPath -CurrentProcess } } end { } } |