Newsgroup: it.comp.www.php
Titolo: punto in cui viene richiamata una funzione

Si può conoscere il punto in cui viene richiamata la funzione corrente?
Ad esempio ho creato questi due file
 
<?php // a.php
function abc() {
     echo "Questa funzione è stata richiamata dal file '" . 
getCallFile() . "' alla riga " . getCallLine();
}
?>
 
<?php // b.php (riga 1)
require_once 'a.php'; // riga 2
abc(); // riga 3
?>
 
Quindi aprendo nel browser la pagina 
http://test/b.php
 dovrebbe comparire:
 
Questa funzione è stata richiamata dal file 'b.php' alla riga 3
 
Ma naturalmente non funziona; infatti le funzioni getCallFile() e 
getCallLine() non esistono (me le sono inventate io, per fare l'esempio).
Dunque in realtà funzioni di questo tipo non esistono proprio, oppure 
non le conosco io?

 Si può conoscere il punto in cui viene richiamata la funzione corrente?
 
http://php.net/manual/en/function.debug-backtrace.php
 
 
Come dice il nome, è solo per debug. Non sfruttarla per scrivere codice 
tipo "nella funzione b, se viene chiamata dal file A faccio Pippo, 
altrimenti faccio Pluto".
 
 
Bye.


Ma il tracciamento si attiva solo in caso di errore?
Non posso usarlo anche in condizioni normali?
 
Comunque c'è un modo per sapere almeno il numero della riga in esecuzione?
 
esempio:
 
<?php //riga1
//riga2
echo 'riga corrente: '.getcurrentline();
?>
 
Naturalmente anche in questo caso, se la fun. getcurrentline esistesse, 
dovrebbe essere visualizzato:
 
riga corrente: 3

 Comunque c'è un modo per sapere almeno il numero della riga in esecuzione?
 
Sì.
Volendo è anche possibile risalire ai parametri in ingresso delle funzioni, ma se non ricordo male per questo è necessario Xdebug: 
http://xdebug.org/docs/execution_trace
 

 Volendo è anche possibile risalire ai parametri in ingresso delle funzioni, ma se non ricordo male per questo è necessario Xdebug:
http://xdebug.org/docs/exe
 
 
xdebug.collectReturn?
exection_trace()?
function_trace()?
 
Non ho capito esattamente qual'è la funzione giusta?

 Non ho capito esattamente qual'è la funzione giusta?
 
Quella giusta è quella che fa quello che vuoi tu, o quella che si 
avvicina di più. Quindi il modo più semplice è provarle. Scrivi 10 righe 
di codice e vedi l'effetto che hanno.
 
Bye.


Allora ho studiato un po' le varie funzioni offerte da xdebug, ed ho 
trovato ad es. xdebug_call_line(), che mi restituisce la riga in cui è 
stata chiamata la funzione corrente.
Interessante, ma vorrei conoscere anche la riga corremente in esecuzione 
(vedere post delle 0.48); esiste una funzione apposita?
Mi sa di no...
 

Scusa, ma hai provato a fare un
 
print_r(debug_backtrace());
 
da qualche parte?!
 
Provaci, e vedrai che tutto quello che ti serve è già li.
File, linea, funzioni, chiamate...
 
Se non ricordo male (ora non riesco a provare) debug_backtrace() ti restituisce solo gli ultimi 3 eventi, se vuoi la traccia completa (dall'inizio dello script fino al punto di debug_backtrace()) devi usare xdebug e, se vuoi un consiglio, salva il backtrace in un file di testo e non stamparlo a video.
 
Se l'applicazione è un minimo complessa sarà chilometrico.


 
Buon consiglio.
 
Comunque guarda quest'altro esempio
 
<?php
 
abc();
 
function abc() {
     abc2();
     var_dump(debug_backtrace());
}
 
function abc2() {
 
}
 
exit();
 
?>
 
Come mai la chiamata alla funzione abc2 non viene registrata?

 Come mai la chiamata alla funzione abc2 non viene registrata?
 
Perchè nel punto in cui chiami debug_backtrace abc2() è già stata
poppata dallo stack di esecuzione.
 
Prova con questo:
 
<?php
 
abc();
 
function abc() {
	abc2();
}
 
function abc2() {
	var_dump(debug_backtrace());	
}
 
exit();
 
?>

 ?>
 
Si, ma se abc2 fosse una funzione abstract....

 Si, ma se abc2 fosse una funzione abstract....
 
Non potrebbe essere richiamata, perché le funzioni abstract non hanno 
corpo, ma solo firma.
 
Bye.

 corpo, ma solo firma.
 
Nella classe astratta, non in quelle derivate.
Cmq dire che una funzione astratta non può essere richiamata... 
sicuramente volevi dire un'altra cosa!!!

 sicuramente volevi dire un'altra cosa!!!
 
No, volevo dire proprio quello.
 
Una funzione astratta (meglio: un metodo astratto, visto che una funzione 
astratta non ha senso) non può essere richiamata, esattamente come una 
classe astratta non può essere istanziata, e non puoi avere un metodo 
astratto dentro una classe non astratta.
 
Una funzione astratta dichiara solo la firma della funzione, non il suo 
corpo (altrimenti non sarebbe astratta), e quella che chiami è la 
funzione che fa l'override della funzione astratta, che deve rispettarne 
il contratto (la firma).
 
Bye.

 il contratto (la firma).
 
Infatti, una funzione astratta diventa una funzione normale, nel momento 
in cui viene implementata all'interno di una classe ereditata, e alla 
fine è quindi richiamabile come tutte le funzioni (metodi).
Dunque se la diciamo in questo modo è già un altra cosa; ma dire 
semplicemente che una funzione non è richiamabile, è poco esplicativo.

 semplicemente che una funzione non è richiamabile, è poco esplicativo.
 
Non fare acrobazie grammaticali per cercare di dimostrare che hai ragione.
 
Una funzione abstract NON può essere richiamata. Non si trasforma. Rimane 
abstract. Esattamente come una interface non "si trasforma" in una classe 
quando la implementi.
 
Bye.

 quando la implementi.
 
Cosa c'entra l'interface?
 

 E se esisterebbe a cosa servirebbe?
 
ESISTESSE, od al limite ESISTE!!!!
 

 E se esisterebbe a cosa servirebbe?
*************************************


Certamente, su questo mi inchino ;)

E se esisterebbe a cosa servirebbe?
 
Come segnaposto. Tutte le classi che concretizzano la classe astratta DEVONO
implementare quei metodi. Oh, ti pare poco?
 
Magari potevano non chiamarla "funzione abstract", ma, che so io, "stub". Od
usare keywords particolari per non confondersi:
 
	incomplete class Pippo {
		mandates integer pluto(string topolino);
	}
 
	[...]
 
	class Minni realizes Pippo {
 
	}
 
	## ERROR: class 'Minni' at line 5 of file minni.lulz must implement
		method pluto(), mandated by incomplete class Pippo at line
		1 of file pippo.lulz
	## Aborting compilation of class Minni
 
...ma tutto sommato 'funzione abstract' mi pare un compromesso accettabile.
 
Leonardo
 
-- 
Were I Glenallan's Earl this tide, and were you Roland Cheyne,
My spur would be in my horse's side, the bridle upon his mane.
If they hae twenty thousand blades and we twice ten times ten,
Yet they hae but their tartan plaids, and we're mail-clad men.

 E se esisterebbe a cosa servirebbe?
 
Che cosa accadrebbe se il male si formerebbe dentro di te?
http://www.youtube.com/watch?v=4kNxv3EwfOc
 
 
;-)
 

 Cosa c'entra l'interface?
 
interface sta a class come abstract function sta a function
 
Sono entrambi dichiarazioni delle firme.
Non puoi istanziare una interface come non puoi richiamare una abstract 
function.
 
Bye.

 ...ma tutto sommato 'funzione abstract' mi pare un compromesso accettabile.
 
Sono d'accordo su tutto quello che hai detto, ma ho capito dove vuoi 
arrivare: hai solo ribadito cose già scontate.

 function.
 
Ma posso richiamarne le implementazioni, visto che funzioni definite in 
interfacce, e metodi astratti, alla fine sono fatte proprio per essere 
implementate.
 

 implementate.
 
E` un po' la base del Design By Contract.
Interface e Abstract sono dei modi per definire (molto labilmente, in PHP, 
mancando molti check sui tipi) dei contratti che le classi devono 
rispettare.
 
Ma appunto definiscono una interfaccia (non grafica, di programmazione) 
che deve essere rispettata. Non definiscono il comportamento.
 
Esempio banale: PSR-3 definisce un'interfaccia LoggerInterface:
 
class MyLog implements LoggerInterface
{
 ...
 public function log($level, $message, array $context)
 {
   print "gnegne!";
 }
}
 
Rispetto il contratto (mancano le definizioni di alcune funzioni, ma 
questa è il nodo centrale, è per non scrivere 40 righe tutte uguali), ma 
la mia classe è ben lontana dall'essere un logger utile.
 
Io rispetto il contratto (la firma della funzione), ma nessuno mi obbliga 
a fare qualcosa di più.
 
E soprattutto non viene in nessun modo richiamata la funzione log() di 
LoggerInterface (che è come se fosse abstract)
 
 
Bye.
 
P.S.: Per inciso, togliendo il print, questa classe può essere utile da 
passare, tramite dependency injection, come logger per massimizzare le 
prestazioni di un'applicazione senza dover modificare il sorgente di 
tutta l'app, che si aspetta un logger standardizzato.
 


 
Ma anche volendo, non si potrebbe richiamare: è solo una sorta di 
progetto su carta (una direttiva), non l'effettiva realizzazione.
Una folta che sarà realizzata concretamente, la si potrà tranquillamente 
utilizzare.

 logica del Php, e di altri vari linguaggi OOP.
 
Quindi confermi quello che ho detto: una funzione abstract non può essere 
richiamata.
 

arrivare: hai solo ribadito cose già scontate.
 
Non tutte; rileggendo il thread, mi accorgo ora che ne mancava una.
 
Leonardo tempus satis remedio


 Non tutte; rileggendo il thread, mi accorgo ora che ne mancava una.
 
Non capisco, scusami ma tra una cosa e l'altra ho anche del lavoro da 
portare avanti.
 


 
Bah in parte si, anche se IHMO è più corretto dire che, ne verrà 
richiamata l'implementazione, piuttosto che affermare senza mezzi 
termini, che un metodo abstract non può essere richiamato.