Newsgroup: it.comp.www.php
Titolo: Problema parser PHP [Atto secondo - lunghetto]

Risalve a tutti.
Innanzittutto ringrazio Setec e Leonardo Serni per le loro preziosissime risposte nel post precedente ma
purtroppo ancora ho dei problemi che non riesco a risolvere.
Riprendo brevemente il problema.
Ho una stringa nella quale ho mescolato PHP e HTML. Con la classe MixedEval riesco ad effettuare il parsing e 
ottengo come output un file di testo che va visualizzato a video. Fin qui tutto ok.
La stringa file di testo (PHP/HTML) viene importata tramite la funzione file_get_contents();
All'interno di questa stringa io posso avere un numero imprecisato di variabili da visualizzzare. Possono essere 2 come possono essere 200.
Inoltre all'interno della stringa devo poter visualizzare anche, non solo variabili normali, ma anche array.
Se tutte queste variabili sono definite nella stringa stessa, all'interno di un blocco <??> allora la classe funza senza nessun problema.
Il problema sta invece quando devo visualizzare delle variabili che si trovano nel contesto esterno alla stringa.
Cioè all'interno della stringa, queste varibili non sono definite all'interno di <? ?> ma si desume che esse siano già definite perchè
esistono nel contesto esterno.
Purtroppo la classe MixedEval sostituisce il valore delle variabili, solamente se esse appartengono alla stringa, altrimenti la variabile rimane
indefinita.
La strada consigliatami da Setec mi è parsa molto buona. Ho utilizzato quindi get_defined_vars() per restituirmi una array con tutte le
variabili definite in un determinato contesto. Come output ho ottenuto un array il cui contenuto è misto (variabili, oggetti, array) e 
rappresenta cio' che in un determinato istante è definito nel mio contesto.
La prima strada che ho provato è stata quella di andare a esplorare ricorsivamente l'array di cui sopra...e farmi ritornare da una funzione
una stringa con tutte le variabili ridefinite, per riottenere un file di testo del tipo:
<?
nomevariabile1="variabil1";
nomevariabile2="variabil2";
nomevariabile3="variabil3";
array["chiave"]=valore;
etc.
etc..
?>
In questo modo...tale stringa l'avrei fatta antecedere alla stringa originale da parsare...in modo che MixEval riusciva a trovare tutte le variabili necessarie...anche quelle esterne...
Ho subito abbandonato questo approccio perchè mi è sembrato molto sporco e sto cercando di pensare a qualcosa di più pulito anche perchè per estrarre tutte le variabili è un mezzo casino. 
Considerando poi...la formattazione di tutti gli array, alcuni finiscono con il punto e virgola, altri hanno le virgolette, altre no,  etc.. dovrei mettermi a colpi di ereg_replace...e per ora...non ho proprio tempo perchè sono preso da lezioni ed esami universitari.
La seconda strada che mi è venuta in mente è quella di utilizzare "extract($variables , EXTR_OVERWRITE)".
dove $variables=get_defined_vars(), cioè l'array che rappresenta le variabili del mio contesto base, dove sono definite le variabili che a me interessano.
Avevo pensato di passare come parametro tale array alla classe MixedEval e li' dentro effettuare l'extract...ma per come è gestita la logica di MixedEval mi sono reso conto...che in fase di sostituzione manco li guarda le variabili che vengono estratte.
Secondo voi esistono alternative al mio modo di ragionare?...oppure mi devo rassegnare a fare quella funzione che mi fa il lavoro
sporco e mi ridefinisce ogni variabile all'interno di una stringa come fosse semplice testo, per poi anteporla alla stringa da parsare?
Ringrazio anticipatamente
euterpex
p.s. conoscete magari qualche altra classe tipo MixedEval  che preveda questo genere di problema?
p.p.s. qui sotto posto la classe MixedEval (c'era un piccolo bug-etto...che ho corretto ma era dovuto sicuramente a una svista dell'autore).
<?
/* MixedEval.php (c) 2001 John Dickinson (
jo...@techwise.com.au
)
 *
 * TERMS OF USAGE:
 * This file was written and developed by John Dickinson (
jo...@techwise.com.au
)
 * for educational and demonstration purposes only.  You are granted the
 * rights to use, modify, and redistribute this file as you like.  The only
 * requirement is that you must retain this notice, without modifications, at
 * the top of your source code.  No warranties or guarantees are expressed or
 * implied. DO NOT use this code in a production environment without
 * understanding the limitations and weaknesses pretaining to or caused by the
 * use of these scripts, directly or indirectly. USE AT YOUR OWN RISK!
 *
 * If you are looking for someone to code in php, perl, asp, java, 
 * javascript (etc) feel free to email or visit our website at 
 * 
www.techwise.com.au
 *
 * If you improve upon this script, please send me a copy so i can make it 
 * available
 * If you find any bugs, let me know and I will try to find time to fix them
 */
 class MixedEval {
  function MixedEval ($Code) {
   $this->Code = stripslashes($Code);
   $this->setCodeArray();   
  }
  function setCodeArray() {
   $token   = ">:<:>:<";  //make sure it is rare
   $phptoken  = "<:>:<:>";
   if(eregi('<\?=', $this->Code, $regs)) { 
    $this->delimitererror =  "<b>PHParse error: <font color=red> tag \"&lt;?=\" is not 
supported </font>";
    echo "<br></b>";
   }
   $this->Code = ereg_replace("<\?php", "<?", $this->Code);
   $this->Code = ereg_replace("<\?", "<?$phptoken ", $this->Code);
   $this->Code = ereg_replace("<\?", $token, $this->Code);
   $this->Code = ereg_replace("\?>", $token, $this->Code); 
   $CodeArray = explode($token, $this->Code);
   for($i=0; $i<sizeof($CodeArray); $i++) {
    if(eregi("^$phptoken",  $CodeArray[$i])) {
     $this->CodeArray[$i]['TYPE'] = "php";     
     $CodeText = substr($CodeArray[$i], strlen($phptoken));
    } else {
     $this->CodeArray[$i]['TYPE'] = "html";
     $CodeText = $CodeArray[$i];
    }
    $this->CodeArray[$i]['TEXT'] = $CodeText;
   }
  }
  function formatError($offender) {
   eval($offender); 
   if($this->delimitererror)
    echo $this->delimitererror;
   else
    echo "<b>check the line number of the following evaled of code:</b><br>";
   echo "<hr>";
   $offender = ereg_replace("\n", "\n", $offender);
   $offender = ereg_replace("\t", '&nbsp;&nbsp;\t', $offender);      
   $offender = ereg_replace(" ", '&nbsp;', $offender);      
   echo '<b><font color=green>0.&nbsp;&nbsp;&lt;?';
   $offenderlines = split("\n", $offender);
   for($j=0; $j<sizeof($offenderlines); $j++) {
    $jNext = $j + 1;
    echo '<br>'.$jNext.".&nbsp;&nbsp;";
    echo $offenderlines[$j];
   }
   $StrangeJ_ThingNext = $StrangeJ_ThingNext + 1;
   echo '<br>'.$StrangeJ_ThingNext.'.&nbsp;&nbsp;?&gt;</font></b>'; 
   echo "<hr>";
  }
  function show() {  
   //Need a strange incrementor name to prevent code interference, something no one will 
   for($StrangeI_Thing=0; $StrangeI_Thing<sizeof($this->CodeArray); $StrangeI_Thing++) {
    if($this->CodeArray[$StrangeI_Thing]['TYPE'] == "php") { 
     @eval($this->CodeArray[$StrangeI_Thing]['TEXT']." \$eval_ok = true; ");
     if(!$eval_ok) {
      $offender = $this->CodeArray[$StrangeI_Thing]['TEXT']; 
      $this->formatError($offender);
     }
     $eval_ok = false; 
    } else {
     echo $this->CodeArray[$StrangeI_Thing]['TEXT'];
    }
   }
  }
 }

 Ho una stringa nella quale ho mescolato PHP e HTML. 
One line solution:
<?php 
eval (' ?' . '>' . str_replace ("'", "\'", file_get_contents
('index.php')) . '<' . '?php ');
?>
Saluti.
-- 
I am what I am, I do what I can
L'uomo, conscio di sbagliare, persevera.

 ?>
Scusami, forse non ho capito bene. Dovrei sostituire il tuo script al posto di MixedEval? Se è cosi' (a parte che non riesco più a visualizzare niente), secondo me non funziona. Il mio problema non è il parsing che funziona egregiamente...ma come fargli entrare queste benedette variabili in quel testo nel modo più pulito possibile.
Cmq...grazie lo stesso..
euterpex

 benedette variabili in quel testo nel modo piů pulito possibile.
Non vedo il problema:
<?php 
$var = "test";
$file_content = '<?php print ($var); ?>';
eval (' ?>' . $file_content . '<?php ');
?>
-- 
I am what I am, I do what I can
Vuoi supportarmi? 
http://url.repository.biz/go/3E


Il problema sta invece quando devo visualizzare delle variabili che si trovano nel contesto esterno alla stringa.
Facciamo una cosa: scrivi un esempio di massimo cinque righe :-) con
i casi peggiori dell'HTML che hai.
Io do' per scontato che chi interpreta la stringa abbia accesso alle
variabili.
Per esempio:
<html>
<head><title>$TITLE</title></head>
<body>
$RIGHE
</body>
</html>
In questo caso diciamo che $TITLE vale 'Titolo' e $RIGHE vale
	array(
		'pluto' => 'riga 2',
		'pippo' => 'riga 1',
	);
...tu che HTML vorresti in risposta?
Leonardo
-- 
Avere studiato senza mettere in pratica e' inutile;
mettere in pratica senza avere studiato e' pericoloso.
                                                - Conphpucio