Per lanciare uno script nel browser bisogna lanciare il server, poi specificare la url in localhost al giusto path.
Propongo un batch in autoit che fa tutto questo con un click sul menu contestuale del file di script.
Idea:
se un file è presente in c:\www\sito1\file.php bisogna lanciare http://localhost:8080/sito1/file.php.
quindi basta rimpiazzare i prefissi e sostituire gli slashes per ottenere la url del server localhost.
Ecco un codice funzionante (scarica anche da qui e ammetti di essere pigro ), da personalizzare con i propri path, poi compilare (tasto destro->compile) ed associare ai files di script.
vedi i commenti
$apacheDocumentRoot = "e:\" ; vedi DocumentRoot in httpd.conf
$apacheUrlRoot = "http://localhost:8080/" ; oppure 127.0.0.1:<porta>
$nomeEseguibileServer = "EasyPHP.exe" ; anche xmapp o Apache.exe
$pathEseguibileServer = "E:\siti\easyphp\EasyPHP.exe"; vedi sopra
$testoTrayTipWindows = "lancio pagina php in locale"
$timeoutSecondiTrayTipWindows = 6
$pathBrowser = "E:\applicazioni\internet\Mozilla Firefox\firefox.exe"
$parametriBrowserAfterUrl = "-url" ; internet explorer non vuole parametri, usare ""
If ($CmdLine[0]==0) Then MsgBox(0,"errore","passare lo script a linea di comando") Exit EndIf
$url = $CmdLine[1]
$url = StringReplace($url, $apacheDocumentRoot, $apacheUrlRoot)
$url = StringReplace($url,"\","/")
TrayTip ( $testoTrayTipWindows , $url, $timeoutSecondiTrayTipWindows , 1 )
If NOT ProcessExists($nomeEseguibileServer) Then
Run($pathEseguibileServer)
Sleep(5000)
EndIf
Premesso che per fare piccole modifiche veloci a scripts PHP ci sono molti editor personalizzabili, ho recentemente cercato un ambiente di sviluppo IDE per PHP gratuito, da usare per progettare applicazioni + complesse su Windows.
Il primo che ho provato è Netbeans for PHP. Netbeans lo ritengo uno tra i più completi IDE per Java, a molti non piace per la sua pesantezza, e in effetti è pesante, ma è il prezzo da pagare per avere il massimo delle funzionalità. E quando si ha a che fare con progetto complessi, le funzionalità aiutano eccome. Da precisare che ci vuole molto tempo ad avviare l’IDE, poi si lavora con fluidità sui progetti aperti.
Dallo screencast vedo già che supporta le classiche funzioni Netbeans per Java, refactoring, evidenziazione codice, autocompletamento (anche di metodi importati da classi create dall’utente e incluse in qualsiasi modo), debugging, templates e abbreviazioni. L’ide installato occupa meno di 90 Mb e non interferisce con altre installazioni di Netbeans.
Interessante è anche l’editor HTML (ovviamente non WYSIWYG) che segnala errori di tag non corrispondenti e ha una piccola palette dei tag, oltre a fornire - in autocompletamento - l’elenco degli attributi disponibili per il tag corrente con tanto di documentazione onscreen.
Molto interessante anche l’editor Javascript che evidenzia sintassi ed errori del codice, autocompleta funzioni degli oggetti javascript, refactoring di variabili e funzioni ecc..
Stessa cosa per CSS: evidenziazione, autocompletamento selettori e attributi, con tanto di palette per selezionare caratteri, colori, bordi, posizioni.
Utile anche la funzione di download/upload FTP dei files che avviene sui corrispondenti path remoti nel server.
Sono rimasto invece deluso da Eclipse PDT dato che molti optano per eclipse piuttosto che netbeans. I tempi di avvio sono simili a quelli di Netbeans PHP. Non è possibile facilmente creare un progetto da files esistenti. la visibilità su metodi e funzioni incluse non ha funzionato bene in alcuni casi, il refactoring delle funzioni e metodi non ha funzionato. Il resto delle funzionalità (autocompletamento e altro anche per CSS e javascript) mi sono invece sembrate ottime e paragonabili a quelle di Netbeans.
So ora dell’esistenza di Dev PHP, quindi forse lo proverò sperando di poterlo usare come alternativa leggera.
Tempo fa ho provato Zend Studio (5.5 mi pare) e immagino che adesso sia almeno all’altezza dei 2 sopra, peccato che sia pagamento.
Sono curioso dei vostri commenti e di sapere cosa voi usate.
In questo articolo presento CakePHP, web framework per PHP.
Per chi non lo sapesse, PHP è un linguaggio di scripting per pagine web dinamiche. Con le eventuali interazioni con il database, permette di realizzare con facilità siti dinamici (gestione news, e-commerce…) e applicazioni web-based (ad es: gestionali online multiutente, installabili in locale o su server online). La maggior parte degli hosting, anche i più economici supportano scripting php. Data la sua forte crescita, licenza d’uso gratuita, facilità d’uso, presenza di molte librerie già pronte, è una delle soluzioni più adottate per le esigenze di piccole e media imprese.
Nello sviluppare un’applicazione complessa, ci si ritrova spesso davanti a implementare funzionalità simili complicate, è quindi fortemente consigliato l’utilizzo di un framework per velocizzare i tempi, ridurre gli errori, concentrarsi più ad alto livello sull’applicazione ed avere altri vantaggi.
Perchè proprio CakePHP ?
Al momento i migliori framework per PHP sono all’incirca Zend, Symphony e CakePHP (cakephp.org).
In questo articolo presento l’ultimo di questi, in quanto ha una bassa curva di apprendimento, è ben documentato, molto utilizzato (trovate molti tutorial e guide all’uso), funziona con MVC, supporta Ajax, caching e, diversamente dai primi 2, gira anche con PHP4.
Se volete analizzare meglio le differenze di funzionalità tra i framework disponibili, cercate su google “php framework comparison chart”.
I framework che trovate non sono in alternativa, ma pensati in modo diverso e con ambiti di funzionalità diversi. Se vi chiedono di realizzare un’applicazione, sarebbe l’ideale avere un’idea di alcuni di essi, in modo da scegliere il più adatto. E’ possibile anche usarne più di uno per la stessa applicazione, ad esempio uno per il backend e uno per il frontend e/o un altro per una funzionalità precisa, Zend e Symphony lavorano insieme senza troppi problemi per esempio.
Iniziamo ! primi passi e nozioni di base…
Scaricate l’ultima versione stabile ed estraetela. Al momento l’ultima è la 1.1.19.6305. Vi trovate una struttura con un file index.php (questo file è il primo file chiamato dal client, elabora tutte le richieste del client e le smista ai componenti interni). La cartella “cake” contiene il motore del framework, mentre in “app” metteremo tutti i sorgenti della nostra applicazione. Questa struttura di directories e files va posizionata tale e quale nel webserver.
Nella root non ci va nessun altro file. Se una url per il client è ad esempio
http://percorso_app:porta/gestione/news/insert,
non significa che abbiamo una struttura di directories gestione/news/insert, ma che verrà chiamata (in http) la pagina index.php passando la stringa
“gestione/news/insert“.
Questo sistema è dovuto a MVC, un pattern architetturale che consente di separare logica applicativa e interfacce utente. Tralasciando la classica definizione di MVC, che non è facilmente intuibile, per ora ci basta sapere che il view gestisce l’interfaccia utente, il model contiene e gestisce i contenuti, il controller gestisce la logica applicativa.
Esempio
Propongo un esempio minimale, un inserimento di news sull’homepage. Se usate Windows, potete testare benissimo in locale, ad esempio con EasyPHP (easyphp.org) che comprende l’ambiente WAMP (windows, apache web server, mysql database server, php linguaggio di scripting) già funzionante dopo la prima installazione senza configurazioni. Se usate linux sarete sicuramente degli smanettoni quindi non avrete penso problemi a scaricarvi i pacchetti e configurarvi l’ambiente
1.preparazione ambiente
Create la tabella con phpmyadmin per le news (riporto la query di creazione):
CREATE TABLE `news` (
`id` INT( 3 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`titolo` VARCHAR( 255 ) NOT NULL ,
`testo` TEXT NOT NULL
)
Inserite anche qualche record di prova.
Andate in app/config, copiate il file database.php.default in database.php, aprendolo vedete che di default viene usato mysql come database, cambiatelo se volete usare SQLite o altri. Inseriteci i parametri di connessione (db, user, pass). Per EasyPHP, lo user è root, la password è vuota.
Servirebbe abilitare MOD_REWRITE nel webserver apache, funzionalità che permette di mappare le url http in percorsi fisici diversi attraverso configurazioni apache o file .htaccess. Se il vostro server non lo supporta, andate in app/config/core.php e decommentate la riga
define (’BASE_URL’, env(’SCRIPT_NAME’));
2. pagine per lettura news
Passiamo a scrivere il codice per l’applicazione. Siccome funziona tutto con MVC, iniziamo a creare il modello (con il contenuto).
Creare il file app/models/news.php, che contiene la classe omonima News (importante: con lettera maiuscola) che deve estendere la classe AppModel
<?php
class News extends AppModel
{
var $name = ‘News’;
}
?>
Creiamo adesso il controller in app/controllers/news_controller.php che estende da AppController.
Questa volta abbiamo in più il metodo index() ovvero il metodo principale che viene chiamato per costruire la pagina, in questo caso (vedi codice seguente) settiamo la variabile news con i record del database.
<?php
class NewsController extends AppController
{
var $name = ‘News’;
function index()
{
$this->set(’news’, $this->News->findAll());
}
}
?>
Terza cosa da creare è la vista, ovvero il file che mostra l’elenco dei records. A questo file, la findAll() passa l’array news (settato sopra dal controller con la set), che per elemento, quindi chiave News, contiene l’array super-globale con i record. Mi spiego meglio con il codice (da inserire in app/views/news/index.thtml).
ottenete la pagina con l’elenco delle news (se avete MOD_REWRITE attivato, non serve specificare la parte di url index.php/).
Come vedete sul titolo di ogni news c’è un link sul titolo che porta a /news/leggi/<id record>. Il contenuto dei questa ultima pagina, sarà restituito dalla funzione omonima leggi($id) dentro il controller, così come la url della index è data dalla funzione index(). In pratica la pagina news/azione/id verrà costruita chiamando il metodo azione() del controller e passandoci l’id alla funzione.
Aggiungiamo quindi la funzione seguente a news_controller.php
function leggi($id = null)
{
$this->News->id = $id;
$this->set(’news’, $this->News->read());
}
Analogamente alla index(), viene setta la variabile news con il record avente id uguale a $id, in modo che il view la possa usare.
Creiamo app/views/news/leggi.thtml e inseriamo la semplice stampa della news
<h1><?php echo $news['News']['titolo']?></h1>
<p><?php echo $news['News']['testo']?></p>
Riaprendo con il browser la pagina vediamo che i links sui titoli portano alle pagine con i dettagli della news.
3.pagine di inserimento/modifica record
Aggiungiamo al controller il metodo add() che gestisce :
function add()
{
if (!empty($this->data) &&
$this->News->save($this->data))
$this->flash(’News inserita.’,'/news’);
}
Ancora una volta aggiungiamo il corrispondente view in app/views/news/add.thtml, che stampa il form di inserimento
In pratica chiamando la url news/add ci troviamo un form che al submit inserisce i dati.
Per creare la pagina di editing dei record, scrivete la funzione edit() in modo che se passate qualche dato chiami la save(), altrimenti chiama la read() dopo aver settato l’id.
function edit($id = null)
{
if (empty($this->data))
{
$this->News->id = $id;
$this->data = $this->News->read();
}
else
{
if ($this->News->save($this->data['News']))
{
$this->flash(’News aggiornata.’,'/News’);
}
}
}
Nel corrispondente view (edit.thtml) dobbiamo ricordarci di inserire il campo (hidden) id nel form, altrimenti in ricezione non riusciamo a capire quale record stiamo modificando.
Potete creare a questo punto un metodo e relativo view con l’elenco news e links per l’editing, in modo analogo alla index() con i link per vedere il testo della news. Tralascio il codice del controller e del view dell’editing per motivi di spazio.
4. ritocchi
Andate in app/config/routes.php, qui potete cambiare i mappaggi dei path delle url nei relativi controller e azioni predefinite. Mappando ad esempio il path root “/” con il controller news e action index, chiamando con il browser “/”, il contenuto sarà quello di /news/index.
Le pagine vanno ovviamente tra loro collegate con dei link, che come abbiamo visto si creano con
Con procedure simili potete creare i form di login.
Gli stili css sono facilmente inseribili, basta modificare quello di default, e questo va in automatico in tutte le pagine che vengono generate.
Guardatevi dal sito ufficiale la documentazione e le nuove funzioni, ci sono (direttamente o tramite plugin) librerie per la maggior parte delle esigenze di applicazioni web: session, cookie, xml, plugin ajax, siti multilingua, rss, socket http, form validation, scaffolding, email, time, javascript, soap per web services, pdf…
Potete anche configurare cosa viene dato all’utente se chiama una pagina (ovvero un metodo nel controller) che non esiste.
Guardatevi i files di configurazione dentro /app/config per personalizzare il comportamento generale del framework.
Conclusioni
Le procedure vi potranno sembrare apparentemente complesse per creare un’applicazione così semplice. Il funzionamento generale è che una pagina che l’utente vede non è una pagina scritta apposta, ma è data da una funzione dentro un controller. Lavorando in questo modo, ragionate sul sito/applicazione come un’unica entità, non come una moltitudine di pagine. Non dovrete mai fare una cosa due volte in questo modo. Se in alcune o tutte le pagine volete qualcosa (javascript, css, footer, menu di navigazione) basta che lo specifichiate una volta sola, riducendo al minimo la possibilità di errori.
Se ci pensate bene avete un’enormità di vantaggi lavorando in questo modo, derivanti sia dal modo di lavorare ad “alto livello”, sia da templating automatico delle pagine, facile controllo e manutenibilità del codice, scrittura html ridotta al minimo (non dovete scrivere i tag html, head, body ecc…, vengono scritti nel rispetto delle regole W3C dal motore di cakephp), una libreria di funzioni e patterns già implementati molto ricca. Ci sono anche dei vantaggi “invisibili”: tutte le pagine generate e relative chiamate al database server appesantiscono al minimo il carico di lavoro del server grazie al sistema di caching integrato.
CakePHP è distribuito con licenza gratuita MIT, simile alla GPL. In pratica potete farci tutto, ma se lo modificate dovete ridistribuirlo con la stessa licenza.
Dal punto di vista della sicurezza, dato che è distribuito con il codice sorgente, tenete conto che all’esterno l’applicazione è molto esposta.
Ho realizzato un progetto in C, che con alcuni input impiega diversi minuti prima di restituire risultati.
Mi sono chiesto se compilando lo stesso codice con compilatori diversi, i tempi di esecuzione degli eseguibili risultanti fossero diversi. Per il momento ho testato solo su win Xp visual studio 6, visual studio 2005, il gratuito Dev-C++ (compilatore GCC, opzioni di ottimizzazione attivate).
Ecco il grafico risultati, più o meno quelli che mi aspettavo, continuerò ad usare Visual studio 6.
Appena riesco testerò anche con Linux e Gcc.
Posto un trucchetto che mi è venuto in mente per avere semplice form anti-spam in una pagina web, senza controlli complicati captcha.
L’idea è che lo spam attraverso i form deriva da robots (ovvero programmi automatici) che analizzano le pagine web, e quando vedono un <form>, effettuano una chiamata alla pagina indicata nella action riempendo gli input con spam e postando.
Si può effettuare un semplice controllo antispam facendo una domanda del tipo ‘quanto fa 4-5 ?’ chiedendo di riempire il campo (quindi accettare il form solo se tale campo ha valore 9), oppure una soluzione tramite javascript/php che all’utente non chiede nulla:
client:
inserire campo aggiuntivo hidden <input type="hidden" name="conferma" value="" />
non mettere un tasto submit, ma un tasto button che (onclick) setta il campo hidden e poi effettua il submit
<input type="button" name="Submit" style="font-weight:bold" value="Invia" onclick="this.form.conferma.value=’<?=time()?>’; this.form.submit()" />
server:
effettuare un controllo sul valore del campo conferma. Qualora il valore sia troppo diverso (e quindi probabilmente derivante da un robot o proveniente da un’altra pagina), scartare la richiesta.
if (abs($_POST['conferma'] - time()) > 3600) exit("spam !!");
Controllo eventuale aggiuntivo: controllare il $_SERVER['HTTP_REFERER'] che sia quello della pagina che invia il form.
Per ovviare ai clients che non supportano javascript, si potrebbe scrivere il form html con il campo conferma di tipo text (scrivendo accanto che cosa s) e il pulsante submit di tipo submit
Mysql offre una interessante funzionalità : la ricerca fulltext, con la quale è possibile creare un indice su più campi, quindi cercare velocemente i record che contengono le parole cercate nei records della tabella.
Esempio:
tabella prodotti di un negozio
creare indice con
ALTER TABLE prodotti ADD FULLTEXT(`nome`, `marca`,`descrizione`)
quindi eseguire le query così: (parola cercata: dolci)
SELECT *,MATCH(`nome`, `marca`,`descrizione`) AGAINST(’dolci’) as pmatch
FROM prodotti
WHERE MATCH(`nome`, `marca`,`descrizione`) AGAINST(’dolci’) > 0
ORDER BY pmatch DESC
Il risultato è una tabella con una colonna in più "pmatc", che contiene un numero indicante la pertinenza (più alto => più record che contenevano la parola).
In pratica MATCH(`nome`, `marca`,`descrizione`) AGAINST(’dolci’) restituisce un punteggio della parola rispetto ai campi del relativo record. E’ necessario ripeterla due volte nella query per problemi di visibilità della clausola where dentro la query.
Indicativamente la pertinenza corrisponde al numero di volte che la parola viene trovata nei campi dell’indice.
Attenzione: l’indice considera el parole per intero, quindi "dolci" o "dolc" NON trova nessun record che contiene "dolce", a differenza di una LIKE ‘%dolc%’
Continuo a postare e mie funzioni php, casomai servissero a qualcuno, ma soprattutto per spammare il planet SpriTe e php-izzare maggiormante demo
Con questo metodo si può creare un formToMail scrivendo semplicemente il form html con names e values.
chiamando la funzione, al posting viene inviato il messaggio chiamando una sola funzione, funzione che compone il body del messaggio semplicemente unendo names e values esistenti. Se il campo contiene "(r)", viene automaticamente mostrato un messaggio di errore "campo X non riempito" con tasto "indietro". Leggi tutto… »
PHP. Capita spesso di voler richiamare una pagina (che è stata già chiamata con dei parametri).
Per non dover ogni volta riscrivere la url da zero, si possono sovrascrivere (o aggiungere se non ci sono già) i parametri in GET con la funzioncina ,codice a fondo post. Esempio : in una pagina di navigazione recordset stiamo visualizzando la pagina X di Y (quindi in GET ci saranno già dei parametri che vogliamo mantenere ), e serve un link alla pagina che però cambi l’ordinamento:
Cioè se la pagina corrente era
pagina.php?order=id&page=4&table=tabella il link dovrebbe essere
pagina.php?order=nome&page=4&table=tabella
Usiamo la funzione e scriviamo
<a href="pagina.php<?=makeUrl( array("order"=>"nome") )?>">ordina tabella per nome</a>
fregandocene dei parametri correnti che verranno mantenuti
Qualcuno ha avuto qualche altra idea per risolvere il problema ? commentate !
//rileggo i parametri GET e li sovrascrivo con quelli passati, restituendo la URL
function makeUrl($overGet)
{
$get = $GLOBALS['_GET'];
// overWrite GET
foreach($overGet as $k => $v)
{
$get[$k] = $v;
}
// make Url
$ga = array();
foreach($get as $k => $v)
{
$ga[] = urlencode($k)."=".urlencode($v);
}
//
return implode("&", $ga);
}
Alcune volte mi sono trovato a dover manipolare immagini in computer altrui e dover ridimensionare e convertire immagini da un formato all’altro, perdendo tempo a trovare o installare un programma adatto.
Perchè non creare un servizio dove uploadare l’immagine, ri-dimensionarle e riscaricarle nel formato scelto ?
A questo indirizzo ho messo una prima versione del tool:
Il funzionamento è tramite il comando convert, parte della famosa imagemagick open source, quindi i formati supportati sono tantissimi. Tra le opzioni, per il momento solo la qualità jpeg, ridimensionamento in pixel o percentuale (anche solo una dimensione, le altre in automatico).
Ho creato un programmino per automatizzare alcune operazioni di windows, ad esempio per spegnere il pc quando il DivX finisce o quando scompare la finestra “copia in corso…” o quando appare la finestra “Render completato” di autocad & simili.
Ancora in versione beta, a chi interessa istruzioni e download a questo link:
Finalmente dopo molti tentativi e discussioni tra me e Raffaello (compagno di univ) abbiamo scoperto perchè la funzione di libreria scanf del linguaggio C non si comporta come sembra o come riportato sui manuali.
Prendiamo il codice
char c;
scanf("%c", &c);
Sembra tutto a posto, infatti stampando poi la variabile c, si vede veramente il carattere digitato in console.
Ma:
char c;
do {
scanf("%c", &c);
}
while(c==’n');
dovrebbe continuare a chiedere un input finchè digitiamo n, invece esce subito anche digitanto esattamente ‘n’ !!!
Spiegazione: scanf mappa sulla stringa formato tutto il contenuto della stringa di input, compreso il newline alla fine ! strano, visto che la scanf necessita dell’andata a capo per terminare l’acquisizione e dovrebbe scartarlo visto che è sempre presente.
Nel caso del ciclo while sopra, in realtà nella locazione di memoria della variabile c nn è presente esattamente il carattere digitato, ma il carattere digitato e (magia ! ) il carattere di newline che viene considerato al secondo ciclo.
Soluzione:
scanf("%c\n", &c);
In questo modo il char digitato va a finire esattamente nella variabile c senza problemi e senza magiche aggiunte.
Il problema ovviamente non si pone con la stringa formato "%d" visto che "\n" è tralasciato per valori interi.