• Moderatore

    PHP operatore ternario con più espressioni in sequenza

    Salve a tutti.
    In un sito che dà problemi con la condivisione su Facebook ho visto che i "meta property og: ..." vengono inseriti dal plugin dei commenti social. Spulciando il codice ho incontrato questa riga:

    
    $image = ($this->params->get('default_image', 0)) ? $this->grabImage() : $this->grabImage((isset($row->text)) ? $row->text : $row->introtext);
    
    

    Su php.net c'è un'avvertenza sul comportamento non ovvio quando si usano più espressioni ternarie: php.net/manual/it/language.operators.comparison.php

    Secondo voi il problema può dipendere da questo?
    Proprio perché non è ovvio, non ho capito come devo tradurre l'espressione sopra con if ... else. Suggerimenti?

    Grazie. 🙂


  • ModSenior

    Ciao,
    l'unico svantaggio è appunto che la leggibilità del codice diventa zero.
    Il codice puoi tradurlo ad esempio cosi:

    if($this->params->get('default_image', 0)){
    $a = $this->grabImage();
    }
    else
    {
    $a = $this->grabImage((isset($row->text));
    }

    if($a)
    {
    $image = $row->text;
    }
    else
    {
    $image = $row->introtext;
    }

    Anche se guardando qual'è il valore di default assegnato al primo parametro del metodo grabImage forse si riesce ad eliminare totalmente il primo if.


  • Moderatore

    Ciao Thedarkita,
    grazie per la spiegazione! Intuivo il significato perché sapevo cosa faceva, ma non riuscivo a tradurre la regola. :smile5:

    Intanto penso di avere risolto il problema, che non era nell'operatore ternario.
    Per individuare l'immagine da inserire nel meta tag usava un preg_match e poi controllava se il file esisteva:

    
    preg_match('/< *img[^>]*src *= *["\']?([^"\']*)/i', $text, $matches);
    if (!file_exists($matches[1])) {
            $matches[1] = immagine di default
    }
    
    

    Il problema è che mi piazzava spesso l'immagine di default. Ho notato che questo accadeva quando nel nome del file dell'immagine c'era uno spazio vuoto, che a livello di html veniva tradotto con '%20', ma poi il file non veniva trovato. Ho modificato così:

    
    $matches[1] = str_replace("%20", " ", $matches[1]);
    if (!file_exists($matches[1])) {
            $matches[1] = immagine di default
    }
    
    

    Non so se sia elegante e rigorosa ma sembra funzionare, ma altri suggerimenti sono bene accetti.

    Per completezza, il plugin in questione è jsocial_comments 2.0 per Joomla! 1.7-2.5.

    Francesco


  • ModSenior

    Figurati. 🙂
    Se ti crea problemi solo con quel carattere puoi lasciare cosi senza alcun problema.
    In caso di problemi con altri caratteri come il simbolo + valuta l'utilizzo di funzioni come urldecode invece di str_replace, anche se non credo sia necessario.


  • Moderatore

    Perfetto, grazie ancora Thedarkita. :smile5:


  • User

    Relativamente al problema degli spazi vuoti nei nomi puoi seguire questa discussione nelle pagine del manuale del PHP it1 .php. net/ manual/en/function.urldecode.php#101401 ( togli tu gli spazi che non posso inserire link attivi ) se ho capito il problema dovrebbe fare al caso tuo, comunque sia è un problema di codifica/decodifica della query string di riferimento.
    Se usi una GET per prendere i valori da passare al database ( a dire il vero spero vivamente che tu non faccia una cosa del genere senza parsare la stringa prima ) comunque questi valori saranno codificati secondo **RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax.

    **Ho notato che a volte per eliminare questo problema basta passare le stringhe tra virgolette, che so: image="quanto è bella questa.jpg" ma non sempre funziona, probabilmente dipende da come il browser codifica la stringa prima di inviarla al server.
    Resta comunque il fatto che una verifica sull'esistenza o meno dell'immagine devi comunque farla a meno che questa non risieda in un database, a quel punto basta verificare la query di ritorno, nel tuo caso il collo di bottiglia è senza dubbio la condizione ( che non è un operatore ternario in quanto questo è il costrutto **$risultato = ( espressione ) ? condizione 1 : condizione 2; **ma va be lasciamo stare ) rimane il fatto che usi due istruzioni per il controllo di flusso in luogo di una sola, io fare una cosa alternativa tipo, scrivere una nuova regex che verifichi il nome del file da cercare, compreso anche di codifica, e poi semplicemente verificare la condizione una sola volta.
    Però non chiedermi nulla sulle regex che sono carentissimo 😄