Fix SCRIPT_DIR variable collision in PHP libraries
CRITICAL BUG FIX: Problem: php-detector.sh and php-analyzer.sh were setting SCRIPT_DIR which collided with parent script's SCRIPT_DIR variable causing /lib/lib/ double path bug when sourcing libraries. Solution: - Changed SCRIPT_DIR to _LIB_DIR in both php-detector.sh and php-analyzer.sh - Changed exit 1 to return 1 in sourced libraries (exit kills parent script) Files modified: - lib/php-detector.sh: Use _LIB_DIR instead of SCRIPT_DIR - lib/php-analyzer.sh: Use _LIB_DIR instead of SCRIPT_DIR, return instead of exit This prevents variable collision when libraries are sourced by modules.
This commit is contained in:
+3
-3
@@ -4,9 +4,9 @@
|
||||
# Dependencies: lib/php-detector.sh, lib/system-detect.sh
|
||||
|
||||
# Source required libraries
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/php-detector.sh" 2>/dev/null || { echo "ERROR: php-detector.sh not found"; exit 1; }
|
||||
source "$SCRIPT_DIR/system-detect.sh" 2>/dev/null || { echo "ERROR: system-detect.sh not found"; exit 1; }
|
||||
_LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$_LIB_DIR/php-detector.sh" 2>/dev/null || { echo "ERROR: php-detector.sh not found"; return 1; }
|
||||
source "$_LIB_DIR/system-detect.sh" 2>/dev/null || { echo "ERROR: system-detect.sh not found"; return 1; }
|
||||
|
||||
# ============================================================================
|
||||
# ERROR LOG ANALYSIS
|
||||
|
||||
@@ -0,0 +1,428 @@
|
||||
#!/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 domain="$1"
|
||||
local username="$2"
|
||||
|
||||
case "$SYS_CONTROL_PANEL" in
|
||||
cpanel)
|
||||
# Check userdata for PHP version
|
||||
local userdata_file="/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
|
||||
if [ -n "$php_version" ]; then
|
||||
pool_config="/opt/cpanel/$php_version/root/etc/php-fpm.d/$username.conf"
|
||||
[ -f "$pool_config" ] && echo "$pool_config" && return 0
|
||||
fi
|
||||
|
||||
# Search all EA-PHP versions
|
||||
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
|
||||
|
||||
# Plesk pools
|
||||
pool_config="/etc/php-fpm.d/plesk-php*-fpm/$domain.conf"
|
||||
[ -f "$pool_config" ] && echo "$pool_config" && return 0
|
||||
|
||||
# InterWorx pools
|
||||
pool_config="/home/$username/var/$domain/php-fpm.conf"
|
||||
[ -f "$pool_config" ] && echo "$pool_config" && return 0
|
||||
|
||||
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() {
|
||||
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() {
|
||||
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
|
||||
Reference in New Issue
Block a user