PHPBBIntegrare PHPBB PHPFunzioni PHP CFunzioni C EcologiaLa mia ecologia   Chi siamoChi è Senamion HomeHome page corner Il Web e l'ecologia

Senamion


Chi siamo:

Il web e l'ecologia, condividere il web e un momento di riflessione sullo stato dell'ecologia e sul suo futuro

Google

Come fare un programma PHP che gira ogni tot di tempo

27 Novembre 2006 by Giovanni | Argomenti: none | 8056

Tramite l’utilizzo del crontab è possibile sviluppare un programma che “gira” ogni tot di tempo oppure in determinati momenti della giornata predefiniti.
Il tutto, una volta capito il meccanismo, è molto semplice.
Per prima cosa occorre capire che un programma php può essere lanciato anche da linea di comando. L’output sarà la shell da cui si esegue, oppure può essere ri-diretto su file aggiungendo in fondo > /nome_directory/nome_file.
Siccome l’output non avviene su un browser è opportuno ricordare che la formattazione HTML non ha più senso. Quindi, ad esempio, un “a capo” va effettuato non con il BR ma con un \n.

Per lanciare il programma PHP da linea di comando bisogna premettere al sorgente PHP l’eseguibile che lo interpreta, ecco ad esempio la linea di comando su un server linux:

/usr/local/bin/php /directory_programma/nome_programma.php

In questo caso l’interprete PHP è /usr/local/bin/php mentre il programma è /directory_programma/nome_programma.php.

Per ridirigere l’output su un file il comando va modificato in questo modo:

/usr/local/bin/php /directory_programma/nome_programma.php > /dir_output/file_output

Dove /dir_output/file_output sarà il nome del file su cui verrà scritto l’output.

A questo punto vediamo di capire cosa occorre scrivere nel crontab (da linea di comando il crontab si può editare tramite il comando “crontab -e“):

  • un valore che indica il minuto (da 0 a 59)
  • un valore che indica l’ora (da 0 a 23)
  • un valore che indica il giorno del mese (da 1 a 31)
  • un valore che indica il mese (da 1 a 12)
  • un valore che indica il giorno della settimana (da 0 a 7 - 0 significa domenica)
  • il file di comando da lanciare come spiegato più sopra

I valori sopracitati possono essere sostituiti da dei valori multipli, che possono essere:

  • * (asterisco) significa “in ciascuno” - quindi se lo si indica nel primo campo significa “in ciascun minuto”
  • 0,5,10 ossia valori separati da virgole (e senza spazi) significa in ciascuno di quei valori - nell’esempio se si considera che 0,5,10 siano il primo campo significa al minuto 0, al minuto 5, al minuto 10
  • 0-10 ossia valori separati da trattino (e senza spazi) significa in ciascuno dei valori nel range - nell’esempio tutti i minuti da 0 a 10, equivalente a 0,1,2,3,4,5,6,7,8,9,10

Infine eccovi alcuni esempi:

  • * * * * * /dir/comando
    significa: esegui il comando ogni minuto
  • 15,45 * * * * /dir/comando
    significa: esegui il comando due volte ogni ora, ai minuti 15 e 45 (quindi alle 0:15 0:45 1:15 1:45 eccetera)
  • 0 2 * * * /dir/comando
    significa: esegui il comando ogni notte alle 2 precise
  • 5 12 10,20 * * /dir/comando
    significa: esegui il comando il 10 e il 20 di ogni mese alle 12:05

Se avete domande o volete altri esempi chiedete pure!

Pubblicato in Funzioni e classi PHP e C |

44 Commenti a “Come fare un programma PHP che gira ogni tot di tempo”

  1. ugo scrive:

    ciao, stavo cercando informazioni proprio a questo riguardo, pero’ mi servirebbe che una volta richiamato il file una prima volta, questo non venga piu’ richiamato le successive. In sostanza, quando richiamo il file, fare in modo che non venga piu’ richiamato (eliminando quindi le successive chiamate). Forse mi sfugge qualcosa e se puoi darmi qualche dritta, grazie! :)

  2. Giovanni scrive:

    Se va richiamato solo la prima volta (ad esempio una volta al giorno) va usato un metodo tipo quello spiegato “alle due di notte”.
    Altrimenti si deve lavorare direttamente sul programma.

  3. ugo scrive:

    no a me servirebbe una cosa del tipo:
    Alle 2 di notte del 15 Gennaio. (per dire)

    e una volta che scatta l’ora e aziono il mio programma pero’ distruggere questo file in modo che l’evento non venga + richiamato (l’anno seguente in pratica).
    Spero di essermi chiarito! :)

  4. Giovanni scrive:

    Per effettuare un comando ad una certa data c’è il comando AT che permette di schedulare un’attività in un certo momento.
    Vedo di preparare un breve tutorial!

  5. » Fare un programma PHP che girerà fra un po’ di tempo - Senamion scrive:

    [...] Facendo seguito all’articolo scritto su come fare per far si che un programma PHP venga lanciato ciclicamente, in questo articolo vediamo come fare per schedulare un programma PHP (e non solo, un qualsiasi batch UNIX) ad un determinato momento (come ad esempio oggi alle 22:00, oppure il 3 gennaio alle 10:05, o anche fra un’ora). Il comando che ci viene incontro per effettuare questa operazione è il comando at di UNIX. Questo comando permette proprio la schedulazione di un’attività in un certo momento predefinito o ad un delta rispetto alla data attuale. Vediamolo più nel dettaglio. Innanzitutto un semplice esempio: at now + 2 hours < /home/myhome/mybatch.com [...]

  6. Regolo76 scrive:

    Salve, mi servirebbe realizzare proprio un’azione del genere ma in realtà non ci ho capito molto….
    premetto che non conosco linux, ma questo programma dovrebbe girare su un server linux :)…

    praticamente io dovrei inserire alcune date in MySql ed in date precise (inserite nel DB) inviare le e-mail…
    è possibile fare una operazione del genere?

  7. Giovanni scrive:

    Nel tuo caso dovresti far girare il programma PHP ogni ora (o ogni minuto, o ogni giorno) e poi all’interno del programma PHP controllare se è scattata la data che hai su DB. Se è scattata fai l’operazione.

  8. peppe scrive:

    salve. Ma questa riga di comando per far girare l’applicazione ogni tot di tempo vale anke per windows?
    Io sto preparando un sito in cui andrò a mandare ping ogni tot di tempo e poi inviare i 4 tempi in un db. TT Questo in windows… Se puoi essermi di aiuto, te ne sarò grato! Ciao

  9. Giovanni scrive:

    No, il cron è tipico di unix / linux, probabilmente esiste qualche cron adatto a windows ma non lo conosco.

  10. peppe scrive:

    Ciao Giovanni.
    Ho installato linux per seguire passo passo i tuoi suggerimenti!
    Ora io voglio fare questa cosa: ho fatto una pagina php che manda ping e riesce ad acquisire i 4 tempi inviandoli in un database assieme al timestamp. E’ qui che voglio lavorare! Voglio fare una pagina php che va a fare la query sul timestamp e, qualora superi i tot minuti (1, 2 o 5), questa pagina deve mandare il ping all’indirizzo acquisito.
    Tutto ciò scritto nell’articolo può essere messo in una pagina php o solo dal terminale? Spero che sia stato chiaro. Ti ringrazio anticipatamente. Ciao

  11. Giovanni scrive:

    In questo caso conviene fare un programma che gira tutti i minuti e fa una query sul data base per vedere se deve eseguire l’operazione (nel tuo caso il ping). Se non deve eseguire non fa nulla, altrimenti fa partire il programma.

  12. peppe scrive:

    Ciao Giovanni,
    ho dei seri problemi con il crontab! Io voglio eseguire uno script php ogni 15 minuti. Come faccio? Mi puoi spiegare cosa devo andare a scrivere nel crontab (ho una suse 10.2)? Entro oggi devo finire il lavoro e nn so dove appigliarmi! Grazie. Ciao

  13. Giovanni scrive:

    Facile:

    0,15,30,45 * * * * /directory/comando

    Tra i numeri non lasciare spazi, gli altri spazi esattamente come sono.

  14. peppe scrive:

    dove /directory/comando non è altro che la path dove ho salvato lo script php? in questo caso la ho nella cartella htdocs di lamp… basta scrivere opt/lampp/htdocs/xxxxxx.php?

  15. Giovanni scrive:

    Mettila dalla home /opt/lampp/htdocs/xxxxxx.php

  16. peppe scrive:

    niente… mi dice che trova degli errori! In questo file php sto facendo dei ping e i risultati gli mando ad un database. Non so più che fare!

  17. Giovanni scrive:

    Se trova gli errori nel php vuol dire che il programma l’ha lanciato. Adesso dovrai correggere il programma.
    Tieni conto che è possibile che essendo lanciato dal cron l’utente non sia lo stesso (dipende l’utente di quale cron hai usato), inoltre i riferimenti di eventuali include devono essere assoluti (visto che parti da un path diverso).
    Il cron comunque, evidentemente, ha funzionato.

  18. peppe scrive:

    ancora niente…. potresti vedere il mio script e dirmi cosa non funziona? è evidente che è partito il crontab, ma gli errori sono sempre quelli… e solo da 5 giorni che uso linux e già sono cotto!

  19. Giovanni scrive:

    Ma se lo lanci a mano funziona?
    Ma hai messo come scritto all’inizio il comando php? Hai verificato che anche sul tuo server sia su /usr/local/bin/php?

    0,15,30,45 * * * * /usr/local/bin/php /opt/lampp/htdocs/xxxxxx.php

  20. peppe scrive:

    in /usr/local/bin/ non c’è php… c’è solo l’icona dell’ingranaggio di bluefish. Cosa dovrebbe essere php?
    Scusami se ti sto dando fastidio…

  21. Giovanni scrive:

    php è l’interprete del php. Devi sapere dove è installato sulla tua macchina.

  22. peppe scrive:

    Giovanni lasciatelo dire… SEI UN GENIO!!! Grazie tante! Mi hai permesso di superare un ostacolo insormontabile per me… te ne sarò riconoscente! Grazie ancora… alla prossima!

  23. Giovanni scrive:

    Sono contento che hai risolto! Buon lavoro!

  24. peppe scrive:

    Ciao Giovanni, vorrei chiederti una cosa un pochino più sofisticata… io vorrei acquisire da un database la frequenza del comando (es. ping per la pagina xxxx ogni 5 minuti, ping per la pagina yyyyy ogni 10 e la pagina zzzz ogni 15 minuti). Questa modifica la devo fare in crontab o nel php? Se la devo fare in crontab cm dovrei fare? Ti ringrazio anticipatamente della risposta sicuramente esaudiente. Ciao

  25. Giovanni scrive:

    I casi sono 2, o fai 3 programmi e li richiami da 3 righe di crontab diverse, oppure fai un programma che gira ogni (ad esempio) 5 minuti e controlli le operazione da effettuare in quel giro.

  26. peppe scrive:

    Puoi essere più chiaro sul secondo caso? Il primo non mi è concesso farlo. Io avevo pensato una cosa del tipo:
    faccio una query della tabella; con un for scansiono le n tuple; all’interno del for metto tre cicli if (per i tre tempi richiesti); all’interno degli if faccio un’altra query in cui acquisisco le righe che rispettino i tre tempi richiesti. Secondo me è buona come idea ma nn riesco a fare un programma funzionante. Tu che ne dici?
    Ciao

  27. Giovanni scrive:

    Normalmente nella tabella si mettono i tempi (quindi 5, 10, 15) e un campo che dice l’ultima volta che hai eseguito l’operazione che ore erano.
    Quando parte il programma legge tutti quelli in cui, dall’ultima esecuzione, è passato più del tempo previsto e ne esegue la funzionalità.

  28. peppe scrive:

    Mi puoi dire le differenze tra il fare tre pagine diverse o un solo programma? Per differenze intendo i problemi che si protrebbero avere in un caso o nell’altro…

  29. Giovanni scrive:

    In linea generale se i 3 programmi fanno 3 cose diverse è sicuramente meglio farne 3. Più semplice il debug, più semplice la configurazione.
    Se invece sono programmi accomunati tra loro, o se hanno una matrice comune per differenziarsi solo in alcuni punti allora meglio fare un programma unico.

  30. peppe scrive:

    Se ti va, ti mando i tre programmi e mi aiuti nel fare un unico programma senza modificare il crontab che gira cmq ogni 5 minuti. Ti dico che i tre programmi sono identici. Cambia solo la frequenza ma io onestamente non so cosa fare, Attendo una risposta. Ciao Giovanni

  31. Giovanni scrive:

    Mandameli a info@ nome di questo sito, spiegandomi in dettaglio cosa vuoi fare, appena ho tempo ci do’ un’occhiata!

  32. peppe scrive:

    fatto! Grazie ciao…

  33. nico scrive:

    ciao!
    trovo molto interessante questo articolo, vorrei avere un consiglio su come adattare tutto questo alle mie esigenze…
    in pratica vorrei che gli utenti stessi creassero degli scheduling, in un contesto tipo browser game con php dove un utente nel momento in cui decide di fare un azione questa accadrà esattamente una settimana dopo alla stessa ora.
    però ogni utente può dare il via a qualunque ora e a qualunque giorno… quindi deduco che queste informazioni dovrò collezionarle in un db e non saranno a priori prevedibili gli scarti temporali fra un operazione e un altra.. cosa mi consigli di fare?
    e semmai vi sono soluzioni senza questo crontab? anche perchè ancora non ho comprato nessuno spazio da nessun provider…(sono in fase di ‘analisi’ diciamo così) dici che tutti i provider che supportano php e mysql suportano anche crontab?

  34. Giovanni scrive:

    Il metodo più semplice è sicuramente quello di scrivere su DB una tabella con tutte le schedulazioni e poi fare girare ogni minuto, nel crontab, uno script che verifica se ci sono schedulazioni da lanciare (quindi con data minori o uguali ad adesso.
    Il cron alcune società di hosting lo danno altre no, verifica una volta che hai deciso di mettere on line il tuo sistema.

  35. Scamitos scrive:

    Salve, ti volevo chiedere una cosa
    se debo inserire nel campo comando di crontab un if then else
    come faccio a gestire i new line??
    Cioè se scrivo if …then ….else… tutto su una riga non mi funziona, quindi dovrei fare
    if….
    then….
    else….
    ma non funziona nemmeno.
    potresti aiutarmi?

  36. Giovanni scrive:

    Devi fare un file di comandi e mettere nel crontab il lancio di quello.

  37. Giuseppe scrive:

    Ciao Giovanni, volevo kiedere una cosa:
    ho tre cammini con l’interprete php, quale scelgo?

    usr/bin/php;
    etc/alternatives/php
    var/lib/rpm/alternatives/php

    Grazie. Ciao

  38. Giovanni scrive:

    Mi verrebbe da dire il primo, comunque guarda quale dei 3 è più recente.

  39. idkkid scrive:

    ciao, complimenti per l’ articolo, vorrei farti una domanda, ma per fermare poi questo, devo per forza killare contrab, o c’ è un altra opzione ?
    oppure c’ è un modo per farlo fermare quando voglio ?

    grazie . . .

  40. Giovanni scrive:

    Per fermare il crontab è sufficiente editarlo (crontab -e) e cancellare la riga, oppure commentarla con un # davanti, oppure cambiare gli orari e rischedularli. Automaticamente il cron aggiornerà le schedulazioni.

  41. idkkid scrive:

    grazie molte . . .

  42. Abby scrive:

    Ciao!
    Sto lottando anche io con questi affari..ma senza risultati..
    In poche parole devo creare uno script php che mi esegua un\’operazione di controllo su un database ad una certa ora del giorno.
    Prima di procedere con l\’implementazione, sto facendo una prova con uno script molto semplice..

    lo script php e` il seguente

    poi inserisco il comando con crontab -e

    46 16 * * * /app/path_applicazione/php/bin/php /app/path_applicazione/autappl/automatic.php > /app/path_applicazione/autappl/log.txt

    Ci sono un po\’ di cose che non vanno..
    1)Se inserisco tale comando con crontab -e non mi viene visualizzato nel file /etc/crontab

    2)lo script non viene eseguito.

    Inoltre, questo script deve essere utilizzabile all\’interno di un sistema di gestione documentale che e` provvisto del suo apache e del suo mysql e quindi anche del suo php (motivo per cui il path dell\’interprete e` /app/path_applicazione/php/bin/php).
    Sapresti darmi qualche suggerimento??
    Grazie
    Abby

  43. Giovanni scrive:

    Alcuni controlli:

    1) è attivo il demone del cron (crond)?
    2) viene creato il file di log /app/path_applicazione/autappl/log.txt alle 16:46 di ogni giorno?
    3) crontab -e è eseguito da un utente che ha accesso all’appliazione?
    4) per vedere il crontab attivo basta fare crontab -l
    5) se il programma php solitamente gira sotto un certo ambiente potrebbe avere bisogno di particolari variabili d’ambiente

  44. k8 scrive:

    Ottimo, molto utile!
    Grazie mille.

Scrivi un commento

This is a captcha-picture. It is used to prevent mass-access by robots. (see: www.captcha.net)

Per inserire il Commento scrivi i 4 caratteri riportati nell'immagine. Possono essere numeri da 0..9 o lettere A..F, alla fine click sul tasto Invia.

  

Se non riesci a leggere l'immagine generane un'altra