r/PowerShell•
donstrack

PowerShell PHP to HTML Converter

Because I am a total newbie, I asked Google Gemini to create a PowerShell script to convert 2000+ dynamic PHP files to static HTML files. I am in the process of archiving my website and would prefer static files. The only PHP I use is five lines in every file that provides variables for Title and Description, then calls the Header include, which is 57 lines for everything up to and including the <body>. The header.php calls the Title and Description variables, and adds the PHP string to add the Canonical, which is the file name. I use a couple simple javascripts, so I need to add the location of my /scripts folder. Before I use this PowerShell script, in what will be my first use of PowerShell, it would be nice if human eyes looked it over.

# --- Configuration ---
$sourceDir = "C:\path\to\your\php_files"
$targetDir = "C:\path\to\your\html_output"
$cssDir    = "C:\path\to\your\php_files\css"
$imgDir    = "C:\path\to\your\php_files\images"

if (!(Test-Path $targetDir)) { New-Item -ItemType Directory -Path $targetDir }

# --- Helper Function for Robust Extraction ---
function Get-PhpVar {
    param($pattern, $content, $default)
    # This regex looks for: $variable_name = "value"; OR $array['key'] = "value";
    # It accounts for optional spaces and different quote types.
    if ($content -match $pattern) { return $Matches[1].Trim() }
    return $default
}

$phpFiles = Get-ChildItem -Path $sourceDir -Filter "*.php"

foreach ($file in $phpFiles) {
    Write-Host "Converting: $($file.Name)" -ForegroundColor Cyan
    $content = Get-Content -Path $file.FullName -Raw

    # 1. Flexible Extraction Patterns
    # Matches: $title, $pageTitle, $_tpl['title'], $meta['title']
    $titlePattern = '(?i)\$(?:page)?title(?:\[[''"]title[''"]\])?\s*=\s*[''"](.+?)[''"]\s*;'
    $descPattern  = '(?i)\$(?:meta)?description(?:\[[''"]description[''"]\])?\s*=\s*[''"](.+?)[''"]\s*;'
    $canonPattern = '(?i)\$(?:page)?canonical(?:\[[''"]canonical[''"]\])?\s*=\s*[''"](.+?)[''"]\s*;'

    $title = Get-PhpVar $titlePattern $content "Default Title"
    $desc  = Get-PhpVar $descPattern $content ""
    $canon = Get-PhpVar $canonPattern $content $file.Name.Replace(".php", ".html")

    # 2. Process PHP Includes
    # Matches: include('file.php'); require "file.php"; include_once(...)
    $content = [regex]::Replace($content, '(?i)(?:include|require)(?:_once)?\s*\(?\s*[''"](.+?\.php)[''"]\s*\)?\s*;', {
        param($m)
        $includePath = Join-Path $sourceDir $m.Groups[1].Value
        if (Test-Path $includePath) { return Get-Content $includePath -Raw }
        return ""
    })

    # 3. Clean remaining PHP and assemble HTML5
    $cleanBody = $content -replace '(?s)<\?php.*?\?>', ''
    
    $htmlOutput = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>$title</title>
    <meta name="description" content="$desc">
    <link rel="canonical" href="$canon">
</head>
<body>
$cleanBody
</body>
</html>
"@

    # 4. Link Replacement (.php -> .html)
    $htmlOutput = $htmlOutput -replace 'href\s*=\s*["'']([^"'']+\.)php(["'']?)', 'href="$1html$2'

    # Save
    $newName = $file.BaseName + ".html"
    $htmlOutput | Out-File -FilePath (Join-Path $targetDir $newName) -Encoding utf8
}

# --- Asset Migration ---
Write-Host "Syncing Assets..." -ForegroundColor Green
@($cssDir, $imgDir) | ForEach-Object {
    if (Test-Path $_) {
        $folderName = Split-Path $_ -Leaf
        Copy-Item -Path $_ -Destination (Join-Path $targetDir $folderName) -Recurse -Force
    }
}

Write-Host "Success! Your site is now static HTML5." -ForegroundColor Goldenrod

Posted Feb 19, 2026, 3:11 PM UTC

04
Loading comments…