Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 30
  1. #1

    [PILLOLA] [AJAX] Framework Invii Simultanei e Temporizzati

    Framework Ajax per AGGIORNAMENTI di CONTENUTI tramite richieste simultantee e temporizzate

    so bene che esistono a decine di framework javascript-ajax e di soluzioni da voi sviluppate,
    cercando su google ed leggendo le guide di html.it c'è veramente di tutto,
    tuttavia ho sempre timore nell'applicare pacchetti di codice alla cieca,
    sia perchè non ho il controllo della situazione, sia perchè di solito a me serve il 10% delle loro potenzialità quindi causerei appesantimenti in kb inutili

    è così che con l'aiuto di:
    - l'ottima guida di Html.it
    - il curioso esempio di Handling Multiple XMLHTTPRequest Objects

    ho prodotto una mia soluzione, che ho deciso di condividere con voi
    impegnandomi a migliorarla sotto i vostri consigli


    Uso
    UpdtAjaxRqstInsr (Cosa,ConCosa [,AttesaMassima [,TraQuanto [,QuanteVolte [,OgniQuanto]]]]);
    parametri obbligatori:
    Cosa= nome del tag in cui inserire il risultato
    ConCosa= url completo e assoluto da caricare

    parametri opzionali del timing:
    AttesaMassima= secondi di massima attesa, oltre i quali chiude la richiesta
    TraQuanto= secondi di attesa prima di inviare la richiesta
    QuanteVolte= numero di volte che voglio sia ripetuta la richiesta
    OgniQuanto= secondo di attesa tra il termine di una richiesta e la ripetizione successiva


    Funzionalità
    - c'è la verifica del supporto ajax da parte del browser: se non supportato restituisce true in modo da attivare l'eventuale <A> da cui parte la richiesta
    - nel tag di destinazione viene caricata una immagine di loading
    - click multipli metteranno in coda più richieste identiche (ma bisogna essere scemi perchè il loading compare), prevedere una disabilitazione del bottone che ha inviato la richiesta credo che vincoli nell'uso di un tag preciso, invece voglio che sia tutto libero
    - prevede un monitoraggio delle attività per le modalità di debugging: un div fa da logger delle richieste inviate al server, ed un altro mostra la coda di attesa contenuta nell'array
    - le richieste possono esser effettuate col metodo Post e Get in contemporanea, è sufficiente usare un url con la query string già impostata, ed eventualmente il parametro Cosa per passare una variabile via get ...è chiaro che quest'ultima riga di codice dovete personalizzarla, poichè la mia soluzione è ad hoc per le mie esigenze: io indico al server con Cosa come personalizzare l'output

    Logica di Funzionamento
    Uso una Array per accodare tutte le richieste ajax da eseguire, dove il campo Stato contiene 1 se la richiesta è aperta, ed il campo Quando contiente l'ora programmata per l'esecuzione della richiesta.
    Tramite la funzione UpdtAjaxRqstInsr(...) inserisco una richiesta nell'array e avvio i cicli di controllo delle richieste, che periodicamente ogni secondo vengono eseguite dalla funzione UpdtAjaxRqstChck, che controlla il timing ed effettua le richieste ajax tramite la funzione UpdtAjaxRqstSend


    Note di Programmazione
    - le variabili hanno nomi con parole sintetizzate dalle prime 4 consonanti
    - sicuramente la sintassi può essere ampiamente ottimizzata, aspetto vostri consigli
    - mi si poneva il problema che se nello stesso istante la 1^ e 2^ funzione fossero eseguite in contemporanea avrebbe funzionato male poichè 1 leggeva ed 1 scriveva sullo stesso array, per questo ho creato 1 variabile che permettesse alla prima funzione di posticiparsi di 0,1sec qualora la seconda funzione fosse in funzione


    Cosa dovete personalizzare
    - Path e Nome dell'immagine di loading
    - Parametri di timing di default (se vi va)
    - l'uso della variabile passata tramite metodo post


    Codice PHP:
    function UpdtAjaxRqstInsr (Cosa,ConCosa,AttesaMassima,TraQuanto,QuanteVolte,OgniQuanto) {
        
    // VERIFICHE PRELIMINARI: se altre funzioni stanno lavorando sull'array, temporeggio 0,1sec
        
    if(typeof(UpdtAjaxRqstChckStts)=='undefined'UpdtAjaxRqstChckStts=0; else if (UpdtAjaxRqstChckStts==1) { setTimeout('UpdtAjaxRqstInsr (Cosa,ConCosa,AttesaMassima,TraQuanto,QuanteVolte,OgniQuanto);',100); return false; }
        
    // VERIFICHE PRELIMINARI: controllo variabili tempo; l'input è in secondi, convertito poi in millisecondi
        
    if(!AttesaMassima)    AttesaMassima=15000;    else    AttesaMassima*=1000;
        if(!
    TraQuanto)            TraQuanto=0;                    else    TraQuanto*=1000;
        if(!
    QuanteVolte)        QuanteVolte=1;
        if(!
    OgniQuanto)            OgniQuanto=0;                    else    OgniQuanto*=1000;
        
    // VERIFICHE PRELIMINARI: Supportato = dice se Ajax è supportato dal browser e determina il return per link di origine: se false funzionerà il tag <A>
        
    UpdtAjaxRqstSppr=false
        
    browserUtente navigator.userAgent.toUpperCase();
        if(
    typeof(XMLHttpRequest) === "function" || typeof(XMLHttpRequest) === "object")    UpdtAjaxRqstSppr=true;
        else if(
    window.ActiveXObject && browserUtente.indexOf("MSIE 4") < 0)        UpdtAjaxRqstSppr=true;
        
    // EXE: se c'è supporto ajax allora accoda richiesta e verifico che i controlli dell'handler siano attivi
        
    if(UpdtAjaxRqstSppr==true){
            
    //piazza il loading nel div
            
    document.getElementById(Cosa).innerHTML='[img]Loading.gif[/img]';    
            
    //se non c'è l'handler lo creo
            
    if(typeof(UpdtAjaxRqstList)=='undefined'UpdtAjaxRqstList = new Array;
            
    //accoda all'handler
            
    dataChiamata=new Date(), Quando=dataChiamata.getTime()+TraQuanto;
            
    i=UpdtAjaxRqstList.length
            UpdtAjaxRqstList
    [i]= new Array;
            
    UpdtAjaxRqstList[i]['Stato']=0;
            
    UpdtAjaxRqstList[i]['Cosa']=Cosa;
            
    UpdtAjaxRqstList[i]['ConCosa']=ConCosa;
            
    UpdtAjaxRqstList[i]['Quando']=Quando;
            
    UpdtAjaxRqstList[i]['QuanteVolte']=QuanteVolte;
            
    UpdtAjaxRqstList[i]['OgniQuanto']=OgniQuanto;
            
    UpdtAjaxRqstList[i]['AttesaMassima']=AttesaMassima;
            
    //attiva l'esecuzione dell'handler
            
    if(typeof(UpdtAjaxRqstChckIdnt)=='undefined'UpdtAjaxRqstChckIdnt='';
            if(!
    UpdtAjaxRqstChckIdnt  || UpdtAjaxRqstChckIdnt==''){
                
    setTimeout('UpdtAjaxRqstChck()',0); //altrimenti abbiamo il primo secondo di pausa, poichè set interval (che al caso nostro) parte dopo la pausa
                
    UpdtAjaxRqstChckIdnt=setInterval('UpdtAjaxRqstChck()',1000);
                }
            return 
    false;
        }else{
            return 
    true;
        }
    }



    function 
    UpdtAjaxRqstChck() {
        
    UpdtAjaxRqstStby=0;             // Standby = dice se c'è ancora qualcosa sul fuoco, ovvero di volta in volta se ci sono richieste aperte e/o da eseguire ancora
        
    UpdtAjaxRqstChckStts=1;     // Check Status = 1 significa che questa funzione è in esecuzione e quindi non si può toccare l'array, alla fine tornerà 0
        // verifico a che punto è l'eventuale richiesta aperta
        // posiziona la richiesta con Stato=1 al primo posto
        
    UpdtAjaxRqstList.sort(function(a,b){return a.Stato<b.Stato});
        if(
    UpdtAjaxRqstList[0]['Stato']==1){
            
    // se ha finito pubblico
            
    if(UpdtAjaxRqst.readyState === 4){
                if(
    UpdtAjaxRqst.status == 200)
                    
    document.getElementById(UpdtAjaxRqstList[0]['Cosa']).innerHTMLUpdtAjaxRqst.responseText;
                else
                    
    document.getElementById(UpdtAjaxRqstList[0]['Cosa']).innerHTML'Richiesta Fallita. Riprova.';
                
    UpdtAjaxRqstList[0]['QuanteVolte']--;
                if(
    UpdtAjaxRqstList[0]['QuanteVolte']>0){
                    
    UpdtAjaxRqstList[0]['Quando']+= UpdtAjaxRqstList[0]['OgniQuanto'];
                    
    UpdtAjaxRqstList[0]['Stato']=0;
                
    // tolgo la riga
                
    } else UpdtAjaxRqstList.splice(0,1);

            
    // se non ha finito verifico il tempo
            
    }else{
                var 
    data=new Date(), data=data.getTime();
                if(
    UpdtAjaxRqstList[0]['AttesaMassima'] > data-UpdtAjaxRqstList[0]['Quando']) UpdtAjaxRqstStby=1;
                else{    
    document.getElementById(UpdtAjaxRqstList[0]['Cosa']).innerHTML'Richiesta Scaduta. Riprova.';
                    
    UpdtAjaxRqstList[0]['QuanteVolte']--;
                    if(
    UpdtAjaxRqstList[0]['QuanteVolte']>0){
                        
    UpdtAjaxRqstList[0]['Quando']+= UpdtAjaxRqstList[0]['OgniQuanto'];
                        
    UpdtAjaxRqstList[0]['Stato']=0;
                        
    // tolgo la riga
                        
    } else UpdtAjaxRqstList.splice(0,1);
                    }
            }
        }

        
    // verifico l'eventuali righe ferme se non ce ne sono di aperte
        
    if(UpdtAjaxRqstStby==&& UpdtAjaxRqstList.length>0){
            
    UpdtAjaxRqstStby=1;
            
    // posiziona le richieste in ordine cronologico
            
    UpdtAjaxRqstList.sort(function(a,b){return a.Quando>b.Quando});
            var 
    data=new Date(), data=data.getTime();
            if(
    UpdtAjaxRqstList[0]['Quando']<data){
                
    UpdtAjaxRqstList[0]['Stato']=1;
                
    UpdtAjaxRqstList[0]['Quando']=data;
                
    UpdtAjaxRqstSend (UpdtAjaxRqstList[0]['Cosa'], UpdtAjaxRqstList[0]['ConCosa']);
                }
        }

        
    //aggiorna status ajax-debugger
        
    var codice='';
        for(var 
    i=0;i<UpdtAjaxRqstList.length;i++)
            
    codice+=
            
    'Stato='+UpdtAjaxRqstList[i]['Stato']+
            
    ' Quando='+UpdtAjaxRqstList[i]['Quando']+
            
    ' QuanteVolte='+UpdtAjaxRqstList[i]['QuanteVolte']+
            
    ' OgniQuanto='+UpdtAjaxRqstList[i]['OgniQuanto']+
            
    ' AttesaMassima='+UpdtAjaxRqstList[i]['AttesaMassima']+
            
    ' Cosa='+UpdtAjaxRqstList[i]['Cosa']+
            
    ' ConCosa='+UpdtAjaxRqstList[i]['ConCosa']+
            
    '
    '
    ;
        if(
    document.getElementById('AjaxStts')) document.getElementById('AjaxStts').innerHTML=codice;

        
    // se le righe sono finite disattiva il controllo
        
    if(UpdtAjaxRqstStby==0) { clearTimeout(UpdtAjaxRqstChckIdnt); UpdtAjaxRqstChckIdnt=''; }

        
    UpdtAjaxRqstChckStts=0;
    }




    function 
    UpdtAjaxRqstSend(Cosa,ConCosa) {
        
    // assegnazione oggetto ajax, di sicuro supportato se siamo arrivati qui
        
    browserUtente navigator.userAgent.toUpperCase();
        if(
    typeof(XMLHttpRequest) === "function" || typeof(XMLHttpRequest) === "object")
            
    UpdtAjaxRqst = new XMLHttpRequest();
        else if(
    window.ActiveXObject && browserUtente.indexOf("MSIE 4") < 0) {
            
    // se non esiste l'unica possibilità è ActiveX di IE5+
            
    if(browserUtente.indexOf("MSIE 5") < 0UpdtAjaxRqst = new ActiveXObject("Msxml2.XMLHTTP");
            else                 
    UpdtAjaxRqst = new ActiveXObject("Microsoft.XMLHTTP");
            }
        
    UpdtAjaxRqst.open('POST'ConCosatrue);    // impostazione richiesta asincrona in GET del file specificato
        
    UpdtAjaxRqst.setRequestHeader("connection""close");    // rimozione dell'header "connection" come "keep alive"
        
    UpdtAjaxRqst.setRequestHeader("content-type""application/x-www-form-urlencoded");    // necessario per l'invio di variabili con POST
        
    UpdtAjaxRqst.send('ajax='+Cosa);    // invio richiesta
        //aggiorna log ajax-debugger
        
    if(document.getElementById('AjaxLogg')) document.getElementById('SrCmndAjaxLogg').innerHTML+=Cosa+" "+ConCosa+"
    "
    ;

    eventuale box per il debugging:

    Codice PHP:
    _ _ _ _ Ajax Status _ _ _ _<div id="AjaxStts"></div>
    _ _ _ _ Ajax Logger _ _ _ _<div id="AjaxLogg"></div
    allora? ve piaqque?

    :ignore:
    Farmacia di Jarno - le mie pillole: Cookie [#780810], Dom4Php4 [#1123236], Fade [#1139489], getCssProperty [#1152911]
    Inchinatevi difronte al Prof! Nacchio!

    A me pare che l'uomo vada avanti con la retromarcia

  2. #2
    Ciao.

    Che bisogno c'è di fare 'multiple simultaneous requests' l'utilizzo di Ajax lo vedo collegato ad eventi
    quindi risolverei il problema in fase di progettazione
    per essere + chiaro se devi fare 'multiple simultaneous requests' hai sbagliato qc no ?


    Without faith, nothing is possible. With it, nothing is impossible
    http://ilwebdifabio.it

  3. #3
    ciao,

    eventi
    che tutto questo possa esser risolto in modo più evoluto attraverso la manipolazione degli eventi ne sono quasi certo, una cosa del tipo questo ma non è ancora un livello di scrittura alla mia portata

    multiple simultaneous requests
    cioè? non ne comprendi l'utilità? o credi che mi sia complicato la vita in questo modo? io avevo bisogno con 1 click di aggiornare 3 div con 3 contenuti divesi, e so che 3 richieste simultanee non possono esser fatte...

    ho capito bene il tuo intervento? :master:
    Farmacia di Jarno - le mie pillole: Cookie [#780810], Dom4Php4 [#1123236], Fade [#1139489], getCssProperty [#1152911]
    Inchinatevi difronte al Prof! Nacchio!

    A me pare che l'uomo vada avanti con la retromarcia

  4. #4
    Originariamente inviato da Jarno
    ciao,

    multiple simultaneous requests
    cioè? non ne comprendi l'utilità? o credi che mi sia complicato la vita in questo modo? io avevo bisogno con 1 click di aggiornare 3 div con 3 contenuti divesi, e so che 3 richieste simultanee non possono esser fatte...

    ho capito bene il tuo intervento? :master:
    Si capito benessimo

    Come la vedo io con il click passi uno o + paremetri
    alla request
    e a seconda dei parametri passati aggiorni gli n div
    secondo me si può fare con una singola request.

    Without faith, nothing is possible. With it, nothing is impossible
    http://ilwebdifabio.it

  5. #5
    ma se gli URL sono diversi come fai? te parti dal presupposto che richiamo un singolo url e dal risultato estrapolo i 3 diversi div che mi interessano? ma così è una soluzione molto limitata a questo caso, non flessibile, no?

    e poi tieni di conto che qui si gestisce allo stesso tempo anche i request temporizzati... quindi che tu voglia o no credo che 1 array ti tocca usarla
    Farmacia di Jarno - le mie pillole: Cookie [#780810], Dom4Php4 [#1123236], Fade [#1139489], getCssProperty [#1152911]
    Inchinatevi difronte al Prof! Nacchio!

    A me pare che l'uomo vada avanti con la retromarcia

  6. #6
    Trovo sempre nobile il fatto di voler aiutare gli altri perdendo tempo a scrivere pillole, quindi inizio questa risposta dicendoti grazie per il post.

    Se mi è possibile vorrei anche commentarlo in quelle parti che reputo siano abbastanza discutibili.

    In primo luogo hai l'abitudine, ricordando anche altri interventi, di scordarti di inizializzare le variabili locali con il var davanti.

    In questo caso una i, ed altre ancora ... abbastanza fastidioso, rischioso e poco stabile se ci sono altri script che commettono lo stesso errore ... e purtroppo ce ne sono, rischi di creare loop infiniti, non ricevere risultati attesi o altro ancora, ma questa è un'altra storia.

    Quella che riguarda questo post invece mi sembra sia altrettanto sconsigliabile e se la mia guida ha contribuito a darti questi spunti significa che l'ho scritta male.

    Ci sono infatti dei capitoli inerenti l'abuso di Ajax, lo stress per il server, ed altro ancora e son sicuro di non aver mai assolutamente consigliato di fare 3 chiamate asincrone per un solo onclick.

    Come ti ha fatto giustamente notare whisher c'è qualcosa che non va a monte della progettazione perchè Ajax è un canale e fare 3 richieste per un link è equivalente ad aprire una pagina web che siccome ha 3 divs diversi ti costringe ad aprirne 3 di pagine facendo 3 richieste differenti e simultanee al server e creando non poca confusione all'utente.

    Come ho detto in un altro articolo, probabilmente meno letto della guida, sviluppare Ajax richiede assolutamente competenze server e non va usato solo perchè è una moda.

    Certo è che ognuno poi sfrutta quello che sa come meglio crede, quindi sei libero di intasare il server, fare 3 chiamate ogni secondo o altro ancora, ma altrettanto certo è che fare richieste simultanee e multiple con Ajax non è una buona pratica, da evitare invece come la peste o come arrivano più utenti nel servizio il rischio è che tutto diventi lento e per tutti, con la peggiore delle ipotesi: blocco totale o server down.

    Una struttura server sviluppata per Ajax deve essere in grado di fornire con una sola chiamata tutte le informazioni necessarie per quella chiamata, quindi anche in questo caso whisher ha più che ragione, il server deve restituire ciò che gli viene chiesto in modo tale da permettere al client di richiedere più di una sola informazione.

    Per quel che riguarda invece le richieste temporizzate, i casi dove queste possono essere utile non sono pochi ma che il tempo sia di almeno un minuto, le richieste ridotte al minimo indispensabile (e si torna al discorso della buona progettazione server-side) e, nel solo caso di una chat, che le informazioni siano poche ed i tempi siano di minimo 1 secondo e mezzo (meglio 2 e mezzo) per ogni update del canale.

    Questi sono consigli personali, sicuramente opinabili, dati da uno che 8 anni fa sviluppava chat in Flash che da 10 anni sfrutta quello che oggi chiamiamo Ajax ... e che con lo stesso, ha già affrontato il discorso chat come siti o applicativi.

    Per concludere spero che questi consigli siano utili per migliorare ancora il buon lavoro che stai comunque facendo, anche dando contributi a questa comunità http://javascript.html.it/articoli/l...muni-con-ajax/
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  7. #7
    Utente di HTML.it L'avatar di pietro09
    Registrato dal
    Jan 2002
    Messaggi
    10,116
    Sinceramente non credo proprio di aver capito lo spirito di questo post, e penso davvero che mi sono completamente fuso il cervello da non capire queste famose chiamate contemporanee

    Dalle mie parti, si usa fare una sola chiamata per più risposte. La cosa viene fatta nel modo più banale con una stringa delimitata; oppure con una stringa in formato json; oppure con una stringa xml.

    E se gli url sono diversi? :berto: supponendo che A faccia la parte client e B faccia la parte server, è ovvio che A e B si debbono mettere daccordo e stipulare un contratto. A dice a B cosa vuole e in che formato, e B dice ad A i parametri da passare.



    "soluzione molto limitata e non flessibile": fammi un esempio concreto di soluzione limitata e non flessibile con una sola chiamata e più risposte
    Pietro

  8. #8
    ho deciso di pubblicare il codice proprio nella speranza di avere interventi come questi, quindi dico grazie a voi... e poi non sapevo che "andr3a" fosse l'autore degli articoli e guide che vedo per il web ...wow che onore

    LA RAZIO DEL CODICE
    andr3a
    sono pienamente d'accordo con quello che dici, ma te stai giudicando il potenziale uso del codice, non il codice e la sua struttura. E' come la storia della pistola, io l'ho prodotta, ma non ti ho mica detto di farci la strage al supermercato. Io non ho promosso l'abuso di ajax, e sto bene attento a non farlo.

    Questa deve essere solo 1 funzione che mi permetta gestire alcuni problemucci legati ad ajax e che non ho trovato sempre risposta nelle altre soluzioni già presenti; nello specifico:
    - il fatto che le richieste immediatamente successive cancellano quelle ancora non concluse (per similitudine è un po' come il problema dei document.onload assegnati da più parti del documento)
    - il timing delle richieste ...che non mi pare sia gestita in modo così completo da nessuna soluzione
    - monitor di debug lato client


    whisher
    credo di aver capito il vostro approccio: se voglio aggiornare 3 div in 1 pagina, non devo fare 3 richieste ma 1 sola in cui organizzo l'output in 3 pacchetti che poi andranno ricollocati dal lato client, tutto questo perchè ottimizza il traffico client-server ...giustissimo, aspetto che non ho preso in considerazione perchè non mi interessava (e poi perchè alla peggio avrei risolto effettivamente con 3 richieste) ma potrebbe essere l'ulteriore sviluppo

    Mi sa che voi vi siete immaginati che io voglia caricare 1 pagina a colpi di micro aggiornamenti dei singoli div... traqui, sta fesseria non mi è minimamente passata per la mente. Ma questo non è un errore del framework ajax, ma di chi imposta la richiesta ajax ed organizza la risposta lato server !!! quindi che c'entra questa critica con il codice?

    ESEMPI DI UTILIZZO
    - come nei siti di trading, l'utente di trova davanti una piattaforma di interazione col server ...e se l'utente effettua 2 click su 2 bottoni diversi, ognuno specializzato per uno specifico aggiornamento che gli devo rispondere io? "no...aspetta che non ho ancora finito" ?


    CORREZIONE CODICE
    ho corretto già diverse cosette, se la cosa va avanti pubblicherò le nuove version

    andr3a
    giustissima l'osservazione sull'inizializzazione delle variabili, ma credo di aver fatto qui nel modo giusto, le variabili non locali sono volutamente così, in più hanno un nome specifico ed univoco e non generico come fanno tutti


    SVILUPPO DEL CODICE
    pietro09: stringa Json, Xml, ..
    giusto, confermo quanto detto sopra, potrebbe essere l'ulteriore sviluppo: convogliare più div di aggiornaento in un unica richiesta
    Farmacia di Jarno - le mie pillole: Cookie [#780810], Dom4Php4 [#1123236], Fade [#1139489], getCssProperty [#1152911]
    Inchinatevi difronte al Prof! Nacchio!

    A me pare che l'uomo vada avanti con la retromarcia

  9. #9
    Utente di HTML.it L'avatar di pietro09
    Registrato dal
    Jan 2002
    Messaggi
    10,116
    :master: non so; è come se ci fosse un errore di fondo, sia concettuale, sia di codice.
    In fondo, senza scomodare siti di trading (che ahimè non so proprio cosa siano), credo che basti fare una paginetta con due pulsanti e due div per le risposte.
    La procedura server basta farle onerose in termini di tempo artificialmente, per esempio una decina di secondi. Dalle prove che ho fatto, cliccando sui due pulsanti, si fanno due richieste ajax diverse, le quali fanno il loro dovere aggiornando i due div.
    E non capisco proprio dove stia il problema

    ps. guarda che non si tratta di polemica, ma giusto desiderio di capire altre posizioni diverse dalle mie. Ciao
    Pietro

  10. #10
    ... effettivamente anche a me sfugge la problematica delle due richieste ... cioè, se si usano 2 oggetti XHR diversi non ho mai avuto mezzo problema :master:

    (se invece si dimentica un var e si usa sempre la stessa variabile è logico che vengono fuori problemi ... scherzo, ma magari incappavi in questa probematica e non in altre )
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.