dea6f27b4d
- lib/domain-discovery.sh: Added -- to grep command (1 fix) - lib/reference-db.sh: Added -- to grep command (1 fix) - lib/user-manager.sh: Added -- to grep command (1 fix) - lib/email-functions.sh: Added -- to awk and grep commands (2 fixes) - lib/php-config-manager.sh: Added -- to grep commands (3 fixes) - lib/php-detector.sh: Added -- to grep command (1 fix) Total: 9 ESCAPE fixes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
447 lines
16 KiB
Bash
447 lines
16 KiB
Bash
#!/bin/bash
|
|
|
|
################################################################################
|
|
# PHP Detector Library
|
|
# Part of Server Toolkit - PHP & Server Optimizer
|
|
#
|
|
# Purpose: Detect all PHP configurations, pools, versions, and settings
|
|
# Author: Server Toolkit Team
|
|
# Dependencies: system-detect.sh, user-manager.sh
|
|
################################################################################
|
|
|
|
# Source dependencies (if not already loaded)
|
|
if [ -z "$SYS_CONTROL_PANEL" ]; then
|
|
_LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
source "$_LIB_DIR/lib/system-detect.sh" 2>/dev/null
|
|
source "$_LIB_DIR/lib/user-manager.sh" 2>/dev/null
|
|
fi
|
|
|
|
################################################################################
|
|
# PHP Version Detection
|
|
################################################################################
|
|
|
|
# Detect all installed PHP versions on the system
|
|
detect_installed_php_versions() {
|
|
local -a php_versions=()
|
|
|
|
# cPanel EA-PHP
|
|
if [ -d "/opt/cpanel" ]; then
|
|
while IFS= read -r dir; do
|
|
local version=$(basename "$dir" | sed 's/ea-php//')
|
|
php_versions+=("ea-php$version")
|
|
done < <(find /opt/cpanel -maxdepth 1 -type d -name "ea-php*" 2>/dev/null | sort)
|
|
fi
|
|
|
|
# CloudLinux Alt-PHP
|
|
if [ -d "/opt/alt" ]; then
|
|
while IFS= read -r dir; do
|
|
local version=$(basename "$dir" | sed 's/php//')
|
|
php_versions+=("alt-php$version")
|
|
done < <(find /opt/alt -maxdepth 1 -type d -name "php*" 2>/dev/null | grep -E "php[0-9]" | sort)
|
|
fi
|
|
|
|
# Plesk PHP
|
|
if [ -d "/opt/plesk/php" ]; then
|
|
while IFS= read -r dir; do
|
|
local version=$(basename "$dir")
|
|
php_versions+=("plesk-php$version")
|
|
done < <(find /opt/plesk/php -maxdepth 1 -type d -name "[0-9]*" 2>/dev/null | sort)
|
|
fi
|
|
|
|
# System PHP
|
|
if command -v php &>/dev/null; then
|
|
local sys_version=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;' 2>/dev/null)
|
|
[ -n "$sys_version" ] && php_versions+=("system-php$sys_version")
|
|
fi
|
|
|
|
# Return array
|
|
printf '%s\n' "${php_versions[@]}"
|
|
}
|
|
|
|
# Get PHP version for a specific domain/user
|
|
detect_php_version_for_domain() {
|
|
local username="$1"
|
|
local domain="$2"
|
|
|
|
case "$SYS_CONTROL_PANEL" in
|
|
cpanel)
|
|
# Check userdata for PHP version
|
|
local userdata_file="${SYS_CPANEL_USERDATA_DIR:-/var/cpanel/userdata}/$username/$domain"
|
|
if [ -f "$userdata_file" ]; then
|
|
local php_ver=$(grep "phpversion:" -- "$userdata_file" | awk '{print $2}' | tr -d "'\"")
|
|
echo "$php_ver"
|
|
return 0
|
|
fi
|
|
|
|
# Fallback: Check FPM pool config
|
|
local pool_config=$(find /opt/cpanel/ea-php*/root/etc/php-fpm.d/ -name "$username.conf" 2>/dev/null | head -1)
|
|
if [ -n "$pool_config" ]; then
|
|
local php_path=$(dirname "$(dirname "$(dirname "$pool_config")")")
|
|
basename "$php_path"
|
|
return 0
|
|
fi
|
|
;;
|
|
|
|
plesk)
|
|
# Query Plesk database
|
|
if command -v plesk &>/dev/null; then
|
|
plesk bin site -i "$domain" 2>/dev/null | grep "PHP version" | awk '{print $NF}'
|
|
return 0
|
|
fi
|
|
;;
|
|
|
|
interworx)
|
|
# Check SiteWorx config
|
|
local domain_conf="/home/$username/var/$domain/siteworx.conf"
|
|
if [ -f "$domain_conf" ]; then
|
|
grep "php_version" "$domain_conf" | cut -d'=' -f2
|
|
return 0
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
# Fallback: Try to execute PHP as user
|
|
su -s /bin/bash "$username" -c "php -r 'echo PHP_MAJOR_VERSION.\".\".PHP_MINOR_VERSION;'" 2>/dev/null
|
|
}
|
|
|
|
################################################################################
|
|
# PHP Configuration File Detection
|
|
################################################################################
|
|
|
|
# Find ALL php.ini files affecting a domain (in priority order)
|
|
find_all_php_configs() {
|
|
local username="$1"
|
|
local domain="$2"
|
|
local php_version="${3:-}" # Optional: e.g., "82" or "8.2" or "ea-php82"
|
|
|
|
declare -a config_files=()
|
|
|
|
# Normalize PHP version format
|
|
local php_ver_short=$(echo "$php_version" | grep -oE '[0-9]+' | head -c2)
|
|
local php_ver_dot="${php_ver_short:0:1}.${php_ver_short:1}"
|
|
|
|
# PRIORITY 1: Per-Directory .user.ini files
|
|
if [ -d "/home/$username" ]; then
|
|
while IFS= read -r file; do
|
|
config_files+=("P1|$file|.user.ini")
|
|
done < <(find "/home/$username" -name ".user.ini" -type f 2>/dev/null)
|
|
fi
|
|
|
|
# Check Plesk domain root
|
|
if [ -d "/var/www/vhosts/$domain" ]; then
|
|
while IFS= read -r file; do
|
|
config_files+=("P1|$file|.user.ini")
|
|
done < <(find "/var/www/vhosts/$domain" -name ".user.ini" -type f 2>/dev/null)
|
|
fi
|
|
|
|
# PRIORITY 2: User-Specific php.ini files
|
|
local user_configs=(
|
|
"/home/$username/public_html/php.ini"
|
|
"/home/$username/php.ini"
|
|
"/home/$username/.php/$php_ver_dot/php.ini"
|
|
"/home/$username/.php/$php_ver_short/php.ini"
|
|
"/home/$username/etc/php.ini"
|
|
"/home/$username/etc/php$php_ver_short/php.ini"
|
|
"/home/$username/var/$domain/etc/php.ini" # InterWorx
|
|
"/var/www/vhosts/system/$domain/etc/php.ini" # Plesk
|
|
)
|
|
|
|
for config in "${user_configs[@]}"; do
|
|
[ -f "$config" ] && config_files+=("P2|$config|user php.ini")
|
|
done
|
|
|
|
# PRIORITY 3: Pool/Version-Specific php.ini
|
|
if [ -n "$php_ver_short" ]; then
|
|
# cPanel EA-PHP
|
|
local cpanel_ini="/opt/cpanel/ea-php${php_ver_short}/root/etc/php.ini"
|
|
[ -f "$cpanel_ini" ] && config_files+=("P3|$cpanel_ini|pool php.ini")
|
|
|
|
# cPanel EA-PHP additional .ini files
|
|
if [ -d "/opt/cpanel/ea-php${php_ver_short}/root/etc/php.d" ]; then
|
|
while IFS= read -r file; do
|
|
config_files+=("P3|$file|pool php.d")
|
|
done < <(find "/opt/cpanel/ea-php${php_ver_short}/root/etc/php.d" -name "*.ini" -type f 2>/dev/null | sort)
|
|
fi
|
|
|
|
# CloudLinux Alt-PHP
|
|
local alt_ini="/opt/alt/php${php_ver_short}/etc/php.ini"
|
|
[ -f "$alt_ini" ] && config_files+=("P3|$alt_ini|alt-php ini")
|
|
|
|
# Plesk PHP
|
|
local plesk_ini="/opt/plesk/php/$php_ver_dot/etc/php.ini"
|
|
[ -f "$plesk_ini" ] && config_files+=("P3|$plesk_ini|plesk php.ini")
|
|
fi
|
|
|
|
# PRIORITY 4: System-Wide
|
|
[ -f "/etc/php.ini" ] && config_files+=("P4|/etc/php.ini|system php.ini")
|
|
|
|
# Return the array (priority|path|description)
|
|
printf '%s\n' "${config_files[@]}"
|
|
}
|
|
|
|
# Get effective value of a PHP setting for a specific user
|
|
get_effective_php_setting() {
|
|
local username="$1"
|
|
local setting="$2"
|
|
|
|
# Query PHP directly as the user (most accurate!)
|
|
su -s /bin/bash "$username" -c "php -r 'echo ini_get(\"$setting\");'" 2>/dev/null
|
|
}
|
|
|
|
# Get all effective PHP settings for a user
|
|
get_all_php_settings() {
|
|
local username="$1"
|
|
|
|
# Get all settings in parseable format
|
|
su -s /bin/bash "$username" -c "php -r 'foreach(ini_get_all() as \$k=>\$v) { echo \$k.\"=\".\$v[\"local_value\"].\"\\n\"; }'" 2>/dev/null
|
|
}
|
|
|
|
################################################################################
|
|
# PHP-FPM Pool Detection
|
|
################################################################################
|
|
|
|
# Find PHP-FPM pool configuration for a user/domain
|
|
find_fpm_pool_config() {
|
|
local username="$1"
|
|
local domain="$2"
|
|
local php_version="${3:-}"
|
|
|
|
local pool_config=""
|
|
|
|
# cPanel EA-PHP pools - search username FIRST (this is how cPanel works!)
|
|
if [ -n "$php_version" ]; then
|
|
# Try username-based config (most common)
|
|
pool_config="/opt/cpanel/$php_version/root/etc/php-fpm.d/$username.conf"
|
|
[ -f "$pool_config" ] && echo "$pool_config" && return 0
|
|
|
|
# Try domain-based config (rare, but possible)
|
|
if [ -n "$domain" ]; then
|
|
pool_config="/opt/cpanel/$php_version/root/etc/php-fpm.d/$domain.conf"
|
|
[ -f "$pool_config" ] && echo "$pool_config" && return 0
|
|
fi
|
|
fi
|
|
|
|
# Search all EA-PHP versions - try username FIRST, then domain
|
|
pool_config=$(find /opt/cpanel/ea-php*/root/etc/php-fpm.d/ -name "$username.conf" 2>/dev/null | head -1)
|
|
[ -n "$pool_config" ] && echo "$pool_config" && return 0
|
|
|
|
if [ -n "$domain" ]; then
|
|
pool_config=$(find /opt/cpanel/ea-php*/root/etc/php-fpm.d/ -name "$domain.conf" 2>/dev/null | head -1)
|
|
[ -n "$pool_config" ] && echo "$pool_config" && return 0
|
|
fi
|
|
|
|
# Plesk pools
|
|
if [ -n "$domain" ]; then
|
|
pool_config="/etc/php-fpm.d/plesk-php*-fpm/$domain.conf"
|
|
[ -f "$pool_config" ] && echo "$pool_config" && return 0
|
|
fi
|
|
|
|
# InterWorx pools
|
|
if [ -n "$domain" ]; then
|
|
pool_config="/home/$username/var/$domain/php-fpm.conf"
|
|
[ -f "$pool_config" ] && echo "$pool_config" && return 0
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
# Parse PHP-FPM pool config and extract all settings
|
|
parse_fpm_pool_config() {
|
|
local pool_config="$1"
|
|
|
|
[ ! -f "$pool_config" ] && return 1
|
|
|
|
# Extract key settings
|
|
local pm=$(grep "^pm\s*=" "$pool_config" | awk -F'=' '{print $2}' | tr -d ' ')
|
|
local max_children=$(grep "^pm.max_children" "$pool_config" | awk -F'=' '{print $2}' | tr -d ' ')
|
|
local start_servers=$(grep "^pm.start_servers" "$pool_config" | awk -F'=' '{print $2}' | tr -d ' ')
|
|
local min_spare=$(grep "^pm.min_spare_servers" "$pool_config" | awk -F'=' '{print $2}' | tr -d ' ')
|
|
local max_spare=$(grep "^pm.max_spare_servers" "$pool_config" | awk -F'=' '{print $2}' | tr -d ' ')
|
|
local max_requests=$(grep "^pm.max_requests" "$pool_config" | awk -F'=' '{print $2}' | tr -d ' ')
|
|
local idle_timeout=$(grep "^pm.process_idle_timeout" "$pool_config" | awk -F'=' '{print $2}' | tr -d ' ')
|
|
local request_terminate=$(grep "^request_terminate_timeout" "$pool_config" | awk -F'=' '{print $2}' | tr -d ' ')
|
|
local slowlog_timeout=$(grep "^request_slowlog_timeout" "$pool_config" | awk -F'=' '{print $2}' | tr -d ' ')
|
|
|
|
# Output in key=value format
|
|
echo "pm=$pm"
|
|
echo "pm.max_children=$max_children"
|
|
echo "pm.start_servers=$start_servers"
|
|
echo "pm.min_spare_servers=$min_spare"
|
|
echo "pm.max_spare_servers=$max_spare"
|
|
echo "pm.max_requests=$max_requests"
|
|
echo "pm.process_idle_timeout=$idle_timeout"
|
|
echo "request_terminate_timeout=$request_terminate"
|
|
echo "request_slowlog_timeout=$slowlog_timeout"
|
|
}
|
|
|
|
# Get current FPM process count for a pool
|
|
get_fpm_process_count() {
|
|
[ -z "$1" ] && return 1
|
|
local pool_name="$1" # Usually username or domain
|
|
|
|
ps aux | grep -E "php-fpm.*pool\s+${pool_name}" | grep -v grep | wc -l
|
|
}
|
|
|
|
# Get memory usage per FPM process for a pool
|
|
get_fpm_memory_usage() {
|
|
[ -z "$1" ] && return 1
|
|
local pool_name="$1"
|
|
|
|
# Get average memory per process (in KB)
|
|
ps aux | grep -E "php-fpm.*pool\s+${pool_name}" | grep -v grep | awk '{sum+=$6; count++} END {if(count>0) print int(sum/count); else print 0}'
|
|
}
|
|
|
|
################################################################################
|
|
# PHP Log File Detection
|
|
################################################################################
|
|
|
|
# Find PHP error logs for a user/domain
|
|
find_php_error_logs() {
|
|
local username="$1"
|
|
local domain="$2"
|
|
|
|
declare -a log_files=()
|
|
|
|
# Common error log locations
|
|
local possible_logs=(
|
|
"/home/$username/logs/error_log"
|
|
"/home/$username/public_html/error_log"
|
|
"/home/$username/logs/$domain.error_log"
|
|
"/var/www/vhosts/$domain/logs/error_log"
|
|
"/home/$username/var/$domain/logs/error_log"
|
|
)
|
|
|
|
for log in "${possible_logs[@]}"; do
|
|
[ -f "$log" ] && log_files+=("$log")
|
|
done
|
|
|
|
printf '%s\n' "${log_files[@]}"
|
|
}
|
|
|
|
# Find PHP-FPM error logs
|
|
find_fpm_error_logs() {
|
|
local username="$1"
|
|
local php_version="${2:-}"
|
|
|
|
declare -a log_files=()
|
|
|
|
if [ -n "$php_version" ]; then
|
|
# Specific version
|
|
log_files+=("/opt/cpanel/$php_version/root/usr/var/log/php-fpm/$username-error.log")
|
|
else
|
|
# All versions
|
|
while IFS= read -r log; do
|
|
log_files+=("$log")
|
|
done < <(find /opt/cpanel/ea-php*/root/usr/var/log/php-fpm/ -name "$username-error.log" 2>/dev/null)
|
|
fi
|
|
|
|
printf '%s\n' "${log_files[@]}"
|
|
}
|
|
|
|
# Find PHP-FPM slow logs
|
|
find_fpm_slow_logs() {
|
|
local username="$1"
|
|
local php_version="${2:-}"
|
|
|
|
declare -a log_files=()
|
|
|
|
if [ -n "$php_version" ]; then
|
|
log_files+=("/opt/cpanel/$php_version/root/usr/var/log/php-fpm/$username-slow.log")
|
|
else
|
|
while IFS= read -r log; do
|
|
log_files+=("$log")
|
|
done < <(find /opt/cpanel/ea-php*/root/usr/var/log/php-fpm/ -name "$username-slow.log" 2>/dev/null)
|
|
fi
|
|
|
|
printf '%s\n' "${log_files[@]}"
|
|
}
|
|
|
|
################################################################################
|
|
# OPcache Detection
|
|
################################################################################
|
|
|
|
# Check if OPcache is enabled for a user
|
|
check_opcache_enabled() {
|
|
local username="$1"
|
|
|
|
su -s /bin/bash "$username" -c "php -r 'echo (function_exists(\"opcache_get_status\") && opcache_get_status() !== false) ? \"1\" : \"0\";'" 2>/dev/null
|
|
}
|
|
|
|
# Get OPcache statistics for a user
|
|
get_opcache_stats() {
|
|
local username="$1"
|
|
|
|
su -s /bin/bash "$username" -c "php -r 'if(function_exists(\"opcache_get_status\")) { \$s=opcache_get_status(); echo \"enabled=\".(\$s!==false?1:0).\"\\n\"; if(\$s) { echo \"memory_used=\".\$s[\"memory_usage\"][\"used_memory\"].\"\\n\"; echo \"memory_free=\".\$s[\"memory_usage\"][\"free_memory\"].\"\\n\"; echo \"memory_wasted=\".\$s[\"memory_usage\"][\"wasted_memory\"].\"\\n\"; echo \"num_cached_scripts=\".\$s[\"opcache_statistics\"][\"num_cached_scripts\"].\"\\n\"; echo \"max_cached_scripts=\".\$s[\"opcache_statistics\"][\"max_cached_scripts\"].\"\\n\"; echo \"hits=\".\$s[\"opcache_statistics\"][\"hits\"].\"\\n\"; echo \"misses=\".\$s[\"opcache_statistics\"][\"misses\"].\"\\n\"; } }'" 2>/dev/null
|
|
}
|
|
|
|
# Calculate OPcache hit rate
|
|
calculate_opcache_hit_rate() {
|
|
local username="$1"
|
|
|
|
local stats=$(get_opcache_stats "$username")
|
|
[ -z "$stats" ] && echo "0" && return 1
|
|
|
|
local hits=$(echo "$stats" | grep "^hits=" | cut -d'=' -f2)
|
|
local misses=$(echo "$stats" | grep "^misses=" | cut -d'=' -f2)
|
|
|
|
[ -z "$hits" ] || [ -z "$misses" ] && echo "0" && return 1
|
|
[ "$hits" -eq 0 ] && [ "$misses" -eq 0 ] && echo "0" && return 1
|
|
|
|
local total=$((hits + misses))
|
|
local hit_rate=$((hits * 100 / total))
|
|
|
|
echo "$hit_rate"
|
|
}
|
|
|
|
################################################################################
|
|
# Helper Functions
|
|
################################################################################
|
|
|
|
# Check if PHP-FPM is in use (vs mod_php)
|
|
is_using_php_fpm() {
|
|
# Check if any PHP-FPM processes are running
|
|
pgrep php-fpm &>/dev/null && return 0
|
|
return 1
|
|
}
|
|
|
|
# Get PHP binary path for a specific version
|
|
get_php_binary_path() {
|
|
local php_version="$1"
|
|
|
|
case "$php_version" in
|
|
ea-php*)
|
|
echo "/opt/cpanel/$php_version/root/usr/bin/php"
|
|
;;
|
|
alt-php*)
|
|
local ver=$(echo "$php_version" | sed 's/alt-php//')
|
|
echo "/opt/alt/php$ver/usr/bin/php"
|
|
;;
|
|
plesk-php*)
|
|
local ver=$(echo "$php_version" | sed 's/plesk-php//')
|
|
echo "/opt/plesk/php/$ver/bin/php"
|
|
;;
|
|
*)
|
|
which php
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Export all functions
|
|
export -f detect_installed_php_versions
|
|
export -f detect_php_version_for_domain
|
|
export -f find_all_php_configs
|
|
export -f get_effective_php_setting
|
|
export -f get_all_php_settings
|
|
export -f find_fpm_pool_config
|
|
export -f parse_fpm_pool_config
|
|
export -f get_fpm_process_count
|
|
export -f get_fpm_memory_usage
|
|
export -f find_php_error_logs
|
|
export -f find_fpm_error_logs
|
|
export -f find_fpm_slow_logs
|
|
export -f check_opcache_enabled
|
|
export -f get_opcache_stats
|
|
export -f calculate_opcache_hit_rate
|
|
export -f is_using_php_fpm
|
|
export -f get_php_binary_path
|