Skip to content

Instantly share code, notes, and snippets.

@mathiasverraes
Created July 12, 2012 07:42
Show Gist options
  • Save mathiasverraes/3096500 to your computer and use it in GitHub Desktop.
Save mathiasverraes/3096500 to your computer and use it in GitHub Desktop.
Recursive PHP Lint script
#!/bin/bash
for file in `find .`
do
EXTENSION="${file##*.}"
if [ "$EXTENSION" == "php" ] || [ "$EXTENSION" == "phtml" ]
then
RESULTS=`php -l $file`
if [ "$RESULTS" != "No syntax errors detected in $file" ]
then
echo $RESULTS
fi
fi
done
@jroman00
Copy link

@canadiannomad You can't use exit status with that. I personally altered the code above to be:

#!/bin/bash

error=false

while test $# -gt 0; do
    current=$1
    shift

    if [ ! -d $current ] && [ ! -f $current ] ; then
        echo "Invalid directory or file: $current"
        error=true

        continue
    fi

    for file in `find $current -type f -name "*.php"` ; do
        RESULTS=`php -l $file`

        if [ "$RESULTS" != "No syntax errors detected in $file" ] ; then
            echo $RESULTS
            error=true
        fi
    done
done


if [ "$error" = true ] ; then
    exit 1
else
    exit 0
fi

Usage:
phplint.sh path/to/directory/ path/to/file.php

Benefits:

  • Use "find" to avoid having to loop through every file to check extension.
  • Accept a variable number of directories/files.
  • I can use the exit status in my build process.

NOTE: I don't care about .phtml files but that can be altered.

@sergeyklay
Copy link

#!/usr/bin/env bash

# trace ERR through pipes
set -o pipefail

# trace ERR through 'time command' and other functions
set -o errtrace

# set -u : exit the script if you try to use an uninitialised variable
set -o nounset

# set -e : exit the script if any statement returns a non-true return value
set -o errexit

ST_OK=0
ST_ERR=1
ST_HLP=2

PURPLE="\033[0;35m"
GREEN="\033[0;32m"
YELLOW="\033[1;33m"
NC="\033[0m"

PHP_MAJOR="$(php -v | head -n 1 | awk '{print $2}' | cut -d '.' -f 1,2)"
PHP_FULL_VERSION=`php -r 'echo phpversion();'`

printf "${GREEN}Recursive PHP syntax check${NC} (lint)\n"

print_help() {
    printf "\n${YELLOW}Usage:${NC} $0 [command]\n"
    printf "\n  -H | --help                     ${PURPLE}Show this help message.${NC}"
    printf "\n  -L | --lint                     ${PURPLE}Recursive PHP syntax check (lint).${NC}"
    printf "\n\n"
}

start_lint() {
    if [ $# -lt 2 ]; then
        printf "\n${YELLOW}Using syntax checker:${NC}\n"
        printf "\n        $0 --lint ${PURPLE}\$(pwd)/relative/path/to/the/files${NC}"
        printf "\n        $0 --lint ${PURPLE}/absolute/path/to/the/files${NC}"
        printf "\n\n"

        exit ${ST_HLP}
    fi

    declare PATH_TO_SCAN=$2
    declare ERROR=0

    if [ ! -d ${PATH_TO_SCAN} ] && [ ! -f ${PATH_TO_SCAN} ]; then
        printf "\nInvalid directory or file: ${PATH_TO_SCAN}"
        printf "\n\n"

        exit ${ST_ERR}
    fi

    printf "\nPHP version:  ${YELLOW}${PHP_MAJOR}${NC} (${PHP_FULL_VERSION})"
    printf "\nPath to scan: ${YELLOW}${PATH_TO_SCAN}${NC}"
    printf "\n\n"

    for file in `find ${PATH_TO_SCAN} -type f -name "*.php"`; do
        RESULTS=`php -l ${file}`

        if [ "$RESULTS" != "No syntax errors detected in $file" ]; then
            ERROR=1
        fi
    done

    if [ "${ERROR}" = 1 ] ; then
        exit ${ST_ERR}
    else
        exit ${ST_OK}
    fi

    printf "\n"
}

[[ $# == 0 || $1 == --help ]] && print_help && exit ${ST_HLP}

while test -n "$1"; do
    case $1 in
        --help|-H)
            print_help
            exit ${ST_HLP}
            ;;
        --lint|-L)
            start_lint ${@}
            exit ${ST_OK}
            ;;
        *)
            print_help
            exit ${ST_HLP}
            ;;
    esac
done

@scones
Copy link

scones commented Feb 17, 2017

Maybe this:
find . -type f -name '*.php' -exec php -l {} ; |grep -v "No syntax errors detected"
;)

fixed this to:
find . -type f -name '*.php' -exec php -l {} \; |grep -v "No syntax errors detected"

@fbrinker
Copy link

You may want to invert the return code of grep so a CI build can fail, if grep found some errors:
find . -type f -name '*.php' -exec php -l {} \; | (! grep -v "No syntax errors detected" )

@jakob-stoeck
Copy link

jakob-stoeck commented Apr 25, 2018

you can run it in parallel (using xargs -P) and disable loading of the php config (with -n) for a significant speed bump like this:

find . -type f -name '*.php' -print0 | xargs -0 -n1 -P4 php -l -n | (! grep -v "No syntax errors detected" )

@JacobDB
Copy link

JacobDB commented Sep 27, 2018

@fbrinker and @jakob-stoeck, thanks for that, that's exactly what I was looking for!

@JoSSte
Copy link

JoSSte commented Sep 5, 2019

with vendor folder excluded for ci/cd
find . -path ./app/vendor -prune -o -type f -name '*.php' -print0 | xargs -0 -n1 -P4 php -l -n | (! grep -v "No syntax errors detected" )

@satishgadhave
Copy link

Thanks @JoSSte

@judgej
Copy link

judgej commented Jun 16, 2020

Maybe this:
find . -type f -name '*.php' -exec php -l {} ; |grep -v "No syntax errors detected"
;)

Just redirect stdout to /dev/null then all you will see are the errors. There is then no need to grep stdout.

find . -type f -name '*.php' -exec php -l {} \; >/dev/null

@Maikuolan
Copy link

Something like this would be pretty useful as a GitHub Action, I reckon.

@vertexvaar
Copy link

vertexvaar commented Feb 5, 2021

I combined and added some parts:

  1. @judgej redirect to /dev/null
  2. Add -false after -prune to omit the vendor folder from output
  3. Add $(nproc) to get the actual amount of usable cores

find . -path ./vendor -prune -false -o -type f -name '*.php' -print0 | xargs -0 -n1 -P$(nproc) php -l -n > /dev/null

Edit: Portable version with comment from @CodeBrauer:

find . -path ./vendor -prune -false -o -type f -name '*.php' -print0 | xargs -0 -n1 -P$(nproc 2> /dev/null || sysctl -n hw.ncpu) php -l -n > /dev/null


I ❤️ this discussion! You people are awesome!

@CodeBrauer
Copy link

@vertex

  1. Add $(nproc) to get the actual amount of usable cores

For those using macOS - nproc is not available, but you can use sysctl -n hw.ncpu

@Jimbolino
Copy link

still havent found a good (portable) version for this
redirecting the output of php -l to /dev/null also hides the parse/syntax error messages

#!/bin/sh
set -ex

find . -type f -name '*.php' ! -path './vendor/*' -exec php -l -n {} \; | (! grep -v "No syntax errors detected" )
echo 'syntax OK'

This works fine on ubuntu, but on macOS it stops the script

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment