Se i frammenti di tipo PHP abbondano su Internet, allora perché scriverne un altro? Beh, i frammenti PHP trovati al giro sono generalmente zoppi. Frammenti che generano una stringa casuale o un ritorno di $_SERVER["REMOTE_ADDR"]
per un indirizzo IP da un client in realtà non sono così interessanti e sono di utilità modesta. Invece, ecco alcuni frammenti che senza dubbio troverete interessanti e utili e che mi hanno tolto dai guai in più occasioni.
<?php
$csv = "";
foreach ($data as $row) {
$csv .= join(",", $row) . "\n";
}
echo $csv;
?>
fputcsv()
, che esegue il tutto molto più velocemente anche perché la sua implementazione è in codice C e gestisce il necessario quotando/escapando i caratteri per noi.Il codice seguente avvolge la logica per costruire l’output in CSV da un array di dati. Ha dei parametri opzionali per consentire di aggiungere le colonne di intestazione e per svuotare il CSV direttamente al browser o per restituire l’output sotto forma di stringa. L’eleganza del codice è l’uso dei flussi con
fputcsv()
che, come funzione, richiede un file aperto per gestire l’operazione.
<?php
function creaCSV($dati, $intestazioni = array(), $comeStringa = false) {
$ritorno = '';
$flusso = $comeStringa
? fopen("php://temp/maxmemory", "w+")
: fopen("php://output", "w");
if (!empty($intestazioni)) {
fputcsv($flusso, $intestazioni);
}
foreach ($dati as $elemento) {
fputcsv($flusso, $elemento);
}
if ($comeStringa) {
rewind($flusso);
$ritorno = stream_get_contents($flusso);
fclose($flusso);
return $ritorno;
} else {
fclose($flusso);
}
}
?>
creaCSV()
nel nostro arsenale, generare i files di tipo CSV diventa semplice e facile.Lo standard non descrive quali sono le funzionalità supportate, che dovrebbero essere forniti da un autoloader PSR-0 compatibile (metodi di registrazione, opzioni di configurazione, ecc.). Se è in grado di trovare automaticamente una definizione di classe nella cartella con il modello
\\(\
), allora è PSR-0 compliant. Inoltre, non specifica la directory principale per
. L’extra, o il contorno, della maggior parte delle implementazioni autoloader è conveniente se è necessario specificare la posizione tramite il codice, ma è inutile se si usa semplicemente una directory già dentro il percorso di inclusione di PHP.
<?php
spl_autoload_register(function ($nomeClasse) {
$nomeClasse = ltrim($nomeClasse, "\\");
preg_match('/^(.+)?([^\\\\]+)$/U', $nomeClasse, $match);
$nomeClasse = str_replace("\\", "/", $match[1])
. str_replace(["\\", "_"], "/", $match[2])
. ".php";
include_once $nomeClasse;
});
?>
$match[2]
, e $match[1]
avrà il nome del namespace, che può essere una stringa vuota. Questo è necessario per identificare le parti perché la sottolineatura non ha alcun significato particolare nella porzione di spazio dei nomi facendo una sostituzione alla cieca con la sottolineatura e il backslash correttoI dati a lunghezza fissa sono relativamente facili da elaborare in linguaggi come C, perché i dati, una volta caricati in memoria, si allineano perfettamente con la struttura dell’accesso ai dati. Ma per alcuni, lavorando con i dati a lunghezza fissa in un linguaggio dinamico come PHP può essere una lotta: la mancanza di tipizzazione del linguaggio rende l’accesso alla memoria impossibile. E come risultato, spesso vediamo del codice che assomiglia a quanto segue:
<?php
// analisi di una intestazione NACHA
$row = fread($fp, 94);
$header = array();
$header["type"] = substr($row, 0, 1);
$header["priority"] = substr($row, 1, 2);
$header["immDest"] = substr($row, 3, 10);
$header["immOrigin"] = substr($row, 13, 10);
$header["date"] = substr($row, 23, 6);
$header["time"] = substr($row, 29, 4);
$header["sequence"] = substr($row, 33, 1);
$header["size"] = substr($row, 34, 3);
$header["blockFactor"] = substr($row, 37, 2);
$header["format"] = substr($row, 39, 1);
$header["destName"] = substr($row, 40, 23);
$header["originName"] = substr($row, 63, 23);
$header["reference"] = substr($row, 86, 8);
print_r($header);
?>
unpack()
.La documentazione per
unpack()
nel manuale PHP dice: “spacchetta una stringa binaria in una matrice in base al formato dato” e mostra l’utilizzo con degli esempi con i caratteri di escape usando dati binari. Ciò che non può essere immediatamente evidente è che la funzione può essere utilizzata per analizzare stringhe a lunghezza fissa grazie allo specificatore del formato di A, che rappresenta un carattere (dopo tutto, non è una stringa seguita da una serie di bits e bytes?).Utilizzando
unpack()
, l’esempio precedente può essere riscritto in modo più elegante come segue:
<?php
// analisi di una intestazione NACHA
$row = fread($fp, 94);
$header = unpack("A1type/A2priority/A10immDest/"
. "A10immOrigin/A6date/A4time/"
. "A1sequence/A3size/A2blockFactor/"
. "A1format/A23destName/"
. "A23originName/A8reference", $row);
print_r($header);
?>
A6date
per esempio analizza i 6 caratteri e li rende disponibili in $header["date"]
.
<?php
class Template {
protected $dir;
protected $vars;
public function __construct($dir = "") {
$this->dir = (substr($dir, -1) == "/") ? $dir : $dir . "/";
$this->vars = array();
}
public function __set($var, $value) {
$this->vars[$var] = $value;
}
public function __get($var) {
return $this->vars[$var];
}
public function __isset($var) {
return isset($this->vars[$var]);
}
public function set() {
$args = func_get_args();
if (func_num_args() == 2) {
$this->__set($args[0], $args[1]);
} else {
foreach ($args[0] as $var => $value) {
$this->__set($var, $value);
}
}
}
public function out($template, $comeStringa = false) {
ob_start();
require $this->dir . $template . ".php";
$content = ob_get_clean();
if ($comeStringa) {
return $content;
} else {
echo $content;
}
}
}
?>
Template
, eventualmente si passa un nome di directory utilizzato per cercare il file del template. Poi, si passano i valori che dovrebbero popolare il modello con metodo il metodo set()
o come nuda proprietà. Una volta che tutti i valori sono stati specificati, si chiama il metodo out()
per il rendering del template.
<?php
$t = new Template();
// imposta un valore come se fosse una proprietà
$t->saluti = "Ciao Mondo!";
// imposta un valore con set()
$t->set("numero", 42);
// imposta valori multipli con set()
$t->set(array(
"foo" => "Pippo",
"bar" => "Pluto"
));
// esegue il rendering del template
$t->out("miotemplate");
?>
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="utf-8">
...
</head>
<body>
<div role="main">
<h1><?=$this->saluti;?></h1>
...
</div>
</body>
</html>
Con il secondo parametro opzionale per
out()
è possibile specificare se restituire il contenuto del modello come una stringa, invece di scaricarlo direttamente al browser, che è possibile sfruttare per sostituire il segnaposto in un modello con il risultato di un modello già compilato.Il problema che basarsi su cURL per le richieste HTTP è duplice:
- ci sono spesso molte opzioni che devono essere impostate, anche per la più semplice delle operazioni;
- si tratta di un’estensione che potrebbe non essere disponibile a seconda dello hosting che ospita il nostro sito web; è una estensione comune, ma non è abilitato per default.
file_get_contents()
e stream_context_create()
sono due funzioni native di PHP e sono disponibili a partire dalla versione 4.3. Insieme, possono essere utilizzati per eseguire molte delle stesse richieste comunemente effettuate tramite cURL.
Per le richieste del tipo GET, file_get_contents()
può essere usato da solo:
<?php
$html = file_get_contents("http://sitoweb.com/prodotto/33");
?>
stream_context_create()
e quindi passare il contesto file_get_contents()
.
<?php
$context = stream_context_create(array(
"http" => array(
"method" => "POST",
"header" => "Content-Type: multipart/form-data; boundary=--foo\r\n",
"content" => "--foo\r\n"
. "Content-Disposition: form-data; name=\"mioFile\"; filename=\"immagine.jpg\"\r\n"
. "Content-Type: image/jpeg\r\n\r\n"
. file_get_contents("image.jpg") . "\r\n"
. "--foo--"
)
));
$html = file_get_contents("http://example.com/upload.php", false, $context);
?>
POST
, con l’array come contesto, con le informazioni necessarie per l’operazione con le chiavi: “method
“, “header
” e “content
“.Quando si utilizza
file_get_contents()
per le richieste complesse come il caricamento di un file, può essere utile fare prima un finto web form ed eseguirlo tramite Firefox
con firebug abilitato o qualcosa di simile per poi esaminare ciò che è stato incluso nella richiesta. Da lì si può dedurre gli elementi di intestazione importanti da includere.
Ancora nessun commento