Présentation
Cette classe permet d'afficher le code qui s'execute sur votre server.
Il y a deux modes de fonctionnement: soit en mode "coupure" (méthode 1) avec utilisation des fonction d'autoload et qui demande au code rendu d'être valable syntaxiquement et un mode "détaché" (methode 2) qui affiche/detecte n'importe quel code mais qui est plus délicat à utiliser et sécuriser...
Cette classe fonctionne de conserve avec la classe Debug que j'ai aussi publié (la classe débug produit un lien qui permet d'afficher le code à l'endroit de l'appel ) c'est pratique.
Par contre mal utilisé cette classe va permettre d'afficher des mots de passe dans le code ou des informations sensibles... a utiliser avec précaution.
Il y a deux modes de fonctionnement: soit en mode "coupure" (méthode 1) avec utilisation des fonction d'autoload et qui demande au code rendu d'être valable syntaxiquement et un mode "détaché" (methode 2) qui affiche/detecte n'importe quel code mais qui est plus délicat à utiliser et sécuriser...
Cette classe fonctionne de conserve avec la classe Debug que j'ai aussi publié (la classe débug produit un lien qui permet d'afficher le code à l'endroit de l'appel ) c'est pratique.
Par contre mal utilisé cette classe va permettre d'afficher des mots de passe dans le code ou des informations sensibles... a utiliser avec précaution.
<?php /** * @package framework * * @author Pierre-Emmanuel Périllon * @license GPL2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * ------------- * the only exception to code modification mandatory diffusion is * about method forcerLegitimite() because this is a security option * (security and secrecy are different but...) but it may not become * something else than a method that forbid/stops the code showing * if requested file contains sensible information... * an static parameters.... but that's data. **/ /** * @see __autoload() * */ require_once('autoload.inc.php'); //YA LE CHOIX // decommenter pour utiliser voir le code à partir du fichier lui meme // par ex http://......./toto/include/classe-superimportante.class.php?parametre_secret // et ceci devrai fonctionner http://......./toto/include/classe-superimportante.class.php?parametre_secret=classe-superimportante.class.php // dans ce cas le ce fichier doit contenir la ligne "\n SourceCode::obtenir(); \n" //require_once 'autoload.inc.php'; // SINON // on decommente la ligne ci dessous et on appelle tous les scripts de cette methode... // SourceCode::obtenir(); // http://......./toto/SourceCode.class.php?parametre_secret=include/classe-superimportante.class.php // note:attention un fichier qui contient l'autoload n'est pas un bootstrap /** * @package framework * */ class SourceCode { /** * ceci devrait être personalisé * * */ // si vous utilisez plusieurs autoloader ... ya qu'à dire qu'on néglige celui des librairies utilisatrices... // enplus j'ai une conception personnelle de l'autoloader // qui retourne le nom du fichier lu et peut ne pas charger la classe via une option (2e position) // donc ici l'autoloader est juste une fonction qui converti un nom de classe en nom de fichier... static $autoloader = 'loadClassAndInterface'; // le machin a rajouter à l'url pour dire qu'on veux afficher le code. // si vous voulez pas qu'on regarde votre code garder ce truc secret et difficile a deviner. static $param = 'parametre_secret'; // les extentions autorisées pour l'affichage en mode 2 // a changer uniquement si vous etes déconecté d'internet. ya une directive sympa dans php.ini // qui permet de lui dire ou c'est en local... static $docUrl = 'http://php.net/manual-lookup.php?pattern='; /** * ceci ne demande moins de personnalisation * */ const patternRequireAndInclude = '#(?:include|require)(?>_once)?\s*\(?[ \t\n]*\'(.*)\'[ \t\n]*\)?#'; const patternClass = '#(?>new\s+([A-Za-z0-9_]+)\s*\()|(?>([A-Za-z0-9_]+)::)|(?>extends\s+([A-Za-z0-9_]+)\s*)|(?>implements\s+([A-Za-z0-9_]+))|(?>catch\s*\(\s*([A-Za-z0-9_]+))#'; const patternFunction ='#(?:(?>(static)|(protected)|(private)|(public)|(abstract)|(final))\s+){0,5}function\s+(&?\w+)\s*\(#i'; const patternException = '#([A-Za-z0-9_]+)exception#i'; static $charset = 'UTF-8'; /** * merci à Brice qui m'a aidé à écrire la premiere version de cette * fonction * @param sourceFileName c'est le nom du fichier * @uses SourceCode::convertirListeSymboleVersLien() * @uses SourceCode::patternRequireAndInclude * @uses SourceCode::patternClass * @uses SourceCode::uri2url() * @static **/ static protected function BriceA($source) { //detection des requires $liste =self::convertirListeSymboleVersLien( $matches[1], '' ); //detection des classes //new //static //extends //interface foreach( $matches[4] as $int ) { } //catch // print_r($matches); $suite = NULL; echo ' <ul style="text-align:left;float:left" title="citation avec fichier trouvé">'; foreach( $liste as $symbole => $filename) { if ($filename === null ) { echo "\n",'<li>Citation: ', $symbole, '</li>'; } { $suite[$symbole] = $filename; } else { echo "\n",'<li><a href="', self::uri2url($filename),'">', $symbole, '</a></li>'; } } echo '</ul>'; if ( $suite !== null ) { echo ' <ul style="text-align:left;float:left" title="citation sans fichier trouvé">'; foreach( $suite as $symbole => $filename) { echo "\n",'<li><a href="', self::uri2url($filename),'">', $symbole, '</a></li>'; } echo '</ul>'; } } /*** * replace un nom de fichier local en ce qu'il devrait être sur le web * pet'te que ça marche pas. * @param filename $file * @return string * */ static protected function uri2url( $file ) { $hide[] = $_SERVER['DOCUMENT_ROOT']; } /** * affiche le code source. * utilise un tableau pour sparer le code et les numros: plus simple. * on ne peut par couper la chaine obtenue par ligne avec par exemple un explode('<br />',$str) * parce que sinon on nique la coloration et avec la non fermeture des spans. * @param string $filename le nom du fichier (pathname afficher) * @return void affiche a tous les coups et continue * @uses SourceCode::afficherNavigation() * @uses SourceCode::BriceA * @uses SourceCode::afficherCss() * @uses SourceCode::afficherCode() * @uses SourceCode::afficherListeFonction() * @uses SourceCode::$charset * @static */ static protected function afficher($filename) { //parce que le serveur on sait jamais... c'est peut-être du IIS malconfiguré (pléonasme) echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=',self::$charset,'" /> <title>Code du script / serveur = ',$_SERVER['SERVER_NAME'],$dir,'/',$file,'</title> <style type="text/css">'; self::afficherCss(); echo ' </style> </head> <body id="top"> <div class="boite"> <h1>',$filename,'</h1> self::afficherNavigation($filename); self::BriceA($fileContent); echo ' <div style="clear:both"></div> </div>'; /* on prépare le code. */ self::afficherCode($_SERVER['DOCUMENT_ROOT'].$filename); echo ' <hr /> <div >licence: GPL 2+, author: Pierre-Emmanuel Périllon.</div>'; self::afficherListeFonction($file); include 'traceursJavascript.inc.php' ; echo ' </body> </html>'; } /** * @param filename $file * @static * */ static protected function afficherCode($file) { echo ' <table> <tr> <th> ? </th> <th> Code </th> </tr> <tr> <td title="Numéro de ligne" ><code>'; /* afficher les numeros dans une cellule*/ for ( $i=1; $i <= $max ; $i++) { echo ' <a id="line',$i,'" href="#line',$i,'">',$i,'</a><br/>'; } echo ' </code></td> <td title="le code php" >', /* le reste dans une autre cellule */ $html,' </td> </tr> </table>'; } /** * @static * */ static protected function afficherCss() { echo ' /*<![CDATA[*/ body{font-size:10pt} a{text-decoration:none} a:hover{font-weight:bolder} .boite{border:black 2px solid;text-align: center} .boite a{text-decoration:underline} code{font-size:10pt} code a{color:gray;text-decoration:none} code a:hover{text-decoration:underline} h1{font-family:monospace} .toolbox{position:fixed;bottom:0;right:0;width:30ex} .toolbox>.resume{text-align:center;border:1px black solid;background:whitesmoke;margin:0;padding:2pt} .liste{margin:0;padding:0;} .liste>li{margin:0;padding:1px;} .toolbox>.liste{list-style-type:none;height:300px;overflow:scroll;background-color:rgba(245,255,250,0.9);display:none;font-size:smaller;border-style:none;} .toolbox:hover>.liste{display:block} .abstract{text-decoration:line-through} .private{color:red} .protected{color:blue} .public{color:green} .final{background-color:yellow} /*]]>*/ '; } /** * @param filename $file * @static * @uses SourceCode::listerFonction() * @uses SourceCode::afficherPrototype() * */ static protected function afficherListeFonction ($filename) { $t = self::listerFonction($filename); echo ' <div class="toolbox">'; if ( $c > 0 ) { echo '<ul class="liste" >'; foreach( $t as $proto) { self::afficherPrototype($proto); } echo '</ul>'; } echo ' <div class="resume" ><a href="#top" title="top">',$c,' méthodes/fonctions</a></div> </div>'; } /** * @param filename $file * @static * @uses SourceCode::listerFichiers() * */ static protected function afficherNavigation($filename) { $t = self::listerFichiers($filename); echo ' <ul style="text-align:left;float:left;width:20em"> <li><a href="',self::faireLien($t[0]),'">fichier précédant</a></li> <li><a href="',self::faireLien($t[1]),'">fichier suivant</a></li>'; /* if ( file_exists('index.php') ) { echo '<li><a href="?',self::$param,'">index</a>.</li>'; } if ( file_exists('../index.php') ) { echo ' <li><a href="..?',self::$param,'">parent</a></li>'; } */ { echo ' <li><a href="',htmlspecialchars($_SERVER['HTTP_REFERER']),'" title="',htmlspecialchars($_SERVER['HTTP_REFERER']),'">referer</a></li>'; } echo ' </ul>'; } /** * @static * @param array $p * */ static protected function afficherPrototype($p) { echo '<a class="',$p['abstract'],' ',$p['visibility'],' ',$p['final'], '" href="#line',$p['line'], '" title="ligne ', $p['line'],': ',$p['abstract'],' ',$p['visibility'],'" >',$p['function'],'()</a></li>'; } /** * liste les fichiers * @param filename $file * @static * @return array * */ static function listerFichiers($filename) { // Debug::var_dump($filename); // Debug::var_dump($tab); if ( $tab === false ) { echo '<tt>Votre hébergement à probablement bloqué glob()... </tt>'; $r[0] = $r[1] = $filename; return $r; } //s'il y a pas au moins un fichier... if (0 == $i ) { } else { $r[0] = $files[$i-1]; } //pas de dépassement $j = $i+1; { $r[1]=$files[0]; } else { $r[1]=$files[$j]; } return $r; } /*** * @param filename $filename * @static * @uses SourceCode::simplierPrototype() * @uses SourceCode::patternFunction * @return array * */ static function listerFonction($filename) { foreach( $f as $n => $line ) { { $x =self::simplierPrototype($matches, $n+1); // on peut avoir deux fonctions du meme nom dans un meme fichier // mais tres difficilitement dans une meme ligne $r[$x['function'].'@'.$x['line']]=$x; } } return $r; } /** * afficher le code source d'une page au cas ou on en a besoin. * @return void affiche et termine ou ne fait rien * @uses SourceCode::afficher() * @static */ static final function obtenir() { { // Debug::here(); { self::afficher($_SERVER['PHP_SELF']); } // if( isset($_GET['getSourceCode'])) else // if ( $_SERVER['PHP_SELF'] === $_SERVER['SCRIPT_NAME']) // ça peut échouer de temps en temps alors que ça devrait pas... { $safeFile = self::forcerLegitimite($_GET[self::$param]); self::afficher($safeFile); } exit; } // else // { // Debug::here(); // echo 'nothing to do'; // } } /** * je serai anglophe j'aurai appelé ça un sanitizer * Je vous déconseille fortement de ne pas personnaliser ce code. * Dans cette configuration, c'est "sécure"... * @param $randomFile une chaine pouvant contenir n'importe quoi mais dont on aimerai s'assurer que c'est bien un nom de fichier. * @return string un nom de fichier. Methode du type "vaincre ou mourir". **/ static protected function forcerLegitimite($randomFile) { // vous devez décommenter vous meme cette partie du code // et n'allez pas dire que ça ouvre une faille de sécurité // si vous exposez ainsi vos mots de passe. /* //interdire de remonter vers la racine... mais que ce passe t'il en cas de caractere non ascii??? if ( strpos($randomFile,'..') !== false ) { header('HTTP/1.0 403 Forbidden'); die( 'parent directory change not allowed' ); return false; //faire plaisir au compilateur } //donner un chemin relatif... encore une syntaxe exotique... $file = $_SERVER['DOCUMENT_ROOT']. $fileRelative = dirname($_SERVER['PHP_SELF']).'/'.$randomFile; if ( !file_exists($file) ) { header('HTTP/1.0 404 Not Found'); die('Not found:'.$file); return false; } //extention connue... foreach( self::$ext as $extention ) { $pos = strrpos($randomFile, $extention); if ( $pos !==false and ( strlen($extention)+$pos === strlen($randomFile) ) ) { return $fileRelative; } } */ } /** * @access private * @param array $m * @param integer $line * @return array * @static * */ static private function simplierPrototype($m, $line) { $tmp= $m[2].$m[3].$m[4]; { $tmp = 'public'; } $r['static'] = ''; $r['abstract'] = ''; $r['final'] = ''; $r['visibility']=$tmp; $r['line'] = $line; return $r; } /** * @access protected * @static * @uses SourceCode::$dir * @uses SourceCode::$ext * @uses SourceCode::patternException * @uses SourceCode::$param * @uses SourceCode::chercherDocumentation() * */ static protected function convertirSymboleVersLien($objet, $type) { { return self::faireLien($objet); } // ouaip dans ce sens là. else if ( function_exists(self::$autoloader) and ($theFile = call_user_func(self::$autoloader, $objet, false) ) !== False ) { return self::faireLien($theFile); } else { { //si c'est une exception, on s'en contrefiche. return null; } else { return self::chercherDocumentation($objet); } } } static function faireLien($theFile) { { } else { } } /*** * trouve l'url associée à une classe ou interface... * @access protected * @static * @param string $type * @param array $array * @return array * @uses SourceCode::convertirSymboleVersLien() * */ static protected function convertirListeSymboleVersLien($array,$type) { // $array = array_unique($array); foreach( $array as $objet ) { { continue; } $l[$type.' '.$objet]= self::convertirSymboleVersLien($objet, $type); //traiter les } return $l; } /*** * @static * @uses SourceCode::$docUrl * * */ static protected function chercherDocumentation($symbole) { } }//class /* la fin */
Developpez.com décline toute responsabilité quant à l'utilisation des différents éléments téléchargés.




La discussion sur le forum
Poster une réponse