• User Attivo

    Controllare se un offset di un array esiste

    Ciao,
    ho creato un ciclo di questo tipo per sapere qual'e' l'id della entry precedente a quella in questione

    [PHP]
    for($i=$start; $i<$limit; $i++) {
    $id_prev = $id_filmato[($i-1)];
    }
    [/PHP]

    quando ciclo la prima entry mi da l'errore
    "Notice: Undefined offset: 4"
    perchè ovviamente l'offset $i-1 non esiste.

    Esiste un modo per verificare se l'offeset in questione esiste in modo da poter creare una condizione?

    qualcosa del tipo isset($id_filmato[($i-1)])

    grazie

    Giuseppe


  • User Attivo

    A parte il fatto che
    [PHP]isset($id_filmato[($i-1)])[/PHP]
    dovrebbe funzionare, ci puoi spiegare un po' meglio cosa vuoi fare, magari postando più di codice?

    Il loop che fai è un po' strano: hai $start (l'entry attuale?) e poi scorri in avanti partendo da $start - 1 (ovviamente questo vuol dire che la seconda iterazione sarà proprio $start, e poi $start + 1 etc.) per cercare un $id_prev (cioè l'$id precedente a quello identificato con $start) - com'è fatto l'array? E che cosa stai cercando esattamente?

    Ciao!


  • User Attivo

    Funziona 🙂
    a volte la stanchezza fa brutti scherzi...

    Effettivamente non sono molto convinto del codice che sto scrivendo:
    quello che sto cercando di fare è creare un sistema di ordinamento di una lista di entry prese da database, l'ordinamento avviene invertendo il timestamp della entry che si vuole spostare con quello successivo (o precedente), l'id della entry non è necessariamente il seguente perchè alcune potrebbero essere state cancellate o spostate.
    Quindi creo degli array, con le colonne del DB, numerati in modo assoluto (uso $start come i$) e per ogni entry specifico qual'e' l'id della entry precedente e successiva
    [PHP]
    $id_prev = $id_filmato[($i-1)];
    [/PHP]
    poi la passo come parametro a una funzione addetta alla visualizzazione.
    [PHP]
    schedaArchivioSnippet($id_filmato*, $sito*, $video*, $titolo*, $descr*, $data*, $prog, $id_prev, $id_next, $stack_pos, $display);
    [/PHP]

    Ora sto cercando di creare un modo per spostare una entry da una pag all'altra (qualora ci sia paginazione)
    $id_filmato[($i-1)]; riuslta non settato perchè non rientra nel set di entry specificate tra i parametri $start e $step
    pensavo di passare alla funzione una parola chiave tipo "first" e "last" e poi rimandare lo spostamento a un altro script php.

    Di seguito riposti il codice completo.
    Vi sembra corretto? o ci sono altri modi migliori per ottenere lo stesso risultato?

    Grazie

    Giuseppe

    [PHP]

    function showArchivio($id_utente = 1, $step = 5, $current_page = 1, $prog = 0) { //prog = programmazione

    $oggi = mktime(23, 59, 59);
    $domani = mktime(0, 0, 0, date("m"), date("d")+1, date("y"));

    //QUERY n. righe
    if($prog==1) {
        $query = "SELECT * FROM tabella WHERE data >= $domani AND id_utente = $id_utente AND cestino=0;"; 
    } else {
        $query = "SELECT * FROM tabella WHERE data <= $oggi AND id_utente = $id_utente AND cestino=0;"; 
    }    
    $id_risult = mysql_query ($query,$id_conness);
    if(!$id_risult) {die('si &egrave; verificato un errore'.mysql_errno().". ".mysql_error());}
    $nrighe = mysql_num_rows($id_risult);
    
    if($nrighe==0) {return "nessuna entry presente"; die();}
    else if($nrighe<=$step) { //no paginazione..
        $step = $step_buf = $nrighe;
        $start = $start_buf = 0;
        $tot_pages = 1;
    } else { //paginazione
        $tot_pages = ceil($nrighe / $step);
        $start = ($current_page - 1) * $step;
    }
    
    //QUERY restituisce filmati
    if($prog==1) {
        $query = "SELECT * FROM tabella WHERE id_utente = $id_utente AND data >= $domani AND cestino = 0 ORDER BY data ASC, ID DESC LIMIT $start, $step;"; 
    } else {
        $query = "SELECT * FROM tabella WHERE id_utente = $id_utente AND data <= $oggi AND cestino = 0 ORDER BY data DESC, ID DESC LIMIT $start, $step;"; 
    }
    $id_risult = mysql_query ($query,$id_conness);
    if(!$id_risult) {die('si &egrave; verificato un errore'.mysql_errno().". ".mysql_error());}
    
    $snippet = "";
    $i = $start;
    //restituzione righe
    while($messaggio = mysql_fetch_array($id_risult,MYSQL_ASSOC))
    {
        $id_filmato* = $messaggio['id'];
        $sito*= $messaggio['sito'];
        $video* = $messaggio['video'];
        $titolo* = $messaggio['titolo'];
        $descr* = $messaggio['descr'];
        $data* = $messaggio['data'];
        $i++;
    }
    
    $limit = $start+(count($id_filmato));
    for($i=$start; $i<$limit; $i++) { 
            if($i==0) { //non ci sono filmati precedenti
                $id_prev = -1;
            } else {
                if (isset($id_filmato[($i-1)])  ) {
                $id_prev = $id_filmato[($i-1)];
                }
                $id_prev="last";
            }
            if($i==$nrighe || $i==($limit-1)) { //se siamo all'ultima entry della pag o del DB..
                $id_next = -1;
            } else {
                $id_next = $id_filmato[($i+1)];
            }
            $display = 1; 
            $stack_pos = $i;
            $snippet .= schedaArchivioSnippet($id_filmato*, $sito*, $video*, $titolo*, $descr*, $data*, $prog, $id_prev, $id_next, $stack_pos, $display);
    }
    $paginazione = paginazioneSnippet($current_page, $tot_pages, $prog);
    $vars = '<p id="current_page" style="display:none;">'.$current_page.'</p>';
    

    return $paginazione.$snippet.$paginazione.$vars;
    }
    [/PHP]


  • User Attivo

    [Premetto che non ho capito al 100% quello che vuoi fare, quindi non starmi a sentire se ti accorgi che dico cose assurde]

    Allora, tu hai timestamp e id dell'attuale video, giusto? E lo vuoi "spostare" (non mi è chiarissimo che vuol dire "spostare" - ipotizziamo che tu intenda "scambiare il timestamp" con un'altra entry), giusto? Non puoi semplicemente utilizzare la timestamp (anche se un po' rischioso, eh!) come id univoco e swappare le due timestamp?

    Per ottenere l'id del video con la timestamp precedente fai un:

    SELECT id, data FROM tabella WHERE data < *timestamp_video_attuale* ORDER BY data DESC LIMIT 0, 1
    

    e poi fai lo swap delle tue timestamp

    UPDATE tabella SET data = timestamp_video_attuale WHERE id = id_video_precedente (restituito dalla query di prima)
    UPDATE tabella SET data = timestamp_restituito_query_di_prima WHERE id = id_video_attuale
    

    Due cose:

    • si potrebbe fare con una subquery ma diventa un po' più complicato, se ho tempo me la studio, però
    • utilizzare la timestamp non è una grande idea, suggerirei un campo "ordine" INT univoco

    HTH, ciao!


  • User Attivo

    Hai capito perfettamente!
    per spostare intendo scambiare d'ordine, le entry sono ordinate per timestamp e per id
    l'id e' il classico campo univoco con autoincrement, preferisco usare questo per identificare le entry

    l'idea di usare una select specificando il timestamp per ricavare la precedente entry mi sembra buona, ed e' anche molto semplice
    ma non e' troppo dispendioso in termini di risorse avere 3 chiamate al DB per ogni spostamento?
    fornendo l'id dall'array risparmio una chiamata ed evito i rischi di usare il timestamp come valore univoco..

    forse l'idea di usare un campo ordine univoco e' la migliore ma dovrei comunque incrociarla con il timestamp per sapere da quale data la entry e' visibile (per offrire la possibilita' di postdatare le entry)

    Grazie

    Giuseppe


  • User Attivo

    Nel codice che hai postato c'erano due query SELECT, nel mio solo una (gli UPDATE ti servono sia in un caso che nell'altro) - in ogni caso sono operazioni atomiche e non dovrebbero appesantire troppo il sistema (quante di queste operazioni pensi di fare al minuto?)

    A pensarci bene l'alternativa delle subquery non è praticabile - almeno penso...

    Se usi un campo univoco per l'ordine (che crei al momento dell'inserimento nel db del filmato) non hai più bisogno della timestamp quando vuoi "spostare" dei filmanti (ovviamente nella visualizzazione della lista è un'altra cosa, la timestamp ti serve ma parliamo d'altro...)

    HTH, ciao! 🙂