Post

Archivio della categoria 'PHP'

PHP: interfaccia per indentare il codice

Se avete del codice scritto velocemente tempo fa, o se dovete leggere codice non vostro e non indentato correttamente, questa interfaccia permette di migliorare l’aspetto del codice, impostando le indentazioni, le parentesi e gli spazi secondo le linee guida di PEAR:

http://www.tote-taste.de/X-Project/beautify/ 

Si possono anche scaricare le librerie che permettono di fare “il trucco” :)

PHP+Ajax: tendina province e comuni

Per fare selezionare un comune dal database servirebbe una tendina di 8000 voci… una possibilità è fare due tendine, una per provincia e una per comune, facendo popolare la seconda in base alla scelta fatta nella prima. Serve:

Una funzione Javascript per il popolamento:

<script type="text/javascript">
function change(ref)
{
  var selid = ref.selectedIndex;
  var value = ref.options[selid].value;  var url = "popola.php";
  var pars="id_provincia="+value;

var myAjax = new Ajax.Request(  url,
  {
    method: 'get',
    parameters: pars,
    onComplete: function (data)
   {
      $('selectComune').innerHTML = data.responseText;
    }
  });
}
</script>

Uno script PHP che esegua la query per il popolamento:

<?
  if (isset($_GET["id_provincia"])){  $strSQL="SELECT * FROM comuni";
  if (is_numeric($_GET["id_provincia"]) AND $_GET["id_provincia"]>0) $strSQL.=" WHERE     id_provincia=".$_GET["id_provincia"];
  $strSQL.=" ORDER BY comune";

// connessione al db
  $connessione=mysql_connect("localhost", "utente", "password");
  $db=mysql_select_db("nomedb") OR DIE ("Impossibile connettersi al database");

$risultati=mysql_query($strSQL) OR DIE ("Impossibile eseguire la query");

  // scrivo la select per intero
  echo "<select class=\"testo_input\" style=\"width: 147px; float: left;\" title=\"selezionare il comune\"
        name=\"comune_mod\" id=\"comune_mod\"><option value=\"0\">Scegli un
        comune</option>";

  while ($rs=mysql_fetch_array($risultati)){
      if($rs["id_comune"] == $_POST[comune_mod]) $selected = "selected"; else $selected = "";
      echo "<option value=\"".$rs["id_comune"]."\">".htmlentities($rs["comune"])."</option>";
    }

    echo "</select>";
    $chiudi=mysql_close($connessione);
  }
?>

Il form:

<form action="index.php?page=lista&amp;sezione=turismo&amp;lang=<?=$lang?>" enctype="multipart/form-data" method="POST" target="_self">
<select style="width:147px; float:left;" class="testo_input" title="selezionare la provincia di appartenenza" name="comune_mod_p" id=
"comune_mod_p" onchange="change(this);">
<option value="">Prima scegli la provincia</option>
<?
$strProvince="SELECT id_provincia, nomeprovincia FROM province";
$risultati=mysql_query($strProvince) OR DIE ("Impossibile eseguire la query");
// scrivo la select per intero
while ($rs=mysql_fetch_array($risultati)){
  //    if($rs["id_provincia"] == $_POST[comune_mod_p]) $selected = "selected"; else $selected = "";
  echo "<option value=\"".$rs["id_provincia"]."\"".$selected.">".$rs["nomeprovincia"]."</option>";
}
?>
</select>
<br/>
<span id="selectComune">
<select class="testo_input" style="visibility: hidden;width:147px; float:left;"></select>
</span><input type="submit" value=<? echo $l_cerca["$lang"]?> class="tasto_cerca" name="cerca_comune">
</form>

PHP: come evidenziare i risultati di una ricerca in una pagina HTML

Avete presente Google quando visualizzate in HTML una pagina PDF risultato di una ricerca, che vi fa vedere evidenziate le parole chiave che avete scelto? Beh, si può fare abbastanza velocemente in PHP!

Per farlo si possono usare le funzioni ob_start() e ob_end_flush() che permettono di bufferizzare l’output generato tra di esse e di passarlo ad una funzione di callback prima di visualizzarlo. Nella funzione di callback si può usare allora eregi_replace() per sostituire le parti di testo che ci interessano con la stessa parte evidenziata.

Ecco il codice:

// funzione che sostituisce il contenuto del buffer
function callback($buffer) {
global $cerca;
// sostituisce tutto quello che non è in un tag con la stessa cosa evidenziata in CSS
if($cerca) return (eregi_replace("(>[^<]*)($cerca)([^>]*<)", "\\1<span class=\"highlighted\">\\2</span>\\3", $buffer));
return $buffer;
}


if($cerca) ob_start("callback"); // inizia il buffer
print "Il mio contenuto";
if($cerca) ob_end_flush(); // termina il buffer

Fatto! L’espressione regolare è case insensitive (eregi_replace() invece di ereg_replace()) e corrisponde a tutto quello che sta fuori di <>, non sostituendo quindi parole chiave ad esempio all’interno di url nei tag <a>.

Basterà impostare una classe nel CSS che evidenzi ad esempio in giallo:

.highlighted {
background-color: yellow;
}

PHP: creare un feed RSS

Per creare un feed RSS è sufficiente avere una tabella di notizie, eventi etc con i seguenti dati:

  • titolo
  • descrizione
  • link

Per farlo possiamo usare la comoda classe feedcreator, da scaricare qui.

Il codice della nostra pagina di creazione feed sarà questo:

<?

include("feedcreator.class.php");
$rss = new UniversalFeedCreator();
$rss->useCached();
$rss->title = "Feed di htmlblog.info"; // titolo del feed
$rss->description = "Tutto quello che vi serve sapere sui feed in PHP"; // descrizione
$rss->link = "http://www.htmlblog.info"; // link del sito
$rss->syndicationURL = "http://www.tremcards.it/".$PHP_SELF; // link del file RSS

$image = new FeedImage();
$image->title = "logo htmlblog.info"; // logo
$image->url = "http://www.htmlblog.info/images/logo.jpg"; // file del logo
$image->link = "http://www.htmlblog.info"; // link a cui vogliamo che punti
$image->description = "Feed fornito da www.tremcards.it. Clicca sull'immagine per visitare il sito.";
$rss->image = $image;

$query="SELECT * from notizie ORDER BY data DESC";

$res = mysql_query($query);
while ($data = mysql_fetch_object($res)) {
$item = new FeedItem();
$item->title = stripslashes($data->titolo); // titolo della notizia
$item->link = "http://www.htmlblog.info/news".$data->IDnotizia.".html"; // link alla
// singola notizia
$item->description = $data->notizia; // breve descrizione
$item->date = $data->data; // data di pubblicazione
$item->source = "http://www.htmlblog.info"; // url di origine della notizia
$item->author = "Staff di htmlblog.info"; // autore

$rss->addItem($item);
}

$rss->saveFeed("RSS1.0", "rss/feednews.xml");
?>

Fatto! L’unica cosa da ricordarsi è di creare la directory rss/ e dargli i permessi di lettura.

Leggere i nomi dei file di una directory

Per leggere i nomi dei file in una directory Unix si può usare il comodo comando:

$a = glob("nome_dir/*");

che restituisce un array con le path di tutti i file della directory (esclusi quelli nascosti)

PHP: short tags e compatibilità XHTML

In PHP è possibile includere il codice da interpretare con i tag

<?php  ... ?>

o, se in php.ini è configurata la direttiva short_open_tags, anche con

<? ... ?>

Il problema diventa a questo punto che nello standard XHTML è possibile inserire in testa ad una pagina XHTML una dichiarazione XML di questo tipo:

<?xml version="1.0" encoding="UTF-8"?>

Se infatti sono attivi gli short_tags, questa istruzione viene interpretata come codice PHP e provoca un errore.

Se sul vostro server Web ancora sono presenti pagine scritte con gli short tags, può essere sufficiente ad evitare questo problema indicare nel file di configurazione del dominio virtuale la direttiva

php_admin_flag short_open_tag Off

In questo modo per il dominio virtuale in esame non sarà attiva la possibilità di usare gli short tags, e l’errore viene evitato.

Attenzione, però: proprio a causa del comportamento sopra descritto, gli short tags sono deprecati in PHP e non dovrebbero essere più usati.

PHP: accesso a MySQL (parte 3)

Vediamo ora un esempio di script per inserire dei dati in un database. Dividiamo lo script in quattro file:

  • header.php contiene il codice PHP che sarà comune anche a tutte le altre pagine del sito (dovremo farne altre, per visualizzare quali sono i dati già inseriti!). Nel nostro caso conterrà la connessione al database
  • header.inc contiene l’header HTML comune a tutte le pagine
  • footer.inc contiene il footer HTML comune a tutte le pagine
  • inserisci_zona.php è il codice della nostra pagina

Inseriremo, per semplicità, un campo in una tabella fatta così:

CREATE TABLE `zona` (
`ID` int(10) unsigned NOT NULL auto_increment,
`Nome` text,
KEY `ID` (`ID`)
);

header.php

<?php
// connessione persistente al database; argomenti sono host utente e password
$connessione = mysql_pconnect("localhost", "root", "");

// scelta del database; argomento è il nome del database
mysql_select_db("nomedatabase");

?>

L’header e il footer HTML sono il minimo indispensabile:

header.inc

<html>
<head>
<title>Inserimento zona</title>
</head>
<body>

footer.inc

</body>
</html>

Ed ecco il “vero” script, inserisci_zona.php. Viene usato un metodo comune, che include in uno stesso file la parte di codice che stampa il form e quella che lo elabora. In questo caso, le sezioni da visualizzare o meno dipendono dalla variabile $action, che viene impostata inviando i dati di un form.

<?php

include "header.php"; // include il file per la connessione al db

include "header.inc"; // include il file con l'intestazione HTML// Viene eseguito solo se deve inserire i dati nel database (cliccando "Conferma")

if($_POST[action]=="submit") {

    // inseriamo qui eventuali modifiche da fare ai dati prima di inserirli

$_POST[Nome] = strtolower($_POST[Nome]);     // rende Nome tutto minuscolo

    $_POST[Nome] = ucfirst($_POST[Nome]);         // mette in maiuscolo la prima lettera

    $query="INSERT INTO zona (Nome) VALUES (\"$_POST[Nome]\");";

    $ris_mysql = mysql_query($query);

    // $ris_mysql è zero se c'è un errore

    if($ris_mysql) {

         ?>

        <p>Dati inseriti correttamente nel database.<br/>

        Vuoi inserire un'altra zona?</p><!--'-->

        <p><a href="inserisci_zona.php">Sì</a> <a href="/">No</a></p>

        <?php

        include "footer.inc";

        exit;

        }

    else print "<p>Errore di inserimento nel database!<br/>Contattare l'amministratore

    di sistema.<br/>

    Query: $query</p>"; // MySQL non ha eseguito correttamente la query

}

// Viene eseguito se si è inviata la form (cliccando "Invia")

if($_POST[action]=="check") {

    // Controlli sintattici dei dati inseriti: se c'è un errore $err = 1 e viene

    // stampato il messaggio di errore nel form accanto al campo relativo

    if(!$_POST[Nome]) { $Nome_msg = "Campo obbligatorio"; $err = "1"; }

    else if(is_numeric($_POST[Nome])) { $Nome_msg = "Formato campo errato"; $err = "1"; }

    else $err = 0;

// Se ci sono errori viene stampato il titolo ERRORE e riproposta la form

    // con i dati precompilati

    if($err==1) print "<h2>ERRORE: controllare i campi indicati</h2>";

// altrimenti fa il riepilogo e chiede conferma. Sono due form perché uno ha

    // come azione submit, uno ha azione nulla e quindi riporta alla form precompilata

    else {

        ?>

        <h2>Riepilogo:</h2>

        <p>Nome: <?php print $_POST[Nome];?></p>

        <form method="POST" action="inserisci_zona.php">

        <input type="hidden" name="Nome" value="<?php print $_POST[Nome];?>"/>

        <input type="hidden" name="action" value="submit"/>

        <input type="submit" value="Conferma"/>

        </form>

        <form method="POST" action="inserisci_zona.php">

        <input type="hidden" name="Nome" value="<?php print $_POST[Nome];?>"/>

        <input type="hidden" name="action" value=""/>

        <input type="submit" value="Modifica"/>

        </form>

        <?php

        include "footer.inc";

        exit;

        }

    }

    ?>

<!-- stampa il form, con lo script stesso come action -->

    <form method="POST" action="inserisci_zona.php">

    <!-- il valore della variabile $Nome, che proviene da eventuali precedenti invii del form,

    viene assegnato all''attributo value del tag input e quindi preimposta il valore del campo

    -->

    <p>Nome: <input type="text" size="30" maxlength="30" name="Nome" value="<?php print $_POST[Nome];?>"/> <?php print $Nome_msg;?></p>

    <input type="hidden" name="action" value="check"/>

    <p><input type="submit" value="Invia"/> <input type="reset" value="Svuota"/></p>

    </form>

<?php

    include "footer.inc";    // include il file con il footer HTML

    ?>

PHP: accesso a MySQL (parte 2)

Vediamo ora come ci si connette usando le funzioni specifiche di MySQL:

Partiamo con il connetterci al database, ecco la funzione ed i suoi campi fondamentali per la connessione:

mysql_pconnect ( "SERVER", "USERNAME", "PASSWORD");

restituisce 1 se la connessione è avvenuta correttamente e 0 se ci sono stati errori. Da notare che è meglio usare mysql_pconnect(), e non mysql_connect(), perché il primo permette di effettuare connessioni persistenti e, se c’è già una connessione attiva, non ne apre un’altra, migliorando nettamente le prestazioni del sistema.

  • SERVER: se lasciato vuoto assumerà il valore di default “localhost:3306” (localhost sulla porta 3306).
  • USERNAME: il nome utente da usare per accedere al database
  • PASSWORD: la password per accedere al database.

Questi dati vi devono essere comunicati da chi vi fornisce l’hosting.

È sempre bene controllare che la connessione avvenga in maniera corretta:

$connessione = mysql_pconnect("localhost","nome","password")
or die("Problemi di connessione: ".mysql_error());

La funzione mysql_error() stampa il messaggio di errore di MySQL.

Per lavorare sui dati dobbiamo poi indicare al server quale database usare, usando la funzione mysql_select_db().

mysql_select_db( "DATABASE", $connessione );

Nota: il database deve esistere :) e $connessione è la risorsa aperta con la funzione mysql_pconnect().

Anche questa funzione restituisce 0 se ha avuto errori e 1 se è andata a buon fine.

mysql_query(QUERY, [$connessione])

mysql_query() permette di effettuare una query sulla connessione aperta. In caso di query che estrae dei dati restituisce una risorsa o 0 in caso di errore; per query di update, delete, drop e simili restituisce 1 se va a buon fine o 0 in caso di errore.

Se $connessione non viene indicata, si fa riferimento all’ultima connessione effettuata.

La risorsa restituita da mysql_query() può essere passata ad altre funzioni della libreria per analizzare i dati:

mysql_fetch_array($risorsa,[MYSQL_ASSOC| MYSQL_NUM]) permette di accedere ai dati del risultato sotto forma di array numerico o associativo. Se non si indica il tipo di array (MYSQL_ASSOC per array associativo, MYSQL_NUM per array numerico) vengono restituiti entrambi.

mysql_num_rows($risorsa) conta il numero di righe del risultato per un select, oppure

mysql_affected_rows($risorsa) conta il numero di righe su cui ha avuto effetto una insert, delete etc.

mysql_fetch_row() accede ad una riga dei risultati e sposta avanti un puntatore interno. La volta successiva che si richiamerà la funzione, quindi, verrà restituita la riga successiva.

mysql_close($connessione);

Chiude la connessione, se ce ne fosse bisogno.

Esistono inoltre molte altre funzioni utili, documentate sul sito di PHP

PHP: accesso a MySQL (parte 1)

Per accedere ad un database MySQL usando PHP si possono usare le funzioni core di PHP, in particolare

  • mysql_pconnect
  • mysql_select_db
  • mysql_close
  • mysql_query
  • mysql_fetch_row

Queste funzioni sono specifiche di MySQL e permettono di gestire una connessione al database e di effettuare delle query su di esso. Vengono installate insieme al modulo php_mysql, e sono parte della distribuzione ufficiale di PHP.
Oppure si possono usare le funzioni della libreria PEAR; queste non sono parte della distribuzione ufficiale di PHP, e quindi non sono presenti su tutti i server in cui viene fatto hosting, ma sono diffusissime e permettono di gestire connessioni a database in maniera indipendente dal motore di database sottostante. E’ consigliato quindi usare le librerie Pear se si deve scrivere del codice manutenibile, ma va controllato che siano supportate sul server utilizzato.

PHP: attenzione alla funzione mail()

In PHP per inviare una mail, ad esempio da un form, si può usare la funzione mail(), che ha la sintassi

mail( $to, $subject, $message, $headers );

Questa però non fa nessun controllo sui campi, in particolare sui campi $to e $message. Se si tratta di un form, a cui quindi si possono passare dei parametri anche tramite URL, è indispensabile fare dei controlli, altrimenti il form può essere utilizzato per inviare messaggi di spam includendo destinatari a piacimento attraverso un campo Bcc: embeddato all’interno del corpo del messaggio. In un form quindi il campo To: va sempre preimpostato, e si deve fare un controllo sul corpo del messaggio per evitare che vi vengano inseriti header SMTP.

Un esempio di controllo che si può fare sul corpo è il seguente:

function has_no_emailheaders($text)
{
return preg_match("/(%0A|%0D|\\n+|\\r+)(content-type:|to:|cc:|bcc:)/i", $text) == 0;
}


if (has_no_emailheaders($body)) {
mail($to, $subject, $body, $header);
}

Archivi e link