PHP Skripte syntaktisch im Deployment überprüfen (Jenkins)

Wenn man im Deployment mit Jenkins sicherstellen möchte, dass PHP Skripte syntaktisch korrekt ausgeliefert werden, kann man die PHP eingebaut Parse Funktion nutzen. Wenn man nach PHP Lint im Internet sucht, findet man eine große menge an Open Source Produkten wie PHP Depend, PHP Codesniffer und viele mehr. Für mich ist das alles recht überladen und benötigt einfach zu viel Setup um mal schnell sicherzustellen, dass keine Tippfehler im Deployment ausgeliefert werden.

Für die minimal Anforderung habe ich einen kleines Wrapper-Skript gebaut, was ich gerne für alle Projekte nutze um grobe Schnitzer einfach auszuschalten:

<?php
 
/*
    this script does a php lint on a certain website with jenkins
    call this skript from ssh commandline and if all php scripts are 
    valid, it returns null. If not the script returns the error 
    information to the commandline of jenkins 
    
    via commandline do it like this:
    c:\xampp\php\php.exe c:\xampp\htdocs\phplint\phplint.php c:\xampp\htdocs\agile-coding\  
    
    don´t forget the slash (backslash) at the end of the directory you want to parse!
    
*/
 
/* configuration options */
$filesuffix = '.PHP';
 
/* point to the php executables */
$prog = "c:\\xampp\\php\\php.exe -l ";
 
/* setting the time limit to zero, cause this can run a long time */
set_time_limit(0);
 
/* if the script is started via commandline, we peal the parameters */
if(isset($argv)){
 
    /* if there is a directory as argument */
    if(isset($argv[1])){
        
        /* we push it into the dir */
        $dir = $argv[1];
        
    }else{
    
        /* otherwise we exit and tell we need the argument */
        exit('the script need the directory argument');
    }
}
 
/* setting up some array´s we need */
$files = array();
$failures = array();
 
/* get all the files into the $files array */
get_directory_listing($dir);
 
/* going thru each file of the directory */
foreach($files as $file){
 
    /* checking if there is a php file in the directory */
    if(strpos(strtoupper($file),$filesuffix) == true){
        
        /* building the execution string */
        $exec = $prog.$file;
        
        /* executing the string and supressing errors */
        $handle = @popen ($exec, "r");
        
        /* checking if there is a handle */
        if($handle != false){
            
            /* creating a clear buffer to read the respond of the executed process */
            $buffer = "";
            
            /* reading the buffer till it is empty */
            while (($buffer = fread($handle, 2096)) != false) {
                
                /* supressing success, if there is no error, there should be nothing to tell */
                $result = strpos($buffer,'syntax errors detected in');
 
                /* if an errors occures */
                if($result < 3){
                    /* push the infos into the $failures array */
                    array_push($failures, $buffer);
                }
            }
        }    
    }
}
 
/* checking the result and setting the returncode for jenkins */
if(count($failures) == 0){
    /* no errors found */
    exit(0);
}else{
    /* errors found and convert everything from array to string */ 
    $info = "";
    
    /* going thru each failure */
    foreach($failures as $failure){
        /* convert it to string */
        $info = $info.$failure;
    }
    
    /* return to command line and exit */
    exit($info);
}
 
function get_directory_listing($dir){
 
    $handle =  opendir($dir);
    GLOBAL $files;
 
    while ($file = readdir($handle)){ 
        if ($file != "." && $file != ".."){ 
 
            if (is_dir($dir.$file)){ 
                get_directory_listing($dir.$file.'/'); 
            }else{ 
                array_push($files, $dir.$file);
            } 
        }
    }
closedir($handle);
} 
?>

Innerhalb vom Jenkins kann man das Skript einfach über die Commandline starten. Einfach als erstes Aufrufarqument das Root Verzeichnis der Webanwendung übergeben, welches man prüfen möchte, und das Skript untersucht alle PHP automatisch.

Wenn ein Fehler auftritt, gibt das Skript die Fehlerinformation von der PHP Schicht an den Jenkins zurück und bricht das Deployment ab.

http://www.agile-coding.net/php-skripte-syntaktisch-im-deployment-ueberpruefen-jenkins/