Snippets

RuWeb.net php_compat_check

Created by Andrey Chesnakov last modified
#!/bin/sh
# Perform script syntax check with specified php binary (and some custom checks) for all users and report errors found
#
# Usage: php_compat_check.sh /usr/ports/lang/php5/work/php-5*/sapi/cli/php 2>&1 | tee php_compat_check.log
#
# Get total number of errors grouped by type:
# egrep '^(Fatal|Parse|Check) error' php_compat_check.errors | awk '{print $1,$2,$3,$4,$5}' | sort | uniq -c

OLD_PHP='/usr/local/bin/php'
SEARCH_ZEND=1

FUNC_PHP54='define_syslog_variables|import_request_variables|session_is_registered|session_register|session_unregister|mysqli_bind_param|mysqli_bind_result|mysqli_client_encoding|mysqli_fetch|mysqli_param_count|mysqli_get_metadata|mysqli_send_long_data'
FUNC_CHECK=$FUNC_PHP54
CUSTOM_CHECKS=SQLITE

CHECK_SQLITE='(^|[^a-z0-9_#])(sqlite_open|SQLiteDatabase)[[:space:]]*\('
CHECK_SQLITE_MSG='Extension "sqlite" is not available in PHP 5.4+'

if [ -e /usr/local/ispmgr/etc/ispmgr.conf ]; then
    ISPMGR=1
else
    ISPMGR=0
fi

NL=$'\n'
PHP=$1
if [ ! -n "$PHP" ]; then
    echo Error: PHP binary not specified
    exit $1
fi

VER=`$PHP -v | grep '^PHP.*built' | awk '{print $2}'`
VER=${VER%.${VER#?*.?*.}}
if [ ! -n "$VER" ]; then
    echo Error: $PHP is not PHP binary?
    exit $1
fi

if [ -n "$OLD_PHP" ]; then
    OLD_VER=`$OLD_PHP -v | grep '^PHP.*built' | awk '{print $2}'`
    OLD_VER=${OLD_VER%.${OLD_VER#?*.?*.}}
    if [ ! -n "$OLD_VER" ]; then
        echo Error: $OLD_PHP is not PHP binary?
        exit $1
    elif [ "$VER" = "$OLD_VER" ]; then
        echo Warning: $OLD_PHP is the same version as $PHP. I will not double-check for old errors.
        OLD_PHP=''
    fi
fi

renice 10 -p $$ 2>/dev/null
umask 007
echo -n > php_compat_check.errors

for USER in `ls -Ap1 /home/ | grep / | tr '/ ' ' /'`; do
#for USER in stats; do
    grep "^$USER:" /etc/passwd >/dev/null || continue
    if [ 0$ISPMGR -eq 0 ]; then
        grep -i "^account=ON" /usr/local/directadmin/data/users/$USER/user.conf >/dev/null || continue
        RESELLER=`grep -i '^creator=' "/usr/local/directadmin/data/users/$USER/user.conf"`
        RESELLER=${RESELLER#*=}
        FILES=`egrep -Irl '<\?(php)?([[:space:]]|$)' /home/$USER/domains/*/*_html/ 2>/dev/null`
        LOG="/home/$USER/.php_${VER}_compat_check.log"
    else
        grep -A1 "<Directory /home/$USER/data>" /usr/local/etc/apache22/httpd.conf | grep -v 'Directory' >/dev/null && continue
        FILES=`egrep -Irl '<\?(php)?([[:space:]]|$)' /home/$USER/data/www/*/ 2>/dev/null`
        LOG="/home/$USER/data/.php_${VER}_compat_check.log"
    fi
    echo "== Checking user $USER ($RESELLER) scripts syntax for compatibility with PHP $VER =="
    FOUND=0
    COUNT=0
    FAILED=0
    SKIPPED=0
    LINES=''
    IFS=$'\n'
    for SCRIPT in $FILES; do
        SKIP=0
        ERRORS=''
        PHP_ERRORS=`$PHP -l "$SCRIPT" 2>&1`
        if [ $? -eq 0 ]; then
            PHP_ERRORS=''
        elif [ -n "$OLD_PHP" ]; then
            $OLD_PHP -l "$SCRIPT" >/dev/null 2>&1
            if [ $? -ne 0 ]; then
                PHP_ERRORS=''
                SKIP=1
            fi
        fi
        unset IFS
        for CHECK in $CUSTOM_CHECKS; do
            eval MSG="\$CHECK_${CHECK}_MSG"
            eval CHECK="\${CHECK_$CHECK}"
            if [ -n "$CHECK" ]; then
                IFS=$'\n'
                for LINE in `egrep -n "$CHECK" "$SCRIPT"`; do
                    LN=${LINE%%:*}
                    ERRORS="$ERRORS${NL}Check error: $MSG in $SCRIPT on line $LN"
                done
            fi
        done
        if [ -n "$FUNC_CHECK" ]; then
                IFS=$'\n'
                for LINE in `egrep -on "(^|[^a-z0-9_#])($FUNC_CHECK)[[:space:]]*\(" "$SCRIPT"`; do
                    LN=${LINE%%:*}
                    FUNC=${LINE#*:}
                    FUNC=${FUNC#[^a-z0-9_]}
                    FUNC=${FUNC%%[^a-z0-9_]*}
                    ERRORS="$ERRORS${NL}Check error: Function $FUNC() is deprecated in $SCRIPT on line $LN"
                done
        fi
        if [ -n "$PHP_ERRORS" -o -n "$ERRORS" ]; then
            if [ $FOUND -eq 0 ]; then
                echo === Checking user $USER scripts syntax for compatibility with PHP $VER === > "$LOG"
#                chown -h "$USER:$USER" "$LOG"
                FOUND=1
            fi
            if [ -n "$PHP_ERRORS" ]; then
                ERRORS="$PHP_ERRORS$ERRORS"
                else
                ERRORS="${NL}Errors parsing $SCRIPT$ERRORS"
            fi
            echo "$ERRORS" >> "$LOG"
            echo "$ERRORS" >> php_compat_check.errors
            FAILED=$((FAILED+1))
        elif [ $SKIP -eq 1 ]; then
            FAILED=$((FAILED+1))
            SKIPPED=$((SKIPPED+1))
        fi
        COUNT=$((COUNT+1))
    done
    if [ "$SEARCH_ZEND" = "1" ]; then
        if [ 0$ISPMGR -eq 0 ]; then
            FILES=`grep -rl '^<?php @Zend;' /home/$USER/domains/*/*_html 2>/dev/null`
        else
            FILES=`grep -rl '^<?php @Zend;' /home/$USER/data/www/*/ 2>/dev/null`
        fi
        IFS=$'\n'
        for SCRIPT in $FILES; do
            if [ $FOUND -eq 0 ]; then
                echo === Checking user $USER scripts syntax for compatibility with PHP $VER === > "$LOG"
#                chown -h "$USER:$USER" "$LOG"
                FOUND=1
            fi
            FAILED=$((FAILED+1))
            ERRORS="${NL}Errors parsing $SCRIPT${NL}Check error: Zend Optimizer available only for PHP 5.2 and lower. in $SCRIPT on line 0"
            echo "$ERRORS" >> "$LOG"
            echo "$ERRORS" >> php_compat_check.errors
            COUNT=$((COUNT+1))
        done
    fi
    if [ $FOUND -eq 0 ]; then
        echo "OK ($COUNT scripts checked, $FAILED failed, $SKIPPED skipped)"
    else
        echo "Errors found! ($COUNT scripts checked, $FAILED failed, $SKIPPED skipped) see $LOG"
        echo -e "\nErrors found! ($COUNT scripts checked, $FAILED failed, $SKIPPED skipped)" >> "$LOG"
    fi
done
#!/bin/sh
# php_compat_notify.sh | tee php_compat_notify.log

DOMAIN=$(hostname)

if [ -e /usr/local/ispmgr/etc/ispmgr.conf ]; then
    ISPMGR=1
    FILES=/home/*/data/.php_*_compat_check.log
    FROM="root@$DOMAIN"
else
    ISPMGR=0
    FILES=/home/*/.php_*_compat_check.log
    FROM="admin@$DOMAIN"
fi

#for FILE in /home/stats/.php_*_compat_check.log; do
for FILE in $FILES; do
    USER=${FILE#/home/}
    USER=${USER%%/*}
    FILE=${FILE##*/}
    VER=${FILE#.php_}
    VER=${VER%%_*}
    if [ 0$ISPMGR -eq 0 ]; then
        grep -i '^account=ON' "/usr/local/directadmin/data/users/$USER/user.conf" >/dev/null || continue
        EMAIL=`grep -i '^email=' "/usr/local/directadmin/data/users/$USER/user.conf"`
        EMAIL=${EMAIL#*=}
        LOG=`cat "/home/$USER/$FILE"`
    else
        grep -A1 "<Directory /home/$USER/data>" /usr/local/etc/apache22/httpd.conf | grep -v 'Directory' >/dev/null && continue
        EMAIL=`grep -i '^Email .' "/usr/local/ispmgr/var/userconf/ispmgr.$USER"`
        if [ $? -eq 0 ]; then
            EMAIL=${EMAIL#* }
        else
            echo "E-mail address for $USER not found!"
            continue
        fi
        LOG=`cat "/home/$USER/data/$FILE"`
    fi
    echo -n "Sending $FILE about $VER for $USER to $EMAIL: "
    echo "To: $EMAIL
From: Webserver Administrator <$FROM>
Subject: PHP syntax errors found
Content-Type: text/plain; charset=utf-8

Внимание!
При проверке ваших PHP-скриптов на совместимость с новой версией PHP ($VER) были обнаружены фатальные ошибки. \
Текст ошибок представлен ниже. Если указанные файлы используются в работе вашего веб-сайта (или его части), \
то скорее всего после обновления PHP ваш сайт (или его часть) перестанет работать.
Чтобы обеспечить работоспособность этих скриптов вам нужно будет их скорректировать (или, если возможно, \
обновить их до версии совместимой с PHP $VER), либо обратиться в службу поддержки и запросить перенос сайта \
на сервер со старой версией PHP.

$LOG
===

(Письмо сгенерировано автоматически. На него не следует отвечать по e-mail. По всем вопросам обращайтесь в службу поддержки.)
" | /usr/sbin/sendmail -t -f "$FROM" && echo OK
done

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.