Newsgroup: it.comp.www.php
Titolo: richiamare file php in modo isolato

Ho creato il seguente file:
 
<?php // b.php
 
if (isset($x)) {
     trigger_error(
        'Riesco ad accedere alla variabile $x, la cosa non va bene!!!'
     );
} else {
     echo 'Tutto ok!!!';
}
 
?>
 
Tale file deve però essere richiamato da un altro file (index.php):
 
<?php // index.php
 
$x=123;
require 'b.php';
 
?>
 
Quindi mi collego a 
http://local/test/index.php
, e come vedete tutto 
funziona, anzi... no!!!
 
Infatti voglio che il file 'b.php' non possa accedere alla variabile $x 
(dichiarata nel file 'index.php' prima dell'istruzione require).
Ho tentato quindi di usare al posto di require, la seguente istruzione:
 
echo file_get_contents('b.php');
 
ma non va bene perchè viene semplicemente letto il contenuto del file 
'b.php', cioè non viene interpretato (eseguito) come un normale script php.
 
Infine ho optato per una terza soluzione:
 
echo file_get_contents(
     $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'] . ':' 
$_SERVER['SERVER_PORT'] . dirname($_SERVER['SCRIPT_NAME']) . '/b.php'
);
 
e finalmente funziona.
 
Però è orribile dover specificare l'url assoluto, non vi pare?
Possibile che non ci sia un modo più semplice per richiamare un file php 
in modo isolato da tutto il resto...
Cioè voglio che 'b.php' venga caricato come se fosse stato richiamato 
direttamente dal browser digitandone l'apposito indirizzo 
(
http://local/test/b.php
).
 
In pratica l'ultima soluzione andrebbe bene, ma invece del diabolico url 
assoluto, non si potrebbe specificare l'url relativo (semplicemente 
'b.php') ?
 
Non so se mi sono spiegato...

 Non so se mi sono spiegato...
 
Sì, ti sei spiegato perfettamente
La domanda è ciclica e si può riassumeere in:
Col linguaggio B il costrutto Ac non funziona
Come faccio a far funzionare B come A?
 
La risposta è:
Usa A
 
In alternativa la versione più user-friendly: non dirci come vuoi fare, 
dicci cosa vuoi fare; è chiaro che stai affrontando la cosa dal punto 
sbagliato
 
Nel caso particolare una soluzione è eseguire separatamente i due file. 
Come approccio si chiama AJAX
Da una pagina renderizzata fai una chiamata al server per ottenere vari 
pezzi di pagina, dati, cose ...
 
-- 
I fatti mi cosano

 pezzi di pagina, dati, cose ...
 
Voglio assicurarmi che alcuni script php (che devono solo manipolare dei 
dati) non producano output.
 
<?php // test_suite.php
 
if (file_get_context('a.php') != '') trigger_error('E stato prodotto 
dell'output');
 
//altre istruzioni...
 
if (file_get_context('b.php') != '') trigger_error('E stato prodotto 
dell'output');
 
//altre istruzioni...
 
if (file_get_context('c.php') != '') trigger_error('E stato prodotto 
dell'output');
 


O_o ?
e tu non ci mettere echo print_r e var_dump dentro ...
Davvero non colgo il punto



 
in questo modo naturalmente viene letto solo il contenuto dei file.
Invece devono essere eseguiti uno ad uno, ma ciascuno in una sorta di 
frame isolato, come se li stesse richiamando direttamente il browser 
(non il file 'test_suite.php').
 
Potrei usare quei cosi che si usavano una volta in html (frame, 
iframe...), ma poi in qualche modo andrebbe verificato il contenuto di 
tali frame (output prodotto dagli script), analizzandoli tramite la 
classe DOMDocument, no no no, lasciamo stare  :-P
 
L'unica cosa è quindi usare gli url assoluti (poco flessibili), ma è 
scomodo, è pasticcioso ;)

 dati) non producano output.
 
ob_start();
include "script.php";
ob_end_clean();
 
 
Per rispondere anche all'altra domanda, se vuoi isolare delle variabili, 
ti basta metterle in un oggetto come private.
 
Se vuoi isolare un pezzo di codice in un file incluso, puoi fare
 
--- script.php
<?php
echo $a;
 
--- index.php
<?php
$a = 10;
function dontfuckwithmyvars()
{
  include "script.php";
}
dontfuckwithmyvars();
 
 
Ma te lo sconsiglio caldamente. Serve solo se devi integrare codice 
legacy molto sporco e scritto male, e mai in questo modo barbaro.
 
Se stai scrivendo il tuo codice, il modo giusto è di programmare a oggetti 
e usare le eccezioni per sollevare errori, invece di stamparli a schermo.
 
Bye.

 scomodo, è pasticcioso ;)
Quando scrivi qui in lista spesso faccio fatica a capire se hai un tuo 
sottile modo di prendere per i fondelli la gente o se davvero pensi 
quello che scrivi
 
Facciamo finta che il trollometro non stia ticchettando
Come ti diceva Alessandro l'approccio corretto è scrivere ad oggetti
Per ottenere pezzi di pagina in modo asincrono e isolato ci sono le 
richieste Ajax (unico contributo di M$ al mondo dell'informatica)
L'argomento è troppo vasto e tu sembri non avere né le minime basi né la 
voglia di impararle
 
Documentazione ce n'è molta



$x = $var_non_dichiarata;
 
secondo te tale script output ne produce o no?
Eppure echo, var_dump, ecc. non ne ho usati!!!

 voglia di impararle
 
ok, quindi bisogna per forza lavorare di js
 


<?php
error_reporting(0);
$x = $var_non_dichiarata;
 
marco@athlonno ~/tmp $ php t.php
marco@athlonno ~/tmp $
 
E la barbarie raggiunge la completezza :D
 
http://www.php.net/manual/en/function.error-reporting.php
 



 
Non è che "per forza" devi lavorare di js
Magari per i tuoi scopi vien più comodo aprire un websocket e parlare 
con nodejs lato server
 
dipende da quello che vuoi fare
Se vuoi usare un martello tutti i problemi diventeranno chiodi


'b.php') ?
 
No, perche' a quel punto il server non saprebbe cosa andare a prendere.
 
Va bene come hai fatto tu: prelevare l'URL del file chiamante, sostituire
al nome chiamante il nome chiamato, e ri-invocare l'URL con un wrapper di
fopen(), o via cURL.
 
Leonardo
 
-- 
 
Then felt I like some watcher of the skies, when a new planet swims into his ken;
Or like stout Cortez when with eagle eyes, he star'd at the Pacific; and all his men
Look'd at each other with a wild surmise - silent, upon a peak in Darien.


 
 
e cmq eventuali $_GLOBAL['mia_key'] rimangono accessibili
 

 fopen(), o via cURL.
 
in effetti è un metodo un po' sporco ma per il momento creerò una 
funzione che componga l'url assoluto e faccia il test.
Appena posso troverò qualcosa di meglio

 e cmq eventuali $_GLOBAL['mia_key'] rimangono accessibili
 
E grazie al cazzo! :D
 
Scusa il francesismo, ma $_GLOBALS è fatto apposta... per non essere 
usato.
 
Se hai script che usano variabili globali, $_GLOBAL e simili, buttali nel 
cesso e riscrivili da zero.
 
Per gli altri script che non fanno tante porcherie ma sono comunque 
legacy, intanto usa i wrapper che ti ho consigliato, ma programmati di 
riscriverli da zero. Meglio.
 
Se parti da zero con tutto e hai bisogno di queste tecniche, hai 
sbagliato approccio. Riparti da zero, studiando un buon manuale di 
programmazione a oggetti (che anche se programmi procedurale ti darà 
buone indicazioni) e di buona programmazione in generale (pragmatic 
programmer, clean code, e simili).
 
Bye.

 (
http://local/test/b.php
).
 
Secondo me stai sbagliando candeggio.
 
Dichiara qualche classe e benvenuto nell'OOP.
 
 
-- 
Andrea
 


 
solo che in questo caso sarà lo script a prendersi le responsabilità; se 
il paziente non vuole farsi visitare dal dottore...
 
Comunque aspetta, provo a spiegare...
Ho scritto degli snippets (esempi di codice) per svolgere alcune 
operazioni (accesso, modifica, convalida dati), che non producono alcun 
output, eccetto in caso d'errore.
Adesso voglio avere la certezza che tali snippets siano funzionanti, 
specialmente ogni volta che su di essi apporto delle modifiche.
Cosa faccio?
Li eseguo ogni volta uno per uno?
 
php ciccio.php
php ciccio2.php
php ciccio2.php
php ciccio4.php
 
E se creassi una sorta di test_suite.php non sarebbe meglio?
Tale suite quindi deve richiamare i file elencati precedentemente.
Inizia quindi da ciccio.php (include 'ciccio.php'), poi chiama 
ciccio2.php (include 'ciccio2.php'), poi chiama... stop, attenzione...
ciccio2.php è in grado di accedere alla variabile $file
 
<?php //ciccio2.php
 
$file->fputs('scrivo quello che voglio, alla faccia di ciccio.php, 
trullallero');
 
?>
 
Infatti la variabile $file è stata creata da ciccio.php
 
<?php //ciccio.php
 
$file = fopen('test.txt', 'w');
$file->fputs('nessuno si deve permettere di scrivere nel mio file');
 
?>
 
E' chiaro?

 programmer, clean code, e simili).
 
comunque forse per quello che voglio fare dovrei implementare dei test 
funzionali in stile doctrine (usati per symfony).
 
$browser->
	get('ciccio.php')->assertNoTextFound()->
	get('ciccio2.php')->assertNoTextFound()->
	get('ciccio3.php')->assertNoTextFound()
;
 
o qualcosa del genere...

 E se creassi una sorta di test_suite.php non sarebbe meglio?
 
Appunto :)
 
Bye.

 funzionali in stile doctrine (usati per symfony).
 
Come ho detto, PHPUnit.
 
Ma devi cambiare il tuo modo di programmare. Non puoi continuare come se 
fosse assembler. E` un linguaggio ad alto livello, e come tale devi 
usarlo.
 
Bye.

 Meglio ancora se usi le eccezioni.
 
ok, e che volevo richiamare gli snippet in ambiente di primo piano 
(niente pre-script), perfettamente naturale e pulito, proprio come 
farebbe il browser

 E' chiaro?
 
Sì, è chiaro che non stai capendo come funziona lo strumento che ti 
ostini ad usare, né stai cercando di capirlo.
Ma leggersi un manuale di programmazione di base pubblicato dopo il 2000?
 
Personalmente sono a epsilon/2 dal PLONK



 
<?php //nomi.php
// esempio elementare (super elementare) di come dichiarare un array
$nomi = array(
	'marco',
	'pietro',
	'luca'
);
?>
 
Il precedente codice è già ingabbiato in un file.
Lo dovrei mettere anche in una function, e magari in una classe, che 
magari deve far parte di un namespace... e alla fine gli metto anche le 
manette e lo mando in prigione ;)
A parte gli scherzi, siccome si tratta solo di un esempio, vorrei 
lasciarlo sciolto, privo di fronzoli strutturali, che lo rendono adatto 
anche per essere incluso in una normale pagina web.
Qui si possono vedere vari esempi:
http://symfony.com/legacy/doc/jobeet/1_4/it/09?orm=Doctrine
 
Capito il senso?

 Capito il senso?
 
Sì, io sì. :)
Ma tu forse non hai notato che tutto quello che testano è OOP, non 
snippet di codice.
 
Bye.


 
esempi funzionanti.
E per essere funzionanti e meglio che siano testati.
 
<?php //script funzionante
$x=9;
unset($x);
?>
 
<?php //script non funzionante (va sistemato)
$x=9
unset($x);
?>
 


con l'OOP ci lavoro da circa 15 anni, ma siccome si tratta di ritagli di 
codici (importabili in testi didattici), volevo evitare...
Inoltre volevo che tali codici fossero testabili in ambiente sterile, ma 
forse entrambe le cose mi sa che non sono concigliabili.
Purtroppo mi tocca scegliere se usarli solo come esempi, oppure come 
librerie (funzionalità utili).

 librerie (funzionalità utili).
E non si capisce  perché un esempio debba essere necessariamente 
alternativo ad una cosa utile
 
 
Bon,  scherzi a parte credo si inizi ad intravedere *cosa* vuoi fare in 
mezzo ad un mare di sproloqui su *come* lo vuoi fare
Perché non ce  lo dici chiaramente, così che magari tu trovi aiuto e che 
qualcun altro più avanti che dovesse fare la stessa cosa tua trovi delle 
utili tracce?
Il NG serve a questo
 
-- 
I cosi mi fattano

 Il NG serve a questo
 
http://www.filedropper.com/esempiofunzionante
 
scaricalo, decomprimilo in una dir. del tuo server, e lancia index.php
 
Noterai che dopo 2 + 2, manca il punto-e-virgola.
Se quindi mettessi questa pagina online, chi la visiterebbe mi 
prenderebbe per il...
 
Ciò si potrebbe evitare se prima della pubblicazione, facessi un 
semplice test sul file sample.php
 
Per fare il test basterebbe che nel browser digitassi
 
http://....../sample.php
 
e mi accorgerei subito dell'errore.
 
Però non sarebbe meglio che tale file venisse richiamato da un'apposita 
unità di test (test-suite o test-case)?
Però vorrei che lo facesse come se fosse un browser, non tramite 
istruzioni include/require.
 
Soddisfa questa spiegazione?

 Soddisfa questa spiegazione?
 
DOMANDA:
 
Ma perchè non vuoi proprio usare include/require?
Perchè l'esempio da testare potrebbe anche eseguire istruzioni 
pericolose, che lo sviluppatore ha introdotto per sbaglio.
Ad esempio richiamare qualcosa che è stato dichiarato precedentemente, 
ma che non deve assolutamente richiamare:
 
<?php //sample_killer.php
$sum=2+2;
if ($sum==4) lancia_la_bomba_atomica();//questa istruzione è finita in 
questo file per sbaglio (la funzione citata solo lo script 'caporale.php')
?>
 
Naturalmente la funzione 'lancia_la_bomba_atomica()' potrebbe essere 
stata dichiarata ad esempio nel file lib.php (o anche in index.php).
 
Dunque se sample_killer.php venisse isolato da tutto quello che lo 
precede, ciò non accadrebbe: verrebbe semplicemente generato un bel 
'function not found...' (non dannoso).
 


Quindi tu cerchi qualcosa che esegua o non esegua una funzione di una 
libreria in base a un criterio non meglio specificato
 
Senza una intelligenza artificiale credo che farai fatica
 
La libreria sample_killer nella documentazione ti dice che ha bisogno 
della funzione lancialabomba();
Se non gliela fai trovare non funziona
 
Se non vuoi lancialabomba non includere la libreria lib
Semplice
 
Se chi la scrive vuole fare il furbetto e non ti dice che usa 
funzioneStandardDiPHPHCheNonVuoiUsareMaHaiInstallatoComunqueSulServer 
ispeziona il codice prima di metterla in produzione
Se non controlli il codice che metti in prod sono pifferi tuoi, mica dei 
costrutti del linguaggio
Se proprio quella funzione non la vuoi usare non installarla quando 
compili php
Su Gentoo ci sono le flag di compilazione per attivare millemila 
funzionalità, da sqlite a xslt ...
 
Ti stai davvero perdendo in un bicchier d'acqua
Per capire dove stai sbagliando, fai uno use-case realistico
vedrai che mentre lo scrivi ti apparirà ovvia l'insensatezza di quello 
che stai dicendo


 che stai dicendo
 
quello che dici è giusto, ma ti mando quest'altro esempio
http://www.filedropper.com/reddito
 
 
Quindi facciamo il solito test:
http://..../reddito/test_suite_reddito.php
 
Molto bene, tutto funziona. L'ha detto la test_suite!!!
 
Mi telefona un collega: "ciao alex, hai per caso un esempio di codice 
php per visualizzare il reddito annuo; sai domani vorrei fare una 
dimostrazione di utilizzo davanti ai miei alunni.
- IO: ma certo che c'è l'ho, e funziona benissimo (è stato appena 
testato); ti mando i sorgenti.
- COLLEGA: grazie mandami tutto via email"
 
Quindi compongo l'email e ci allego 'annuo.php' e 'lib.php' (la libreria 
di supporto).
Il file 'mensile.php' non glielo mando (il reddito mensile non me l'ha 
chiesto).
 
L'indomani mi richiama: "ciao alex, il tuo esempio non ha funzionato.
Ho digitato
http:/.../annuo.php
compare l'errore: Call to undefined function view() in...
- IO: impossibile l'ho testato... ma aspetta che rifaccio il test, e ti 
richiamo"
 
Quindi rifaccio il test
 
http://..../reddito/test_suite_reddito.php
 
Molto bene, tutto funziona. L'ha detto la test_suite!!!
E lo sapevo, sicuramente il mio collega avrà combinato qualche pasticcio.
 
Adesso provo anche ad eseguirli singolarmente:
 
http://.../reddito/view/mensile.php
Ecco il reddito mensile: 1050
Perfetto aahaah!!!
 
http://.../reddito/view/annuo.php
Perfett... porc...
Call to undefined function view() in...
azz aveva ragione
 
Ma come mai nella test-suite tutto funziona?
E già, merito del require, che richiama entrambi i file nello stesso 
habitat!!!

 habitat!!!
 
Secondo il mio inutile parere, ti stai facendo delle seghe mentali degne 
di Freud, Jung e Lacan messi insieme.
 
Just my2c
 
Seriamente: ci sono e^n [n>2] modi per mandare in vacca un progetto 
software. Tu li vuoi eliminare tutti.
 
Ci sono interi volumi dedicati alle "Best Practices" e alle "Unit 
testing". Ma in tutti i volumi, anche in quelli più ottimisti, non c'è 
scritto "Fai come dico io e non avrai MAI errori".
 
Se introduci un errore di sintassi, in un linguaggio interpretato lo 
scoprirai solo a runtime (se compila tutto lo script, altrimenti dovrai 
attendere di cadere sulla riga farlocca, come nel vecchio BASIC).
Se introduci un errore nella logica, lo scoprirai forse con una unit 
test ben scritta (a sua volta passabile di essere fallace, per cui 
dovresti scrivere la Unit test della Unit test, ad libitum).
Se introduci una "bad practice" (ad esempio un file include con percorso 
assoluto cablato nel codice), è una tua mancanza, di cui ti accorgerai 
solo in futuro.
 
Ma queste sono cose che scoprirai solo vivendo...
 


Visto che come dicevo c'è dell'insegnamento di mezzo?
Ma per caso sei un insegnante statale?
 
Non è merito dell'habitat  cche in campo informatico  non è un termine 
che si usa, è merito del tuo approccio che è l'epitome delle worst-practices
Potresti migliorare e passare alle bad-practices usando require_once() 
sia in mensile che annuo
Saremmo sempre a livello di Facoltà di Informatica di Addis Abeba dove 
s'era laureato "Pierino medico della mutua", ma un pochino meno peggio


 s'era laureato "Pierino medico della mutua"
 
Quello in cui arriva l'interrupt e la ISR lancia la scorreggia dal 
distributore automatico di pasta e fagioli?
 
 
-- 
Andrea