Territorio, storia, cultura: conoscere le risorse che hai sotto casa con GLOCAL Web-App. Come mettere in moto un progetto con Codeigniter, terza puntata

Glocal alle prese ancora con la parte statica

Il link del progetto in working progress
http://umbriawayformazione.altervista.org/ci_project_glocal/

Riassunto delle puntate precedenti

All’ indirizzo https://umbriawayinfo.wordpress.com/2021/03/06/territorio-storia-cultura-conoscere-le-risorse-che-hai-sotto-casa-con-glocal-web-app-come-mettere-in-moto-un-progetto-con-codeigniter-seconda-puntata/ abbiamo visto nella seconda puntata come sistemare un template adesso dobbiamo soddisfare le nostre curiosità legate alla parte statica.

Problem Solving

Quindi seguendo le modalità espresse dall’ articolo io posso agganciare qualsiasi altra pagina oltre alla index? Anche se ho per le mani una Ferrari (codeigniter framework) in questo momento desideriamo capire se almeno ai primordi del suo utilizzo posso almeno assicurare le funzionalità basiche al mio sito linkando pagine semplici statiche

La pratica

Quindi facendo riferimento alla fonte dei template indicata nel primo articolo prendiamo la nostra nuova pagina e la chiamiamo gallery.php con l’idea di vedere se dalla home posso visualizzarla con tanto di foto. Metto quindi il link sulla navbar in alto:

<li>
<a href="http://umbriawayformazione.altervista.org/ci_project_glocal/index.php/ColleNoceraUmbra/photos">Photos</a>
</li>

In questo link seguo la sintassi MVC voluta per convenzione dal fremowork che mi impone di inserire URL BASE seguita dalla index e dal NOME DEL CONTROLLER e dal METODO indicata dalla funzione, quindi sul CONTROLLER aggiungerò una function publica:

public function photos()
{
$this->load->view('gallery');
}

Apriamo una parentesi su come usare i link con codeigniter

Sopra abbiamo usato un link come http://umbriawayformazione.altervista.org/ci_project_glocal/index.php/ColleNoceraUmbra/photos ma è una operazione sacrilega, così non sfruttiamo la potenza del framework. Qui abbiamo a disposizione due modi alternativi per fare le cose ossia:

<a href="<?php echo site_url();?>/ColleNoceraUmbra/photos">Photos</a>

che equivale a:

<a href="http://umbriawayformazione.altervista.org/ci_project_glocal/ColleNoceraUmbra/photos">Photos</a>

e

<a href="<?php echo base_url();?>/index.php/ColleNoceraUmbra/photos">Photos</a> 

che riprende quanto contenuto nel file config.php presente nella cartella config:

$config['base_url'] = 'http://umbriawayformazione.altervista.org/ci_project_glocal/';

e che equivale a:

<a href="http://umbriawayformazione.altervista.org/ci_project_glocal/index.php/ColleNoceraUmbra/photos">Photos</a>

La differenza tra i due metodi consiste che site_url() include anche la pagina index.php mentre base_url() si porta dietro solo quanto memorizzato nella stringa del file config e index.php va aggiunto nel link. IN SOSTANZA usando SITE_URL() non abbiamo necessità di includere la pagina index che viene già catturata di default, mentre non è così per BASE_URL()

La costruzione del template

Per tirare su il template della gallery non facciamo altro che seguire i consigli delle puntate precedenti ma a questo punto ecco sopraggiungere una amara sorpresa: quando andiamo a visualizzare l’URL indicato dal link che porta alla gallery il sistema ci dice che non trova nessuna pagina, indicando proprio il fatto che non esiste.

PANICO ASSOLUTO, come COMBATTERE CONTRO LA STREGONERIA

In informatica succede spesso, ogni tanto qualcosa misteriosamente non funziona, allora come in questo caso vai a vedere in tutti gli angoli del controller e della vista se hai scritto giusto quello che dovevi scrivere o se non hai commesso qualche errore plateale. Hai rispettato le regole di codeigniter, hai aggiunto la nuova pagina al controller senza il MODEL perchè non abbiamo necessità di spedire nessun dato dal DB alla pagina ma anche facendo delle cose semplicissime non c’è verso di vedere nulla!

URL, la funzione che risolve i problemi!

Codeigniter usa delle funzioni contenute negli HELPER (una cartella presente dentro la cartella SYSTEM) per risolvere i problemi, ma se queste funzioni non vengono richiamate siamo al punto di partenza, crederò di essere vittima di un ritò vudù o di un attacco di ipotetici pirati della rete. Ma non è così, semplicemente devi andare sul file autoload.php presente nella cartella config e andare a scrivere in prossimità degli helper settati di default a vuoto:

$autoload['helper'] = array('url', 'form' , 'html', 'file');

in questo caso abbiamo incluso le funzioni url, form, html, file visto che c’eravamo, ossia un set di funzionalità che aiuteranno in futuro a gestire il codice in vari ambiti e non solo sulla gestione degli url. A questo punto portiamo tutto su server via FTP e dovrebbe funzionare tutto, se cliccando sul link della galleria dalla home page finisco di nuovo nel vuoto con errori in cui mi danno la pagina inesistente, significa o che devo aggiornare magari il browser con CTRL + F5 o che forse devo fare altro. In teoria così dovrei vedere tutto ma se proprio voglio essere sicuro richiamo gli helper specifici che mi servono anche dal metodo costruttore della classe del controller che diventa quindi nel nostro caso specifico:

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

class ColleNoceraUmbra extends CI_Controller {

	public function __construct()
	{
		parent::__construct();
		$this->load->helper('url');
	}

	/**
	 * Index Page for this controller.
	 *
	 * Maps to the following URL
	 * 		http://example.com/index.php/welcome
	 *	- or -
	 * 		http://example.com/index.php/welcome/index
	 *	- or -
	 * Since this controller is set as the default controller in
	 * config/routes.php, it's displayed at http://example.com/
	 *
	 * So any other public methods not prefixed with an underscore will
	 * map to /index.php/welcome/<method_name>
	 * @see https://codeigniter.com/user_guide/general/urls.html
	 */
	public function index()
	{
		$this->load->view('index');
	}

	public function photos()
	{
		$this->load->view('gallery');
	}

}

Al momento attuale delle conoscenze acquisite pensiamo che questa sia una sorta di ridondanza ma contro la stregoneria non si sa mai, adesso scrivendo questa ulteriore cosa con il costruttore che prima non c’era rendiamo disponibile la gestione degli URL per tutte le nostre funzioni pubbliche e aggiornando i file sul server davvero andiamo a vedere quello che volevamo vedere, ossia la pagina graficamente colta nella sua lungimirante funzionalità:

Imparare cose nuove

Quando si lavora su un progetto si possono sperimentare dal vivo delle situazioni, nello specifico all’ interno della cartella HELPERS abbiamo creato un file che poi abbiamo richiamato anche nel file autoload.php presente nella cartella config e in questo file abbiamo scritto la famosa dichiarazione iniziale che è un controllo di sicurezza che dice ai contenuti di essere replicabili solo all’ interno della applicazione predefinita seguita da un set di istruzioni che stampano un testo a video e che ha un metodo che possiamo richiamare:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

if ( ! function_exists('test_method'))
{
    function test_method($var = '')
    {
        return $var;
    }
}

A questo punto abbiamo aggiunto l’helpers anche nel costruttore del controller e provato a stampare qualcosa:

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

class ColleNoceraUmbra extends CI_Controller {

	public function __construct()
	{
		parent::__construct();
		$this->load->helper('url','fwd_helper');
	}

	/**
	 * Index Page for this controller.
	 *
	 * Maps to the following URL
	 * 		http://example.com/index.php/welcome
	 *	- or -
	 * 		http://example.com/index.php/welcome/index
	 *	- or -
	 * Since this controller is set as the default controller in
	 * config/routes.php, it's displayed at http://example.com/
	 *
	 * So any other public methods not prefixed with an underscore will
	 * map to /index.php/welcome/<method_name>
	 * @see https://codeigniter.com/user_guide/general/urls.html
	 */
	public function index()
	{
		$this->load->view('index');
		echo test_method('Hello World');
	}

	public function photos()
	{
		$this->load->view('gallery');
	}

}
helpers personalizzati

e vediamo l’effetto che fa, in questo modo ci rendiamo anche conto di quanto possiamo essere versatili nel personalizzare le nostre WEB APP costruendo delle funzioni personalizzate! Gli helper sono all’ inizio cercati dentro il path system/helpers se non vengono trovati vanno a prelevarli da dentro il path application/helpers. Dentro questa cartella possiamo anche sovrascrivere gli helpers di sistema aggiungendo nuovi funzioni semplicemente facendo una copia del file e inserendo all’ inizio il prefisso MY_seguitodanomefileinteresse; Il prefisso si può cambiare e personalizzare nel file config.php nel parametro:

$config['subclass_prefix'] = 'MY_';

Il discorso sugli helpers sarebbe riduttivo sbolognarlo con queste poche coordinate e anzi questi brandelli di informazione da approfondire stanno ad indicare la complessità di un mondo complesso e labirintico quale è Codeigniter!

Conclusioni

A questo punto abbiamo un cancello base come http://umbriawayformazione.altervista.org/ci_project_glocal/ e anche un modulo gallery a parte accessibile dalla home che é http://umbriawayformazione.altervista.org/ci_project_glocal/index.php/ColleNoceraUmbra/photos a questo punto dobbiamo interrogarci seriamente a che cosa serva una gallery statica fatta in questa maniera, ossia senza caratteristiche dinamiche che vengono offerte da codeigniter e che non stiamo sfruttando (non è meglio gestire tutto con un DB?)

Area riservata semplice in PHP senza il supporto di database per memorizzare i dati

All’ indirizzo https://www.oggieunaltropost.it/2016/10/come-creare-un-area-riservata-con-il-php-senza-database.html vi è un interessante articolo che semplifica le operazioni sull’ allestimento di una ipotetica area riservata, l’applicazione pratica di questo insieme di file si può vedere all’ indirizzo http://umbriawayformazione.altervista.org/php_project_dragon/ dove non si vuole dare accesso a tutto gli utenti a “contenuti pseudoriservati”, magari rivolti a un ipotetico editore e si dà invece l’opzione di entrare nei contenuti solo dopo aver effettuato il login. Di fatto quindi ho clonato la index per togliere l’alert in prima pagina con l’accesso di login costruito prendendo il codice su https://www.w3schools.com/, con la sua stilizzazione CSS, dopodichè ho tolto i veti dal link che trasmette per ogni immagine il suo contenuto corrispondente passando dinamicamente un id tramite metodo GET. quindi la home.php è una delle pagine che servono e le altre due sono LOGIN.PHP e VERIFICA.PHP , quest’ ultimo deve essere inserito nelle pagine con i contenuti da proteggere. Vediamo come l’autore dell’ articolo riempe di contenuti la home.php (che nell’articolo è riconoscibile come index.php) che ovviamente nel mio caso sarà più articolata:

file home.php (con contenuti aggiuntivi se è il caso per la grafica del cms)

<?php include("verifica.php");?>
<html>
<head>
    <title>Area riservata</title>
</head>
<body>
Questo contenuto lo vedi solo da loggato!
<br />
<a href="login.php">Logout</a>
</body>
</html>

file verifica.php

<?php
    session_start();
    if(trim($_SESSION["collegato"])!="si")
    {
        header("location: login.php");
        die("...Attendere, prego...");
    }
?>

file login.php

<?php
    session_start();
    unset($_SESSION["collegato"]);
    $user=trim($_POST["username"]);
    $pwd=trim($_POST["password"]);
    $mex="";
    if($user!=""&&$pwd!="")
    {
        if ($user=="ciccio"&&$pwd=="bello")
        {
            $_SESSION["collegato"]="si";
            header("location: home.php");
            die("...Attendere, prego...");
        }
        else $mex="<br />Errore: Username o Password errate!<br /> <br />";
    }
?>
<html>
<head>
    <title>Area riservata</title>
</head>
<body>
<strong>Login</strong>
<br />
<?php if($mex!="") echo $mex;?>
<form method="post" action="login.php" enctype="multipart/form-data">
Username: <input type="Text" name="username" maxlength="20" size="10" />
<br />
Password: <input type="Password" name="password" maxlength="20" size="10" />
<br />
<input type="Submit" value="Entra" />
</form>
</body>
</html>

In questo caso il file di logout coincide con la stessa pagina login.php che fa l’unset($_SESSION[“collegato”]) , ossia lo svuotamento delle variabili di sessione, ma che fare se siamo di fronte a una esigenza diversa? Posso creare un file logout.php e inserire il seguente codice:

<?php 
session_start();

// cancello tutti i dati di sessione
$_SESSION = array();

// Cancelliamo l'eventuale cookie di sessione
if (isset($_COOKIE[session_name()]))
{
   setcookie(session_name(), '', time()-42000, '/');
}

// distruggiamo la sessione
session_destroy();

//reindirizzo
header("location: index.php");
?>

e infine il file della home.php diventerebbe per uscire dalle sessioni e tornare alla base:

<a href="logout.php">Logout</a>

Il file presentato da https://www.oggieunaltropost.it/2016/10/come-creare-un-area-riservata-con-il-php-senza-database.html è solo una variante rispetto al tema vasto delle aree protette, in questo caso senza login che si appoggia a un database. L’inconveniente di questi sistemi sono legati al fatto che le pwd sono comunque scritte all’ interno del codice PHP mentre andrebbero tutelate e protette in modo maggiormente sicuro. Tuttavia quando non c’è un grado di riservatezza eccessiva e scrupolosa, non ci sono dati sensibili che possono provocare danni a cose o a persone da prelevare, il sistema è assolutamente funzionale, come è il caso di http://umbriawayformazione.altervista.org/php_project_dragon/index.php

L’apertura del secondo fronte come strategia a supporto del web developer, quando la trascendenza non arriva e i problemi di sviluppo continuano a rimanere in sospeso: conquistare la vetta per riorganizzare l’attacco, analisi di un search engine in PHP procedurale!

Negli scacchi la strategia di aprire un secondo fronte nelle operazioni di attacco, quando abbiamo un vantaggio acquisito magari su lato opposto ma non basta per vincere la partita, è una soluzione spesso ok per portare a casa il punto. Quando si inizia con CI Framework non si hanno tutte le risposte e quindi l’unica filosofia che si può perseguire è quella di scomporre i problemi in problemi più piccoli e anche di studiare gli esempi perché far funzionare tutto e subito non è alla portata del NEWBIE!


Quando un problema come nel mio caso attende una risposta trascendente sull’operatore LIKE in MVC che al momento non arriva, tutto quello che si può fare é non perdere l’allenamento con CI e cimentarsi comunque a percorsi indiretti CHE APPARENTEMENTE PORTANO LONTANO DA UNA SOLUZIONE. Ad esempio vediamo come realizzare nel procedurale una soluzione come un search engine che al momento traslato su CI non mi funziona. Un motore di ricerca interno per il mio western Movie è indispensabile ma al momento deve mancarmi qualche info tecnica su come mettere in moto la dinamica di funzionamento. Almeno avere le idee chiare nel prcedurale! Immaginiamo quindi di volere tirare su un search engine che cerca solo info legate alle birre, come fare? Abbiamo la nostra pagina statica come index o piattaforma di lancio o di ricerca dopodiché nel body inseriamo:

<form action="result.php" method="get"> 
<img src="images/logo.png" />
<input type="text" name="user_query" size="80" placeholder="write something to search beer"/> 
<input type="submit" name="search" value="Search Beer Now">
</form>

analizziamo bene i punti critici che sono dopo l’apertura e la conseguente chiusura del tag FORM: action=”result.php” e method=”get” presenti nel form che si preoccupano rispettivamente di inviare i dati compilati dall’ utente a una pagina che farà il lavoro sporco e la specificazione del metodo GET preferito per comodità ma non per specifiche di sicurezza a POST. Il nome del campo testo è molto importante: name=”user_query” così come é molto importante il pulsante identificato come search . Questo FORM spediscei dati alla pagina di elaborazione result.php che recupererà i dati in transito sulla URL con il metodo GET per inserirli in una Query che filtrerà i dati nel database grazie alla clausola WHERE e all’operatore LIKE che fa uso dei caratteri Jolly (%) per supportare alcuni criteri di ricerca. Vediamo quindi come si recuperano intanto i dati:

if(isset($_GET['search'])){
$get_value = $_GET['user_query'];
if($get_value==''){
echo "<center><b>Please go back, and write something in the search box!</b></center>";
exit();
}

Alla riga uno si chiede se l’utente ha spedito qualcosa come dati, se il pacchetto dati ‘search’ è pieno (ISSET) allora setta una variabile di nome get_value che ha come valore la cattura del dato del campo testo! Dopodiché ci sarà una condizione IF – ELSE che dice: se il valore di get_value é vuoto avvisa che devi cercare qualcosa di diverso in wikibeer (nella stringa campo testo) altrimenti procedi con una situazione di TRUE e il codice si sviluppa in questo modo:

$result_query = "select * from tuonometabella where keywords like '%$get_value%'";
$run_result = mysqli_query($conn, $result_query);
if(mysqli_num_rows($run_result)<1){
echo "<center><b>Oops! sorry, nothing was found in the database!</b></center>";
exit();
}

Qui l’interpretazione della stele di Roseta dice che: seleziona tutti i record presenti nella tabella con il nome da te scelto dove il campo keywords ha come valore (grazie all’ operatore LIKE) la stringa digitata dall’ utente, dopodichè questa query in relazione ai parametri di connessione avrà una situazione di tabella vuota e di tabella piena, quindi devo gestire i messaggi all’ utente con un IF-ELSE dove sopra si evince solo la prima istruzione condizionale del FALSE che riporta un messaggio di database VUOTO all’ utente, che continua sotto con la condizione TRUE caratterizzata dal ciclo WHILE che fa tutto il lavoro di scorrimento dei dati:

while($row_result=mysqli_fetch_array($run_result)){
$title=$row_result['title'];
$link=$row_result['link'];
$link1=$row_result['link1'];
$tipo=$row_result['tipo'];
$alcol=$row_result['alcol'];
$desc=$row_result['desc'];
$history=$row_result['history'];
$image=$row_result['image'];
	
echo "<div class='results'>
	
<h2>$site_title</h2>
<img src='images/$image' width='88' height='100' style='float:left;padding-right:4px;margin-right:4px;'/>
<a href='$link' target='_blank'>$link</a>&nbsp;&nbsp;<a href='$link1' target='_blank'>$link1</a>
<p align='justify'>$tipo - $alcol - $desc</p> 
<p align='justify'>$history</p> 
</div>";

}
}

Quindi con due sole pagine, una di spedizione di dati e l’altra di ricezione abbiamo una INTERA APPLICAZIONE FUNZIONANTE! Certo a livello grafico il tutto lascia molto a desiderare, per cui stiamo seriamente pensando a fini didattici di migliorare il restyling della nostra applicazione, soprattutto in termini responsivi, che sarà oggetto del nostro prossimo articolo!

Come rendere un primordiale acronimo CRUD interessante e coinvolgente con HTML, CSS, BOOTSTRAP, PHP e MySQL!

Quello che può fare un semplice CRUD con PHP e MySQL ha del miracoloso! CRUD è l’acronimo di C-REATE R-EAD U-PDATE D-ELETE ossia le quattro operazioni base che un web developer junior inizia a conoscere quando si inserisce verso la meta del web developer senjor. Un CRUD è l’essenza di un applicativo che legge i dati con la famosa query SELECT (quindi READ), che aggiorna i dati con la famosa query UPDATE, che cancella i dati con la query o il comando DELETE e che legge i dati con la quintaessenza della programmazione dinamica: una semplice query SELECT, un imperioso comando che costringe la pagina a piegarsi alla volontà del suo creatore sciorinando dati a destra e a manca! Okweb developer umbria ma bando alle chance e parliamo di cose concrete e pratiche. Nell’ applicativo costruito tenendo come base un CRUD sono state inserite diverse funzionalità aggiuntive che abbelliscono il tutto anche con i ccs. L’applicativo ha uno scopo, quello di permettere a un giocatore di scacchi di fissare il suo repertorio di aperture per studiarle, quindi l’esempio del CRUD calza a pennello per lanciare un messaggio chiaro e ineluttabile: il CRUD nasce per soddisfare a esigenze concrete del quotidiano, poco importa che sia lavoro o svago piuttosto che economia locale o della comunità europea. Vediamo come nasce l’applicativo. E’ chiaro che la prima parte della costruzione dell’ architettura è già svelata: l’utente deve essere in grado di modificare i suoi dati dopo averli creati e anche di aggiornali e cancellarli se durante lo studio delle sue aperture scacchistiche qualcosa nopn gli sconfifferà. Il problema piu angosciante per un aspirante web developer junior è: e adesso come faccio a fare la connessione con il database? Intanto devo poter disporre di un DB in rete o in locale (essendo un applicativo disegnato sulle esigenze personali può funzionare anche solo con XAMP) poi ho bisogno di un editor per creare i file che non saranno tanti come si può intuire visto che l’applicativo avrà bisogno di una index che legge i dati in ingresso, di una pagina ADD che inserisce i dati creati, di una che fa l’aggiornamento UPDATE, di una che cancella impartendo il comando DELETE. Ma prima di fare questo dobbiamo studiare la struttura del database che in questo caso avrà quattro campi:

  • una chiave primaria autoincrementante progressiva definita classicamente come intero ID
  • un campo nel quale scriveremo la prospettiva di studio del nostro impianto di gioco, ossia se vogliamo focalizzarci dalla parte del bianco o del nero con un campo stringa definito come COLORE
  • un campo o colonna definito come NOME per indicare il tipo di apertura che voglio giocare e studiare come stringa nel tipo di dato e lunga un centinaio di caratteri, come il precedente colore.
  • un campo descrittivo che ha le stesse caratteristiche delle ultime due COLORE E NOME ribattezzato DESCRIZIONE che avrà questa volta un ampiezza di dati large ossia trecento caratteri

OVVIAMENTE prima di fare queste definizioni all’ interno del DB servirà un nuovo database da creare entro il quale bisogna costruire una tabella che conterrà i nostri dati definiti dai nomi di campo o colonna descritti sopra.

Formalizzata questa semplice questione del database in dieci minuti, non ci resta che creare le pagine. Risolviamo subito la questione del collegamento ai dati nel file db, dove andrò a istanziare una variabile a cui verrà applicata il metodo connect che prende quattro parametri ossia chi è il server, come si chiama l’utente che si collega sulla macchina, quale pwd utilizza e infine dove va l’utente fisicamente in quale database, nel mio caso:

$db = new Mysqli;

$db->connect(‘localhost’,’root’,”,’crud’);

if(!$db){
echo “error”;
}

Abbiamo aggiunto anche un prototipo di controllo da perfezionare che dice: se la variabile è diversa da $db, ossia se non vede al suo interno dei dati, restituisci un messaggio di errore che ci avvisi di un malfunzionamento. Questa funzione andrebbe migliorata e ampliata ma al momento limitiamoci a stare dentro le tematiche del CRUD. Quindi il problema è risolto perchè ora sulla pagina index scriverò l’inclusione a questa pagina con:

<?php include ‘db.php’; >

con queste due semplici operazioni, ossia la creazione dei parametri di collegamento e l’inclusione alla pagina che leggerà i dati (READ nel paradigma acronimo crud) abbiamo praticamente fatto tanta roba! A questo punto non ci resta che impartire i nostri comandi SQL sul database, ossia per leggere i dati uso una SELECT espressa in queste modalità $sql = “select * from nometabella, ossia sto dicendo alla macchina di tirarmi fuori tutti i dati (asterisco o carattere jolly) dalla tabella che li contiene. Ora a livello di idea progettuale ne consegue che ogni pagina del CRUD avrà la sua query:

nella index.php: $sql = “select * from tasks
nella pagina add.php : $sql = “insert into nometabella (colore, name, descrizione) values (‘$colore’,’$name’,’$descrizione’)”;
nella pagina delete.php: $sql = “delete from tasks where id = ‘$id'”;
nella pagina update.php: sql2 =”update nometabella set colore=’$colore’, name=’$task’, descrizione=’$descrizione’ where id =’$id'”;

Per poter passare da una pagina all’ altra i valori da modificare o da aggiornare hanno bisogno di fare riferimento a un ID univoco che viene passato tra le pagine appunto e che ricade sulla pagina di interesse, ecco perché vediamo la clausola where id = ‘$id’, ossia fai questa operazione dove id è uguale al record corrispondente. La cattura dei valori degli id avviene con questo meccanismo o variabile GET:

$id= (int)$_GET[‘id’];

$sql = “select * from nome tabella where id=’$id'”;

Ora a grandi linee un CRUD ha questa impalcatura, è chiaro che poi ci saranno delle tabelle che raggruppano i dati, è palese che serviranno i tag HTML da intercalare con quelli PHP per recuperare i valori dei dati dopo aver fatto la classica FETCH con espressioni del tipo:

<input type=”text” required name=”descrizione” value=”<?php echo $row[‘descrizione’];?>” class=”form-control”><br/>

dove in questo caso abbiamo fatto quello che in VUE si chiama PROPS ossia iniettare i dati all’ interno del nostro campo di testo descrizione nell’ espressione: value=”<?php echo $row[‘descrizione’];?>” situazione che andrà ripetuta per tutte le circostanze anche per i campi nome e apertura.

Sostanzialmente le basi del crud sono legate appunto alle quattro semplici query che formano una base solida sulla quale appoggiarsi per costruire belle applicazioni: in questo caso sono state implementate anche funzionalità di paginazione (comunque complicate perchè la pagina va segmenetata in record quando si supera un certo limite di inserimento), stampa e ricerca tutte situazioni che arricchiscono ulteriormente con i CSS e l’immagine di background in modalità cover di sfondo le funzionalità delle mie creazioni. L’articolo vuole solo offrire un potenziale di sviluppo sulle modalità espresse dalla tecnologia PHP MYSQL CRUD senza entrare nei dettagli della costruzione che comunque è ridotta all’ osso, ma esteticamente aggraziata grazie al framework responsivo BOOTSTRAP (facile da riconoscere per il colore dei bottoni): sei file con l’aggiunta di una immagine ma con elementi grafici come finestra modale e altro da non sottovalutare. Se volessi crescere ulteriormente con la mia applicazione dovrei implementare altri parti tipo: prima di cancellare posso aprire una finestra di dialogo che dice all’ utente di fare attenzione e di essere consapevole di quello che sta facendo? E se volessi ordinare i dati delle colonne come faccio con php e mysql? E’ roba per web developer senior? Volendo integrarie tecnologia AJAX con JQuery per rendere la modalità di visualizzazione dei dati asincrona per non andare incontri a rallentamenti rendering del client potrei farlo? Ce la posso fare?

Buon CRUD a tutti!

Sei STATIC? Allora dovresti fare ginnastica: OOP e PHP, perché i richiami alle variabili statiche offrono flessibilità alle applicazioni, settima puntata

Nelle ultime puntate di OOP e PHP come https://umbriawayincrementa.wordpress.com/2020/04/22/pubblico-o-privato-questo-non-e-un-film-sugli-enti-dislocati-sulla-penisola-ma-oop-e-php/   abbiamo esplorato il potenziale offerto dai progetti che presentano una visibilità delle variabili (o proprietà) pubbliche o private, dipende molto anche dalle caratteristiche del progetto. A questo punto c’è una nuova parola che entra in scena STATIC. Ma di che stiamo parlando? Supponiamo che nella nostra classe GM debba trovarmi nella necessità di creare un account utente per un sito che ospita un area riservata magari con dei servizi a pagamento. Sappiamo che le classi hanno la funzione di proporre una riutilizzabilità del codice per cui potrei usare la classe ACCOUNT anche in altri progetti, quindi inizierò ad avere una classe che ospiterà un paio di variabili canoniche del tipo username e password:

class Account
{
private $username;
private $password;

}

supponiamo che ogni volta che un oggetto si istanzi su questo oggetto io voglia tenere il conto delle nuove istanze istanziate (è un gioco di parole ma rende l’idea). Quanti nuovi oggetti sono stati creati su quella classe? Sappiamo che una classe è un qualcosa di unico nel suo genere e che non possiamo prendere come riferimento ogni oggetto per fare un conto centralizzato del numero che ci interessa, quindi per forza dovremmo introdurre all’ interno della classe una proprietà universale che ha un valore assoluto che mai verrà modificato. Quindi ci viene in aiuto il nostro STATIC, una parola chiave che fa proprio al caso nostro perchè conosciamo i limiti dei metodi private perché leggono solo i membri privati dove vengono definiti, mentre in questo caso la nostra esigenza è un altra, ci serve una variabile contatore che si incrementa ogni volta che una nuova istanza viene creata. per cui iniziamo a introdurre una nuova voce nella nostra classe, private static $count;

class Account
{
private $username;
private $password;
private static $count;
}

A questo punto ci serve un metodo che prende in ingresso l’oggetto istanziato e lo incrementa ogni volta che l’operazione di un nuovo oggetto creato si ripete, quindi siccome abbiamo anche visto quale è l’utilità di un costruttore, cioé quella di inizializzare in automatico delle operazioni al momento della creazione dell’ oggetto, ci inventiamo una funzione (o metodo) __construct (è il modo convenzionale di implementare un costruttore) che fa al caso nostro, inserendo anche un nuovo elemento quella della costante PREFIX (per convenzione si scrivono in maiuscolo) che farà da separatore prima del numero incrementato:

class Account
{
private $username;
private $password;
private static $count;

const PREFIX=”user_”;

function __construct($u, $p=”12345″)
{
$this->username=self::PREFIX.$u;
$this->password=$p;

self::$count++;
printf(“Creato $this->username: account n. %d <br>”, self::$count);
}
}

Che fa sostanzialmente questo costruttore? Accetta due parametri di ingresso, in cui nel secondo quello della password ($p) diciamo arbitrariamente che ha un valore universale se non viene inserito, in questo modo quando verrà creato l’ogetto io dovrò soltanto digitare $u, ossia lo username. Poi assegno i parametri degli argomenti inseriti tra parentesi a delle assegnazioni dell’ oggetto account, tenendo appunto presente che grazie alla costante prefisso avrò poi un separatore con il numero incrementale nel conteggio delle istanze create. Il tutto sembra più difficile da raccontare che a farsi in quanto una volta istanziati i nostri oggetti e ottenuto il nostro script, grazie a http://phptester.net/ a video otterremo:

class Account
{
private $username;
private $password;
private static $count;
const PREFIX=”user_”;

function __construct($u, $p=”12345″)
{
$this->username=self::PREFIX.$u;
$this->password=$p;

self::$count++;
printf(“Creato $this->username: account n. %d <br>”, self::$count);
}
}

$a=new Account(“Svidler”);
$b=new Account(“Aronian”);
$c=new Account(“Carlsen”);
$d=new Account(“Piscopo”);

RISULTATO A VIDEO e risposta alla domanda quanti oggetti sono stati istanziati:

Creato user_Svidler: account n. 1
Creato user_Aronian: account n. 2
Creato user_Carlsen: account n. 3
Creato user_Piscopo: account n. 4

Da notare infine il sibilinno simbolo arcano geroglifico o assiro babilonese %d che funziona solo da SEGNAPOSTO per lasciare spazio a self::$count ossia la nostra variabile statica. Se ne deduce quindi che i caratteri i due punti ripetuti sono proprio un modo caratteristico nella sintassi di PHP di riconoscere le proprietà statiche di una classe che sono per l’appunto dei valori assoluti presenti nella classe come riferimento per tutti gli oggetti che verranno istanziati