[PHP] CodeIgniter - Visualizzare singolo risultato

Gaz9000

Nuovo Utente
13 Nov 2016
1
0
1
24
Salve a tutti,
da qualche tempo sto cercando di utilizzare CodeIgniter per sviluppare un' applicazione web che ha come scopo quello di mostrare alcuni articoli giornalistici.
Attualmente sono riuscito a estrarre tutti gli articoli presenti all'interno del database che vengono utilizzati come anteprime per il lettore, adesso vorrei riuscire a mostrare ogni singolo articolo separandolo dagli altri.

Tutti gli articoli sono mostrati in /articoli/, vorrei mostrare ogni singolo articolo in /articoli/leggi/id/

Controller:

Codice:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Articoli extends CI_Controller
{
    
    public function index()
    {             
        $this->load->model('articles_model');
        
        $data = array (
                        'titolo' => ' Articoli'
                      );

        $articles_data['data'] = $this->articles_model->select_articles();
    
        $this->load->view('header', $data);
        
        $this->load->view('nav');
        
        $this->load->view('articles-content', $articles_data);
        
        $this->load->view('footer');
        
    }
    
    public function leggi()
    {
        //???????
    }
    
}
Model:

Codice:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Articles_model extends CI_Model
{
    
    public function select_articles()
    {
        $this->db->select('*');
        $this->db->from('articoli');
        $this->db->join('autori', 'articoli.id_autore = autori.id_autore', 'left');
        $this->db->join('immagini', 'articoli.id_immagine = immagini.id_immagine', 'left');
        $query = $this->db->get();
        return $query->result_array();
        
    }
    
}


View:



Codice:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
?>
<div id="content" class="article">
   <div id="articles">
         <?php foreach($data as $row){
         $limited_article = word_limiter($row['testo_articolo'], 200);
      ?>
      <section class="article">
         <h2><?php echo $row['titolo_articolo'];?></h2>
         <img class="article-image" src="<?php echo base_url('/assets/images/' . $row['nome_immagine']) ;?>">
         <p class="info">Autore: <?php echo $row['nome_autore']; ?> Data: <?php echo $row['data_articolo'] ?></p>
         <p><?php echo $limited_article; ?></p>
      </section>
      <?php    }?>
   </div>
</div>
Come posso risolvere? Grazie in anticipo.
 

roberto bandiera

Nuovo Utente
17 Ott 2018
3
0
1
Innanzitutto aggiungi alla pagina della view, che mostra l'elenco degli articoli,
un ancora cliccabile in corrispondenza del titolo dell'articolo,
che richiami la funzione leggi() del Controller

Inoltre, per questioni di leggibilità del codice si consiglia di sostituire tutte
le istruzioni echo con espressioni di visualizzazioni di singole variabili:
PHP:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
?>
<div id="content" class="article">
   <div id="articles">
        <?php foreach($data as $row){
        $limited_article = word_limiter($row['testo_articolo'], 200);
     ?>
     <section class="article">
        <h2>
         <?= anchor('articoli/leggi/'.$row['id_articolo'], $row['titolo_articolo']) ?>
        </h2>
        <img class="article-image" src="<?= base_url('/assets/images/' . $row['nome_immagine']) ?>">
        <p class="info">Autore: <?= $row['nome_autore'] ?> Data: <?= $row['data_articolo'] ?></p>
        <p><?= $limited_article ?></p>
     </section>
     <?php    }?>
   </div>
</div>


poi nel controller scrivi la funzione leggi() con parametro l'id dell'articolo da mostrare

public function leggi($id)
{
 $this->load->model('articles_model');
      
      // si chiama una apposita function del model
       $article_data['data'] = $this->articles_model->select_single_article($id);
 
       $this->load->view('header');
      
       $this->load->view('nav');
      
       $this->load->view('single_article_content', $article_data);
      
       $this->load->view('footer');
}


si aggiunge al model una function che restituisce il dettaglio del singolo articolo
Ritengo che una espressione SQL parametrica sia più leggibile:

 public function select_single_article()
   {
       $query = 'select * from (articoli
                left join autori on articoli.id_autore = autori.id_autore)
                left join immagini on articoli.id_immagine = immagini.id_immagine
                where id_articolo = ?', array($id_articolo));
      // si restituisce una sola riga di dati
      return $query->row_array();
   }

notare che questa funzione ritorna un solo record (una sola riga)

ed infine la pagina della view che visualizza il singolo articolo


single_article_content.php


<?php
defined('BASEPATH') OR exit('No direct script access allowed');
?>
<div id="content" class="article">
     <section class="article">
        <h2>
         <?= $row['titolo_articolo']?>
        </h2>
        <img class="article-image" src="<?= base_url('/assets/images/' . $row['nome_immagine']) ?>">
        <p class="info">Autore: <?= $row['nome_autore'] ?> Data: <?= $row['data_articolo'] ?></p>
        <p><?= $row['testo_articolo'] ?></p>
     </section>
 
</div>

<?= anchor('articoli/index', 'ritorna a elenco degli articoli') ?>

Per ulteriori specificazioni puoi vedere il mio libro su CodeIgniter3.
roberto bandiera
 
Ultima modifica di un moderatore:

macus_adi

Utente Attivo
5 Dic 2017
1.312
88
48
IT/SW
Quoto @roberto bandiera anche se non capisco il motivo di creare un nuovo metodo nel model
select_single_article
, si potrebbe prevedere nel modello sin dall'origine, e utilizzerei un template engine (che preferisco per pulizia di codice) anziché il classico php.
Model
PHP:
public $filter=[];

/**
* Metodo per la risoluzione di qualsiasi richiesta,
*/
public function unique_model_search(ArticoliController $data){
//scriverei un helper per processare i dati o al massimo un hook per gestirli a livello globale
$this->db->select('tupla');
//eventuali join nel caso del dettaglio
foreach($this->filter as $k=>$v){
//naturalmente il caso banale, sarebbe necessario processare il tutto in AND o in OR
/* quindi $this->filter['AND']=[]; $this->filter['OR']=[]; $this->filter['ANDIN']=[] naturalmente ognuno utilizza l'approccio che più gli aggrada.*/
$this->where($k,$v);
}
$data->data_controller=$this->get($tabella)->result_object();
if(count($data->data_controller)==1)$data->details=TRUE;

}
Il model setta i parametri nel controller (in questo caso) per restituire la view corretta.

Nel controller non devi far altro:
PHP:
public $data_controller=[];
public $details=FALSE;

public function __construct(){
parent::__construct();
//da utilizzare se viene implementata la risoluzione degli obj automaticamente
//$this->resolv_object();
}

/**
* Metodo di risoluzione obj processando i dati in input
*/
public function resolv_object(){
}

/**
* metodo d'accesso a quanto richiesto
*/
public function find_actions($id=0){

($id>0)?$this->article_model->filter['AND'][]=['id'=>$id]:null;
$this->article_model->unique_model_search($this);

if($this->details){
//eseguo il rendering dei dati per singolo item
}else{
//eseguo il rendering dei dati per la lista degli item
}
}
Solitamente per comodità ed ereditarietà da altri framework la prima rotta sono solito dichiararla a mano lasciando all'action del controller l'onere di chiamare i metodi corretti, evitando di chiamare esattamente la mappatura del controller + action,
quindi in questo caso semplificato:
PHP:
$route['visualizza/articoli']='controller_articoli/find_actions';
$route['visualizza/articolo/(:num)']='controller_articoli/find_actions/$1';
Evitando la mappatura controller + action si riesce a proteggere meglio l'applicazione.
 
Ultima modifica:

Max 1

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
29 Feb 2012
4.278
330
83
@roberto bandiera
Da regolamento del forum, come tutti noi sei tenuto ad usare il tag
quando posti del codice PHP e il tag
per il codice generico, oppure la funzione codice dalla barra degli strumenti


Inoltre ti prego di leggere attentamente il regolamento generale del forum e quello di sezione dove posti
Grazie
 

roberto bandiera

Nuovo Utente
17 Ott 2018
3
0
1
Concordo pienamente con la nuova versione proposta.
La mia forse risultava più semplice da leggere, tuttavia l'utilizzo di metodi più generali riduce il numero di righe di codice da scrivere.
Le prestazioni del DBMS non credo siano diverse nei due casi.

Per quanto riguarda il marcatore PHP, non sapevo di averlo usato.
Io ho semplicemente fatto un copia incolla dal blocco note.
Roberto Bandiera