PHP - Native Handler
PHP webhook handler using native functions.
<?php
$secret = "your_secret";
// Read payload
$payload = file_get_contents("php://input");
$signature = $_SERVER["HTTP_X_HUB_SIGNATURE_256"] ?? "";
// Verify signature
$hash = "sha256=" . hash_hmac("sha256", $payload, $secret);
if (!hash_equals($hash, $signature)) {
http_response_code(401);
exit("Invalid signature");
}
// Handle event
$event = $_SERVER["HTTP_X_GITHUB_EVENT"] ?? "unknown";
if ($event === "push") {
shell_exec("sh /path/to/deploy.sh");
}
echo "OK";
?>
PHP - Verify Signature
Signature verification function.
<?php
function verifyGitHubSignature($payload, $signature, $secret) {
if (empty($signature)) {
return false;
}
$hash = "sha256=" . hash_hmac("sha256", $payload, $secret);
return hash_equals($hash, $signature);
}
// Usage
$payload = file_get_contents("php://input");
$signature = $_SERVER["HTTP_X_HUB_SIGNATURE_256"] ?? "";
$secret = "your_webhook_secret";
if (!verifyGitHubSignature($payload, $signature, $secret)) {
http_response_code(401);
exit("Invalid signature");
}
?>
PHP - Parse JSON Payload
Parse and process webhook payload.
<?php
$payload = file_get_contents("php://input");
$data = json_decode($payload, true);
// Get repository information
$repo = $data['repository']['name'] ?? '';
$branch = $data['ref'] ?? '';
$pusher = $data['pusher']['name'] ?? '';
// Log webhook event
error_log("Webhook received: $repo, $branch by $pusher");
// Execute deployment
if ($branch === 'refs/heads/main') {
shell_exec("cd /var/www/html && git pull origin main");
}
?>
PHP - Complete Example
Full working PHP webhook handler with error handling.
<?php
// Configuration
$secret = getenv('WEBHOOK_SECRET') ?: 'your_secret';
$deploy_script = '/path/to/deploy.sh';
$log_file = '/var/log/github-webhook.log';
// Read payload
$payload = file_get_contents("php://input");
$signature = $_SERVER["HTTP_X_HUB_SIGNATURE_256"] ?? "";
$event = $_SERVER["HTTP_X_GITHUB_EVENT"] ?? "unknown";
// Log request
file_put_contents($log_file, date('Y-m-d H:i:s') . " - Event: $event\n", FILE_APPEND);
// Verify signature
$hash = "sha256=" . hash_hmac("sha256", $payload, $secret);
if (!hash_equals($hash, $signature)) {
http_response_code(401);
file_put_contents($log_file, "Invalid signature\n", FILE_APPEND);
exit("Invalid signature");
}
// Handle push event
if ($event === "push") {
$data = json_decode($payload, true);
$branch = $data['ref'] ?? '';
file_put_contents($log_file, "Push to: $branch\n", FILE_APPEND);
// Execute deployment script
$output = shell_exec("sh $deploy_script 2>&1");
file_put_contents($log_file, "Deploy output: $output\n", FILE_APPEND);
}
http_response_code(200);
echo "OK";
?>
Run - Development
Run PHP development server.
# Start built-in server
php -S 0.0.0.0:8000
# Test webhook
curl -X POST http://localhost:8000/webhook.php \
-H "X-GitHub-Event: push" \
-d '{"ref":"refs/heads/main"}'
Run - Apache
Apache configuration for PHP webhook.
<VirtualHost *:80>
ServerName webhook.example.com
DocumentRoot /var/www/webhook
<Directory /var/www/webhook>
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/webhook_error.log
CustomLog ${APACHE_LOG_DIR}/webhook_access.log combined
</VirtualHost>
Run - Nginx + PHP-FPM
Nginx configuration with PHP-FPM.
server {
listen 80;
server_name webhook.example.com;
root /var/www/webhook;
location /webhook.php {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Environment Variables
Store secret in environment file.
Apache - Add to .htaccess:
SetEnv WEBHOOK_SECRET your_secret_here
Nginx - Add to site config:
fastcgi_param WEBHOOK_SECRET your_secret_here;
PHP-FPM - Add to pool config /etc/php/8.1/fpm/pool.d/www.conf:
env[WEBHOOK_SECRET] = your_secret_here
Docker Deployment
Containerize PHP webhook handler.
FROM php:8.1-apache
COPY webhook.php /var/www/html/
RUN chown -R www-data:www-data /var/www/html
EXPOSE 80
Build and run:
docker build -t github-webhook-php .
docker run -p 8000:80 -e WEBHOOK_SECRET=your_secret github-webhook-php
File Permissions
Set proper permissions for deployment script.
# Make deploy script executable
chmod +x /path/to/deploy.sh
# Give PHP user permission (if needed)
sudo chown www-data:www-data /path/to/deploy.sh
# Or add www-data to appropriate group
sudo usermod -aG deployers www-data
Logging
Enhanced logging for debugging.
<?php
function logWebhook($message) {
$log_file = '/var/log/github-webhook.log';
$timestamp = date('Y-m-d H:i:s');
file_put_contents($log_file, "[$timestamp] $message\n", FILE_APPEND);
}
// Log incoming request
logWebhook("Webhook received: " . $_SERVER["HTTP_X_GITHUB_EVENT"]);
// Log verification result
if (!verifySignature()) {
logWebhook("ERROR: Signature verification failed");
} else {
logWebhook("SUCCESS: Signature verified");
}
?>
View logs:
tail -f /var/log/github-webhook.log