Télécharger ang class SourceCode

Avatar de gene69
Membre Expert
Mise à jour le : 20/08/2011  ·   Licence : Autre  ·   Téléchargé 13 fois   ·   17 Ko  +
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.

Téléchargement :






		
  1. <?php
  2. /**
  3.  * @package framework
  4.  *
  5.  * @author Pierre-Emmanuel Périllon
  6.  * @license GPL2
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  21.  * MA 02110-1301, USA.
  22.  * -------------
  23.  * the only exception to code modification mandatory diffusion is
  24.  * about method forcerLegitimite() because this is a security option
  25.  * (security and secrecy are different but...) but it may not become
  26.  * something else than a method that forbid/stops the code showing
  27.  * if requested file contains sensible information...
  28.  * an static parameters.... but that's data.
  29.  **/
  30. /**
  31.  * @see __autoload()
  32.  * */
  33. require_once('autoload.inc.php');
  34. //YA LE CHOIX
  35. // decommenter pour utiliser voir le code à partir du fichier lui meme
  36. // par ex http://......./toto/include/classe-superimportante.class.php?parametre_secret
  37. // et ceci devrai fonctionner http://......./toto/include/classe-superimportante.class.php?parametre_secret=classe-superimportante.class.php
  38. // dans ce cas le ce fichier doit contenir la ligne "\n SourceCode::obtenir(); \n"
  39. //require_once 'autoload.inc.php';
  40.  
  41. // SINON
  42. // on decommente la ligne ci dessous et on appelle tous les scripts de cette methode...
  43. // SourceCode::obtenir();
  44. // http://......./toto/SourceCode.class.php?parametre_secret=include/classe-superimportante.class.php
  45. // note:attention un fichier qui contient l'autoload n'est pas un bootstrap
  46.  
  47. /**
  48.  * @package framework
  49.  * */
  50. class SourceCode
  51. {
  52. /**
  53.  * ceci devrait être personalisé
  54.  *
  55.  * */
  56. // si vous utilisez plusieurs autoloader ... ya qu'à dire qu'on néglige celui des librairies utilisatrices...
  57. // enplus j'ai une conception personnelle de l'autoloader
  58. // qui retourne le nom du fichier lu et peut ne pas charger la classe via une option (2e position)
  59. // donc ici l'autoloader est juste une fonction qui converti un nom de classe en nom de fichier...
  60. static $autoloader = 'loadClassAndInterface';
  61. // le machin a rajouter à l'url pour dire qu'on veux afficher le code.
  62. // si vous voulez pas qu'on regarde votre code garder ce truc secret et difficile a deviner.
  63. static $param = 'parametre_secret';
  64. // les extentions autorisées pour l'affichage en mode 2
  65. static $ext = array('php', '.inc.php', '.class.php','.int.php') ;
  66. // a changer uniquement si vous etes déconecté d'internet. ya une directive sympa dans php.ini
  67. // qui permet de lui dire ou c'est en local...
  68. static $docUrl = 'http://php.net/manual-lookup.php?pattern=';
  69.  
  70. /**
  71.  * ceci ne demande moins de personnalisation
  72.  * */
  73. const patternRequireAndInclude = '#(?:include|require)(?>_once)?\s*\(?[ \t\n]*\'(.*)\'[ \t\n]*\)?#';
  74. 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_]+))#';
  75. const patternFunction ='#(?:(?>(static)|(protected)|(private)|(public)|(abstract)|(final))\s+){0,5}function\s+(&?\w+)\s*\(#i';
  76. const patternException = '#([A-Za-z0-9_]+)exception#i';
  77. static $ignore = array('self', 'parent', 'static');
  78. static $charset = 'UTF-8';
  79.  
  80. /**
  81. * merci à Brice qui m'a aidé à écrire la premiere version de cette
  82. * fonction
  83. * @param sourceFileName c'est le nom du fichier
  84. * @uses SourceCode::convertirListeSymboleVersLien()
  85. * @uses SourceCode::patternRequireAndInclude
  86. * @uses SourceCode::patternClass
  87. * @uses SourceCode::uri2url()
  88. * @static
  89. **/
  90. static protected function BriceA($source)
  91. {
  92. //detection des requires
  93. preg_match_all (self::patternRequireAndInclude, $source, $matches);
  94. $liste =self::convertirListeSymboleVersLien( $matches[1], '' );
  95.  
  96. //detection des classes
  97. preg_match_all (self::patternClass,$source,$matches);
  98. //new
  99. $liste = array_merge( $liste , self::convertirListeSymboleVersLien($matches[1], 'class') );
  100. //static
  101. $liste = array_merge( $liste , self::convertirListeSymboleVersLien($matches[2], 'class') );
  102. //extends
  103. $liste = array_merge( $liste , self::convertirListeSymboleVersLien($matches[3], 'class') );
  104. //interface
  105. $interface = array();
  106. foreach( $matches[4] as $int )
  107. {
  108. $tmp = explode(',',str_replace( array("\n\t\0 "), '', trim($int)));
  109. $interface = array_merge($interface, $tmp );
  110. }
  111. $liste = array_merge( $liste , self::convertirListeSymboleVersLien( $interface, 'interface' ) );
  112. //catch
  113. $liste = array_merge( $liste , self::convertirListeSymboleVersLien($matches[5], 'class') );
  114. // print_r($matches);
  115.  
  116. $liste = array_unique($liste );
  117.  
  118. $suite = NULL;
  119.  
  120. echo '
  121. <ul style="text-align:left;float:left" title="citation avec fichier trouvé">';
  122. foreach( $liste as $symbole => $filename)
  123. {
  124. if ($filename === null )
  125. {
  126. echo "\n",'<li>Citation: ', $symbole, '</li>';
  127. }
  128. else if ( strpos($filename,'http://') === 0 )
  129. {
  130. $suite[$symbole] = $filename;
  131. }
  132. else
  133. {
  134. echo "\n",'<li><a href="', self::uri2url($filename),'">', $symbole, '</a></li>';
  135. }
  136. }
  137. echo '</ul>';
  138. if ( $suite !== null )
  139. {
  140. echo '
  141. <ul style="text-align:left;float:left" title="citation sans fichier trouvé">';
  142. foreach( $suite as $symbole => $filename)
  143. {
  144. echo "\n",'<li><a href="', self::uri2url($filename),'">', $symbole, '</a></li>';
  145. }
  146. echo '</ul>';
  147. }
  148. }
  149.  
  150.  
  151.  
  152. /***
  153. * replace un nom de fichier local en ce qu'il devrait être sur le web
  154. * pet'te que ça marche pas.
  155. * @param filename $file
  156. * @return string
  157. * */
  158. static protected function uri2url( $file )
  159. {
  160. $hide[] = $_SERVER['DOCUMENT_ROOT'];
  161. return str_replace($hide,/*'http://'.$_SERVER['SERVER_NAME']*/ '', $file);
  162. }
  163.  
  164.  
  165.  
  166. /**
  167. * affiche le code source.
  168. * utilise un tableau pour sparer le code et les numros: plus simple.
  169. * on ne peut par couper la chaine obtenue par ligne avec par exemple un explode('<br />',$str)
  170. * parce que sinon on nique la coloration et avec la non fermeture des spans.
  171. * @param string $filename le nom du fichier (pathname afficher)
  172. * @return void affiche a tous les coups et continue
  173. * @uses SourceCode::afficherNavigation()
  174. * @uses SourceCode::BriceA
  175. * @uses SourceCode::afficherCss()
  176. * @uses SourceCode::afficherCode()
  177. * @uses SourceCode::afficherListeFonction()
  178. * @uses SourceCode::$charset
  179. * @static
  180. */
  181. static protected function afficher($filename)
  182. {
  183. $file = basename($filename);
  184. $dir = dirname( $filename);
  185. $fileContent= file_get_contents($_SERVER['DOCUMENT_ROOT'].$filename);
  186. //parce que le serveur on sait jamais... c'est peut-être du IIS malconfiguré (pléonasme)
  187. header('Content-type: text/html ; charset='.self::$charset.';');
  188. echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  189. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  190. <html xmlns="http://www.w3.org/1999/xhtml">
  191. <head>
  192. <meta http-equiv="content-type" content="text/html; charset=',self::$charset,'" />
  193. <title>Code du script / serveur = ',$_SERVER['SERVER_NAME'],$dir,'/',$file,'</title>
  194. <style type="text/css">';
  195. self::afficherCss();
  196. echo '
  197. </style>
  198. </head>
  199. <body id="top">
  200. <div class="boite">
  201. <h1>',$filename,'</h1>
  202. <p>derniere modification: <span id="lastModified">',date('r',filemtime($_SERVER['DOCUMENT_ROOT'].$filename)),
  203. '</span>. Cette page est affiché par <em>',get_class(),'</em>.</p>';
  204. self::afficherNavigation($filename);
  205. self::BriceA($fileContent);
  206. echo '
  207. <div style="clear:both"></div>
  208. </div>';
  209. /* on prépare le code. */
  210. self::afficherCode($_SERVER['DOCUMENT_ROOT'].$filename);
  211. echo '
  212. <hr />
  213. <div >licence: GPL 2+, author: Pierre-Emmanuel Périllon.</div>';
  214. self::afficherListeFonction($file);
  215.  
  216. include 'traceursJavascript.inc.php' ;
  217.  
  218. echo '
  219. </body>
  220. </html>';
  221. }
  222.  
  223. /**
  224. * @param filename $file
  225. * @static
  226. * */
  227. static protected function afficherCode($file)
  228. {
  229. $fileContent= file_get_contents($file);
  230. $max = substr_count ($fileContent,"\n")+1;
  231. $recherche = array('<br />'/*, '</font>', '</span>'*/);
  232. $remplace = array("<br />\n"/*, "</font>\n", "</span>\n"*/);
  233. $str = highlight_string($fileContent,true);
  234. $html= str_replace($recherche, $remplace, $str);
  235. echo '
  236. <table>
  237. <tr>
  238. <th> ? </th>
  239. <th> Code </th>
  240. </tr>
  241. <tr>
  242. <td title="Numéro de ligne" ><code>';
  243. /* afficher les numeros dans une cellule*/
  244. for ( $i=1; $i <= $max ; $i++)
  245. {
  246. echo '
  247. <a id="line',$i,'" href="#line',$i,'">',$i,'</a><br/>';
  248. }
  249. echo '
  250. </code></td>
  251. <td title="le code php" >',
  252. /* le reste dans une autre cellule */
  253. $html,'
  254. </td>
  255. </tr>
  256. </table>';
  257. }
  258.  
  259. /**
  260. * @static
  261. * */
  262. static protected function afficherCss()
  263. {
  264. echo '
  265. /*<![CDATA[*/
  266. body{font-size:10pt}
  267. a{text-decoration:none}
  268. a:hover{font-weight:bolder}
  269. .boite{border:black 2px solid;text-align: center}
  270. .boite a{text-decoration:underline}
  271. code{font-size:10pt}
  272. code a{color:gray;text-decoration:none}
  273. code a:hover{text-decoration:underline}
  274. h1{font-family:monospace}
  275. .toolbox{position:fixed;bottom:0;right:0;width:30ex}
  276. .toolbox>.resume{text-align:center;border:1px black solid;background:whitesmoke;margin:0;padding:2pt}
  277. .liste{margin:0;padding:0;}
  278. .liste>li{margin:0;padding:1px;}
  279. .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;}
  280. .toolbox:hover>.liste{display:block}
  281. .abstract{text-decoration:line-through}
  282. .private{color:red}
  283. .protected{color:blue}
  284. .public{color:green}
  285. .final{background-color:yellow}
  286. /*]]>*/
  287. ';
  288. }
  289.  
  290. /**
  291. * @param filename $file
  292. * @static
  293. * @uses SourceCode::listerFonction()
  294. * @uses SourceCode::afficherPrototype()
  295. * */
  296. static protected function afficherListeFonction ($filename)
  297. {
  298. $t = self::listerFonction($filename);
  299. $c = count ($t);
  300. echo '
  301. <div class="toolbox">';
  302. if ( $c > 0 )
  303. {
  304. echo '<ul class="liste" >';
  305. foreach( $t as $proto)
  306. {
  307. self::afficherPrototype($proto);
  308. }
  309. echo '</ul>';
  310. }
  311. echo '
  312. <div class="resume" ><a href="#top" title="top">',$c,' méthodes/fonctions</a></div>
  313. </div>';
  314. }
  315.  
  316. /**
  317. * @param filename $file
  318. * @static
  319. * @uses SourceCode::listerFichiers()
  320. * */
  321. static protected function afficherNavigation($filename)
  322. {
  323. $t = self::listerFichiers($filename);
  324. echo '
  325. <ul style="text-align:left;float:left;width:20em">
  326. <li><a href="',self::faireLien($t[0]),'">fichier précédant</a></li>
  327. <li><a href="',self::faireLien($t[1]),'">fichier suivant</a></li>';
  328. /*
  329. if ( file_exists('index.php') )
  330. {
  331. echo '<li><a href="?',self::$param,'">index</a>.</li>';
  332. }
  333. if ( file_exists('../index.php') )
  334. {
  335. echo '
  336. <li><a href="..?',self::$param,'">parent</a></li>';
  337. }
  338. */
  339. if ( isset($_SERVER['HTTP_REFERER']) )
  340. {
  341. echo '
  342. <li><a href="',htmlspecialchars($_SERVER['HTTP_REFERER']),'" title="',htmlspecialchars($_SERVER['HTTP_REFERER']),'">referer</a></li>';
  343. }
  344. echo '
  345. </ul>';
  346. }
  347.  
  348.  
  349.  
  350.  
  351. /**
  352. * @static
  353. * @param array $p
  354. * */
  355. static protected function afficherPrototype($p)
  356. {
  357. echo '<li>',(empty($p['static'])?'->':'::');
  358. echo '<a class="',$p['abstract'],' ',$p['visibility'],' ',$p['final'],
  359. '" href="#line',$p['line'],
  360. '" title="ligne ',
  361. $p['line'],': ',$p['abstract'],' ',$p['visibility'],'" >',$p['function'],'()</a></li>';
  362. }
  363.  
  364. /**
  365. * liste les fichiers
  366. * @param filename $file
  367. * @static
  368. * @return array
  369. * */
  370. static function listerFichiers($filename)
  371. {
  372. // Debug::var_dump($filename);
  373. $dir = dirname($filename);
  374. $ref = basename($filename);
  375.  
  376. $tab = glob($_SERVER['DOCUMENT_ROOT'].$dir.'/*.php');
  377. // Debug::var_dump($tab);
  378. if ( $tab === false )
  379. {
  380. echo '<tt>Votre hébergement à probablement bloqué glob()... </tt>';
  381. $r[0] = $r[1] = $filename;
  382. return $r;
  383. }
  384. $files = array_map('basename',$tab);
  385. $i = array_search($ref, $files);
  386. //s'il y a pas au moins un fichier...
  387. if (0 == $i )
  388. {
  389. $r[0] = end($tab);
  390. }
  391. else
  392. {
  393. $r[0] = $files[$i-1];
  394. }
  395. //pas de dépassement
  396. $j = $i+1;
  397. if ( $j == count($files) )
  398. {
  399. $r[1]=$files[0];
  400. }
  401. else
  402. {
  403. $r[1]=$files[$j];
  404. }
  405. return $r;
  406. }
  407.  
  408.  
  409. /***
  410. * @param filename $filename
  411. * @static
  412. * @uses SourceCode::simplierPrototype()
  413. * @uses SourceCode::patternFunction
  414. * @return array
  415. * */
  416. static function listerFonction($filename)
  417. {
  418. $f = file ($filename);
  419. $r = array();
  420. foreach( $f as $n => $line )
  421. {
  422. if ( preg_match(self::patternFunction, $line, $matches ) )
  423. {
  424. $x =self::simplierPrototype($matches, $n+1);
  425. // on peut avoir deux fonctions du meme nom dans un meme fichier
  426. // mais tres difficilitement dans une meme ligne
  427. $r[$x['function'].'@'.$x['line']]=$x;
  428. }
  429. }
  430. ksort($r);
  431. return $r;
  432. }
  433.  
  434.  
  435. /**
  436. * afficher le code source d'une page au cas ou on en a besoin.
  437. * @return void affiche et termine ou ne fait rien
  438. * @uses SourceCode::afficher()
  439. * @static
  440. */
  441. static final function obtenir()
  442. {
  443. if( isset($_GET[self::$param]) )
  444. {
  445. // Debug::here();
  446. if ( empty($_GET[self::$param]) )
  447. {
  448. self::afficher($_SERVER['PHP_SELF']);
  449. } // if( isset($_GET['getSourceCode']))
  450. else // if ( $_SERVER['PHP_SELF'] === $_SERVER['SCRIPT_NAME']) // ça peut échouer de temps en temps alors que ça devrait pas...
  451. {
  452. $safeFile = self::forcerLegitimite($_GET[self::$param]);
  453. self::afficher($safeFile);
  454. }
  455. }
  456. // else
  457. // {
  458. // Debug::here();
  459. // echo 'nothing to do';
  460. // }
  461. }
  462.  
  463.  
  464. /**
  465. * je serai anglophe j'aurai appelé ça un sanitizer
  466. * Je vous déconseille fortement de ne pas personnaliser ce code.
  467. * Dans cette configuration, c'est "sécure"...
  468. * @param $randomFile une chaine pouvant contenir n'importe quoi mais dont on aimerai s'assurer que c'est bien un nom de fichier.
  469. * @return string un nom de fichier. Methode du type "vaincre ou mourir".
  470. **/
  471. static protected function forcerLegitimite($randomFile)
  472. {
  473. // vous devez décommenter vous meme cette partie du code
  474. // et n'allez pas dire que ça ouvre une faille de sécurité
  475. // si vous exposez ainsi vos mots de passe.
  476. /*
  477. //interdire de remonter vers la racine... mais que ce passe t'il en cas de caractere non ascii???
  478. if ( strpos($randomFile,'..') !== false )
  479. {
  480. header('HTTP/1.0 403 Forbidden');
  481. die( 'parent directory change not allowed' );
  482. return false; //faire plaisir au compilateur
  483. }
  484. //donner un chemin relatif... encore une syntaxe exotique...
  485. $file = $_SERVER['DOCUMENT_ROOT']. $fileRelative = dirname($_SERVER['PHP_SELF']).'/'.$randomFile;
  486. if ( !file_exists($file) )
  487. {
  488. header('HTTP/1.0 404 Not Found');
  489. die('Not found:'.$file);
  490. return false;
  491. }
  492. //extention connue...
  493. foreach( self::$ext as $extention )
  494. {
  495. $pos = strrpos($randomFile, $extention);
  496. if ( $pos !==false and ( strlen($extention)+$pos === strlen($randomFile) ) )
  497. {
  498. return $fileRelative;
  499. }
  500. }
  501. */
  502. header('HTTP/1.0 403 Forbidden');
  503. die ('not allowed, please edit '.__FILE__.':'.__LINE__);
  504. }
  505.  
  506. /**
  507. * @access private
  508. * @param array $m
  509. * @param integer $line
  510. * @return array
  511. * @static
  512. * */
  513. static private function simplierPrototype($m, $line)
  514. {
  515. $tmp= $m[2].$m[3].$m[4];
  516. if (empty($tmp))
  517. {
  518. $tmp = 'public';
  519. }
  520. $r['static'] = '';
  521. $r['abstract'] = '';
  522. $r['final'] = '';
  523. $key=array('static','abstract','final','function');
  524. unset($m[0]);
  525. unset($m[2]);
  526. unset($m[3]);
  527. unset($m[4]);
  528. $r=array_combine($key,$m);
  529. $r['visibility']=$tmp;
  530. $r['line'] = $line;
  531. return $r;
  532. }
  533.  
  534. /**
  535. * @access protected
  536. * @static
  537. * @uses SourceCode::$dir
  538. * @uses SourceCode::$ext
  539. * @uses SourceCode::patternException
  540. * @uses SourceCode::$param
  541. * @uses SourceCode::chercherDocumentation()
  542. * */
  543. static protected function convertirSymboleVersLien($objet, $type)
  544. {
  545. if ( empty( $type ) and file_exists ($objet) )
  546. {
  547. return self::faireLien($objet);
  548. }
  549. // ouaip dans ce sens là.
  550. else if ( function_exists(self::$autoloader) and ($theFile = call_user_func(self::$autoloader, $objet, false) ) !== False )
  551. {
  552. return self::faireLien($theFile);
  553. }
  554. else
  555. {
  556. if ( preg_match(self::patternException,$objet,$matches) )
  557. {
  558. //si c'est une exception, on s'en contrefiche.
  559. return null;
  560. }
  561. else
  562. {
  563. return self::chercherDocumentation($objet);
  564. }
  565. }
  566. }
  567.  
  568. static function faireLien($theFile)
  569. {
  570. if (empty($_GET[self::$param]) )
  571. {
  572. return htmlspecialchars($theFile).'?'.self::$param;
  573. }
  574. else
  575. {
  576. return '?'.self::$param.'='.urlencode($theFile);
  577. }
  578. }
  579.  
  580. /***
  581. * trouve l'url associée à une classe ou interface...
  582. * @access protected
  583. * @static
  584. * @param string $type
  585. * @param array $array
  586. * @return array
  587. * @uses SourceCode::convertirSymboleVersLien()
  588. * */
  589. static protected function convertirListeSymboleVersLien($array,$type)
  590. {
  591. // $array = array_unique($array);
  592. $l = array();
  593. foreach( $array as $objet )
  594. {
  595. $objet = trim($objet);
  596. if ( empty($objet) or in_array( $objet , self::$ignore ) )
  597. {
  598. continue;
  599. }
  600. $l[$type.' '.$objet]= self::convertirSymboleVersLien($objet, $type);
  601. //traiter les
  602. }
  603. return $l;
  604. }
  605.  
  606. /***
  607. * @static
  608. * @uses SourceCode::$docUrl
  609. *
  610. * */
  611. static protected function chercherDocumentation($symbole)
  612. {
  613. return self::$docUrl.urlencode($symbole);
  614. }
  615.  
  616.  
  617. }//class
  618. /* la fin */
Developpez.com décline toute responsabilité quant à l'utilisation des différents éléments téléchargés.

Connexion

Identifiant
Mot de passe
S'inscrireMot de passe oublié ?
 
 
 
 
Partenaires

Hébergement Web