Skip to content

Commit

Permalink
Add support to PHP 7.4, add support to installing alpha/beta/RC versions
Browse files Browse the repository at this point in the history
  • Loading branch information
mlocati committed Jun 14, 2019
1 parent bfc92a1 commit ea65e17
Show file tree
Hide file tree
Showing 13 changed files with 110 additions and 45 deletions.
21 changes: 15 additions & 6 deletions PhpManager/private/Constants.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,16 @@ New-Variable -Option Constant -Scope Script -Name 'RELEASESTATE_ARCHIVE' -Value
New-Variable -Option Constant -Scope Script -Name 'ARCHITECTURE_32BITS' -Value 'x86'
New-Variable -Option Constant -Scope Script -Name 'ARCHITECTURE_64BITS' -Value 'x64'

New-Variable -Option Constant -Scope Script -Name 'RX_ZIPARCHIVE' -Value 'php-(\d+\.\d+\.\d+)(?:RC([1-9]\d*))?(-nts)?-Win32-VC(\d{1,2})-(x86|x64)\.zip'
# PHP non-stable identifier: Alpha
New-Variable -Option Constant -Scope Script -Name 'UNSTABLEPHP_ALPHA' -Value 'alpha'
# PHP non-stable identifier: Beta
New-Variable -Option Constant -Scope Script -Name 'UNSTABLEPHP_BETA' -Value 'beta'
# PHP non-stable identifier: Release candidate
New-Variable -Option Constant -Scope Script -Name 'UNSTABLEPHP_RELEASECANDIDATE' -Value 'RC'
# PHP non-stable identifiers regex
New-Variable -Option Constant -Scope Script -Name 'UNSTABLEPHP_RX' -Value "$UNSTABLEPHP_ALPHA|$UNSTABLEPHP_BETA|$UNSTABLEPHP_RELEASECANDIDATE"

New-Variable -Option Constant -Scope Script -Name 'RX_ZIPARCHIVE' -Value "php-(\d+\.\d+\.\d+)(?:($UNSTABLEPHP_RX)([1-9]\d*))?(-nts)?-Win32-(?:VC|vs)(\d{1,2})-(x86|x64)\.zip"

New-Variable -Option Constant -Scope Script -Name 'EXTENSIONSTATE_BUILTIN' -Value 'Builtin'
New-Variable -Option Constant -Scope Script -Name 'EXTENSIONSTATE_UNKNOWN' -Value 'Unknown'
Expand All @@ -28,15 +37,15 @@ New-Variable -Option Constant -Scope Script -Name 'ENVTARGET_MACHINE' -Value 'Ma

New-Variable -Option Constant -Scope Script -Name 'URL_PECLREST_1_0' -Value 'https://pecl.php.net/rest/'

# A production release.
# PEAR stability: a production release.
New-Variable -Option Constant -Scope Script -Name 'PEARSTATE_STABLE' -Value 'stable'
# A non-production release. Beta should be used for code that has a stable API and is nearing a fully stable release. Regresion tests and documentation should exist or soon follow to qualify as a beta release. Release candidates should use the beta stability.
# PEAR stability: a non-production release. Beta should be used for code that has a stable API and is nearing a fully stable release. Regresion tests and documentation should exist or soon follow to qualify as a beta release. Release candidates should use the beta stability.
New-Variable -Option Constant -Scope Script -Name 'PEARSTATE_BETA' -Value 'beta'
# A new non-production release. Alpha should be used for new code that has an unstable API or untested code.
# PEAR stability: a new non-production release. Alpha should be used for new code that has an unstable API or untested code.
New-Variable -Option Constant -Scope Script -Name 'PEARSTATE_ALPHA' -Value 'alpha'
# A very new non-production release. Devel should be used for extremely new, practically untested code.
# PEAR stability: a very new non-production release. Devel should be used for extremely new, practically untested code.
New-Variable -Option Constant -Scope Script -Name 'PEARSTATE_DEVEL' -Value 'devel'
# A frozen picture of development at a particular moment.
# PEAR stability: a frozen picture of development at a particular moment.
New-Variable -Option Constant -Scope Script -Name 'PEARSTATE_SNAPSHOT' -Value 'snapshot'

New-Variable -Option Constant -Scope Script -Name 'CACERT_PEM_URL' -Value 'https://curl.haxx.se/ca/cacert.pem'
Expand Down
2 changes: 1 addition & 1 deletion PhpManager/private/Get-PeclArchiveUrl.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
$rxMatch += '-' + [regex]::Escape($PackageVersion)
$rxMatch += '-' + [regex]::Escape('' + $PhpVersion.ComparableVersion.Major + '.' + $PhpVersion.ComparableVersion.Minor)
$rxMatch += '-' + $(if ($PhpVersion.ThreadSafe) { 'ts' } else { 'nts' } )
$rxMatch += '-vc' + $PhpVersion.VCVersion
$rxMatch += '-(vc|vs)' + $PhpVersion.VCVersion
$rxMatch += '-' + [regex]::Escape($PhpVersion.Architecture)
$rxMatch += '\.zip$'
$urls = @("https://windows.php.net/downloads/pecl/releases/$handleLC/$PackageVersion")
Expand Down
9 changes: 5 additions & 4 deletions PhpManager/private/Get-PhpVersionFromUrl.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@
}
$data = @{}
$data.Version = $match.Matches.Groups[1].Value;
$data.RC = $match.Matches.Groups[2].Value;
$data.Architecture = $match.Matches.Groups[5].Value;
$data.ThreadSafe = $match.Matches.Groups[3].Value -ne '-nts';
$data.VCVersion = $match.Matches.Groups[4].Value;
$data.UnstabilityLevel = $match.Matches.Groups[2].Value;
$data.UnstabilityVersion = $match.Matches.Groups[3].Value;
$data.Architecture = $match.Matches.Groups[6].Value;
$data.ThreadSafe = $match.Matches.Groups[4].Value -ne '-nts';
$data.VCVersion = $match.Matches.Groups[5].Value;
$data.ReleaseState = $ReleaseState;
if ($null -ne $PageUrl -and $PageUrl -ne '') {
$data.DownloadUrl = [Uri]::new([Uri]$PageUrl, $Url).AbsoluteUri
Expand Down
2 changes: 1 addition & 1 deletion PhpManager/private/Install-PhpExtensionPrerequisite.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
Write-Verbose ('Checking prerequisites for {0}' -f $Extension.Name)
switch ($Extension.Handle) {
imagick {
$rxSearch = '/ImageMagick-[\d\.\-]+-vc' + $PhpVersion.VCVersion + '-' + $PhpVersion.Architecture + '\.zip$'
$rxSearch = '/ImageMagick-[\d\.\-]+-(vc|vs)' + $PhpVersion.VCVersion + '-' + $PhpVersion.Architecture + '\.zip$'
$pageUrl = 'https://windows.php.net/downloads/pecl/deps/'
Set-NetSecurityProtocolType
$webResponse = Invoke-WebRequest -UseBasicParsing -Uri $pageUrl
Expand Down
14 changes: 11 additions & 3 deletions PhpManager/private/Install-PhpFromUrl.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,13 @@
if (-Not(Test-Path -Path $exePath -PathType Leaf)) {
throw "Unable to find php.exe in the downloaded archive"
}
& $exePath @('-n', '-v') | Out-Null
if ($LASTEXITCODE -eq $Script:STATUS_DLL_NOT_FOUND -or $LASTEXITCODE -eq $Script:ENTRYPOINT_NOT_FOUND) {
try {
$exeOutput = & $exePath @('-n', '-v') 2>&1 | Out-String
} catch {
$exeOutput = $_.Exception.Message
}
$exeExitCode = $LASTEXITCODE
if ($exeExitCode -eq $Script:STATUS_DLL_NOT_FOUND -or $exeExitCode -eq $Script:ENTRYPOINT_NOT_FOUND -or $exeOutput -match 'vcruntime.*is not compatible with this PHP build') {
switch ($PhpVersion.VCVersion) {
6 { $redistName = '6' } # PHP 5.2, PHP 5.3
7 { $redistName = '2002' }
Expand All @@ -61,7 +66,8 @@
11 { $redistName = '2012' } # PHP 5.5, PHP 5.6
12 { $redistName = '2013' }
14 { $redistName = '2015' } # PHP 7.0, PHP 7.1
15 { $redistName = '2017' } # PHP 7.2
15 { $redistName = '2017' } # PHP 7.2, PHP 7.3
16 { $redistName = '2019' } # PHP 7.4
default {
throw ('The Visual C++ ' + $PhpVersion.VCVersion + ' Redistributable seems to be missing: you have to install it manually (we can''t recognize its version)')
}
Expand Down Expand Up @@ -102,6 +108,8 @@
Write-Debug 'Failed to remove temporary folder'
}
}
} elseif ($exeExitCode -ne 0) {
throw "Running PHP resulted in the following error:`n$exeOutput"
}
} finally {
try {
Expand Down
82 changes: 59 additions & 23 deletions PhpManager/private/PhpVersion.ps1
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
class PhpVersion : System.IComparable
{
<#
The version of PHP, without the RC state
The version of PHP, without the alpha/beta/RC state
#>
[string]
[ValidateNotNull()]
[ValidateLength(1, [int]::MaxValue)]
$Version
<#
The number of the release candidate, if any
The unstability level, if any (alpha, beta, RC)
#>
[Nullable[int]] $RC
[string]
[ValidateNotNull()]
$UnstabilityLevel
<#
the version of PHP, possibly including the RC state
The unstability version, if any
#>
[Nullable[int]] $UnstabilityVersion
<#
the version of PHP, possibly including the alpha/beta/RC state
#>
[ValidateNotNull()]
[ValidateLength(1, [int]::MaxValue)]
Expand Down Expand Up @@ -48,26 +54,49 @@
Initialize the instance.
Keys for $data:
- Version: required
- RC: optional
- UnstabilityLevel: optional
- UnstabilityVersion: optional
- Architecture: required
- ThreadSafe: required
- VCVersion: required
#>
hidden PhpVersion([hashtable] $data)
{
$this.Version = $data.Version
if ($data.ContainsKey('RC') -and $data.RC -ne '') {
$this.RC = [int] $data.RC
if ($data.ContainsKey('UnstabilityLevel') -and $null -ne $data.UnstabilityLevel) {
$this.UnstabilityLevel = $data.UnstabilityLevel
} else {
$this.UnstabilityLevel = ''
}
if ($data.ContainsKey('UnstabilityVersion') -and $null -ne $data.UnstabilityVersion -and $data.UnstabilityVersion -ne '') {
if ($this.UnstabilityLevel -eq '') {
throw "UnstabilityVersion provided without UnstabilityLevel"
}
$this.UnstabilityVersion = [int] $data.UnstabilityVersion
} else {
$this.RC = $null
$this.UnstabilityLevel = $null
}
$dv = $this.Version
$cv = $this.Version
if ($null -eq $this.RC) {
$cv += '.9999'
} else {
$dv += 'RC' + $this.RC
$cv += '.' + $this.RC
switch ($this.UnstabilityLevel) {
'' {
$cv += '.9999999'
}
$Script:UNSTABLEPHP_RELEASECANDIDATE {
$dv += $Script:UNSTABLEPHP_RELEASECANDIDATE + $this.UnstabilityVersion
$cv += '.' + (8000000 + $this.UnstabilityVersion)
}
$Script:UNSTABLEPHP_BETA {
$dv += $Script:UNSTABLEPHP_BETA + $this.UnstabilityVersion
$cv += '.' + (4000000 + $this.UnstabilityVersion)
}
$Script:UNSTABLEPHP_ALPHA {
$dv += $Script:UNSTABLEPHP_ALPHA + $this.UnstabilityVersion
$cv += '.' + (2000000 + $this.UnstabilityVersion)
}
default {
throw 'Unrecognized UnstabilityLevel'
}
}
$this.FullVersion = $dv
$this.ComparableVersion = [System.Version] $cv
Expand Down Expand Up @@ -231,22 +260,29 @@ class PhpVersionInstalled : PhpVersion
if (-Not($executableResult)) {
throw "Failed to execute php.exe: $LASTEXITCODE"
}
$match = $executableResult | Select-String -Pattern '^(\d+\.\d+\.\d+)(?:RC(\d+))?@(\d+)$'
$match = $executableResult | Select-String -Pattern "^(\d+\.\d+\.\d+)(?:($Script:UNSTABLEPHP_RX)(\d+))?@(\d+)$"
$data.Version = $match.Matches.Groups[1].Value
$data.RC = $match.Matches.Groups[2].Value
$data.Architecture = Get-Variable -Scope Script -ValueOnly -Name $('ARCHITECTURE_' + $match.Matches.Groups[3].Value + 'BITS')
$data.UnstabilityLevel = $match.Matches.Groups[2].Value
$data.UnstabilityVersion = $match.Matches.Groups[3].Value
$data.Architecture = Get-Variable -Scope Script -ValueOnly -Name $('ARCHITECTURE_' + $match.Matches.Groups[4].Value + 'BITS')
$executableResult = & $data.ExecutablePath @('-i')
$match = $executableResult | Select-String -CaseSensitive -Pattern '^[ \t]*Thread Safety\s*=>\s*(\w+)'
$data.ThreadSafe = $match.Matches.Groups[1].Value -eq 'enabled'
$match = $executableResult | Select-String -CaseSensitive -Pattern '^[ \t]*Compiler\s*=>\s*MSVC([\d]{1,2})'
if ($null -eq $match) {
if ([System.Version]$data.Version -le [System.Version]'5.2.9999') {
$data.VCVersion = 6
} else {
throw 'Failed to recognize VCVersion'
}
} else {
if ($null -ne $match) {
$data.VCVersion = $match.Matches.Groups[1].Value
} elseif ([System.Version]$data.Version -le [System.Version]'5.2.9999') {
$data.VCVersion = 6
} else {
$match = $executableResult | Select-String -CaseSensitive -Pattern '^[ \t]*Compiler\s*=>\s*Visual C\+\+\s+(\d{4})(?:\s|$)'
if ($null -eq $match) {
throw "Failed to recognize VCVersion"
}
$vcYear = $match.Matches.Groups[1].Value
switch ($vcYear) {
'2019' { $data.VCVersion = 16 }
default { throw "Failed to recognize VCVersion from Visual C++ $vcYear" }
}
}
$match = $executableResult | Select-String -CaseSensitive -Pattern '^[ \t]*Loaded Configuration File\s*=>\s*([\S].*[\S])\s*$'
$data.IniPath = ''
Expand Down
Binary file modified PhpManager/private/bin/Inspect-PhpExtension-x64.exe
Binary file not shown.
Binary file modified PhpManager/private/bin/Inspect-PhpExtension-x86.exe
Binary file not shown.
6 changes: 3 additions & 3 deletions PhpManager/public/Install-Php.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
[OutputType()]
param (
[Parameter(Mandatory = $true, Position = 0, HelpMessage = 'The PHP version to be installed')]
[ValidatePattern('^\d+(\.\d+)?(\.\d+)?(RC\d*)?$')]
[ValidatePattern('^\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')]
Expand Down Expand Up @@ -85,7 +85,7 @@
}
}
# Check $Version format
$match = $Version | Select-String -Pattern '^([1-9]\d*)(?:\.(\d+))?(?:\.(\d+))?(RC(\d*))?$'
$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"
}
Expand All @@ -105,7 +105,7 @@
if ($match.Matches.Groups[4].Value -eq '') {
$searchReleaseStates = @($Script:RELEASESTATE_RELEASE, $Script:RELEASESTATE_ARCHIVE)
} else {
$rxSearchVersion += 'RC'
$rxSearchVersion += $match.Matches.Groups[4].Value
if ($match.Matches.Groups[5].Value -eq '') {
$rxSearchVersion += '\d+'
} else {
Expand Down
2 changes: 1 addition & 1 deletion PhpManager/public/Update-Php.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
} else {
$installedVersion = [PhpVersionInstalled]::FromPath($Path)
}
if ($null -eq $installedVersion.RC) {
if ($installedVersion.UnstabilityLevel -eq '') {
$possibleReleaseStates = @($Script:RELEASESTATE_RELEASE, $Script:RELEASESTATE_ARCHIVE)
} else {
$possibleReleaseStates = @($Script:RELEASESTATE_QA)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Install-Php -Version 7.2 -Architecture x64 -ThreadSafe 0 -Path C:\PHP -TimeZone

Use the `Update-Php` command to upgrade PHP.
The command will automatically check if there's a newer version available: if so, the PHP installation will be upgraded.
Please note that non-release candidate (RC) versions will be upgraded to non-RC versions, and RC versions will be upgraded to RC versions.
Please note that stable versions will be upgraded to stable, and non-stable (alpha/beta/release candidate) versions will be upgraded to non-stable versions.
Also the 32/64 bit and the thread safety will be the same.

```powershell
Expand Down
9 changes: 9 additions & 0 deletions src/Inspect-PhpExtension.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <inttypes.h>
#include <stdio.h>

// https://github.com/php/php-src/blob/php-7.4.0alpha1/Zend/zend_modules.h#L34
#define ZMA_PHP_7_4 20190529
// https://github.com/php/php-src/blob/php-7.3.0beta1/Zend/zend_modules.h#L34
// https://github.com/php/php-src/blob/php-7.3.6/Zend/zend_modules.h#L34
#define ZMA_PHP_7_3 20180731
Expand Down Expand Up @@ -48,6 +50,7 @@ typedef struct {
LPCSTR version;
} extensionInfo;

// zend_module_entry is defined in php/Zend/zend_modules.h
typedef struct {
uint16_t size;
DWORD zend_api;
Expand All @@ -67,6 +70,7 @@ typedef struct {
LPVOID request_shutdown_func;
LPVOID info_func;
LPCSTR version;
// etcetera
} zend_module_entry_20050617;

typedef struct {
Expand All @@ -82,6 +86,7 @@ typedef struct {
LPVOID request_shutdown_func;
LPVOID info_func;
LPCSTR version;
// etcetera
} zend_module_entry_20020429;

typedef zend_module_entry_Base*(__stdcall *getModuleEntryBase)();
Expand All @@ -103,6 +108,10 @@ void parsePhpExtension(HMODULE hModule, extensionInfo* extensionInfo)
if (get_moduleAddress != NULL) {
zend_module_entry_Base* zmeBase = ((getModuleEntryBase)get_moduleAddress)();
switch (zmeBase->zend_api) {
case ZMA_PHP_7_4:
if (extensionInfo->php == NULL) {
extensionInfo->php = "7.4";
}
case ZMA_PHP_7_3:
if (extensionInfo->php == NULL) {
extensionInfo->php = "7.3";
Expand Down
6 changes: 4 additions & 2 deletions test/tests/Install-Get-Update-Uninstall-Php.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
$initialPhpVersion.Version | Should -BeOfType [string]
$initialPhpVersion.Version | Should -BeExactly '7.1.0'
$initialPhpVersion.ComparableVersion | Should -BeOfType [version]
$initialPhpVersion.RC | Should -BeNullOrEmpty
$initialPhpVersion.UnstabilityLevel | Should -BeNullOrEmpty
$initialPhpVersion.UnstabilityVersion | Should -BeNullOrEmpty
$initialPhpVersion.FullVersion | Should -BeExactly $initialPhpVersion.Version
$initialPhpVersion.DisplayName | Should -BeLike "*$($initialPhpVersion.Version)*"
$initialPhpVersion.Architecture | Should -BeExactly 'x64'
Expand All @@ -33,7 +34,8 @@
$updatedPhpVersion.Version | Should -Match '^7\.1\.'
$updatedPhpVersion.ComparableVersion | Should -BeOfType [version]
$updatedPhpVersion.ComparableVersion | Should -BeGreaterThan $initialPhpVersion.ComparableVersion
$updatedPhpVersion.RC | Should -BeNullOrEmpty
$updatedPhpVersion.UnstabilityLevel | Should -BeNullOrEmpty
$updatedPhpVersion.UnstabilityVersion | Should -BeNullOrEmpty
$updatedPhpVersion.FullVersion | Should -BeExactly $updatedPhpVersion.Version
$updatedPhpVersion.DisplayName | Should -BeLike "*$($updatedPhpVersion.Version)*"
$updatedPhpVersion.Architecture | Should -BeExactly $initialPhpVersion.Architecture
Expand Down

0 comments on commit ea65e17

Please sign in to comment.