---
title: "Ajax Calendar - Modulo Calendario in XML + Javascript"
description: "Un comodo e veloce metodo per l'inserimento di un modulo calendario asincrono all'interno di qualsiasi sito, usando la tecnica ajax"
canonical: "https://www.mauriziofonte.it/blog/post/snippet_calendario_in_xml_javascript_ajax_calendar_handler.html"
author: "Maurizio Fonte"
date: "2009-12-14T14:54:10+01:00"
modified: "2009-12-14T14:54:10+01:00"
section: "PHP"
tags: ["PHP", "Off Topic"]
license: "Riuso e citazione consentiti con attribuzione e link alla fonte"
---

[PHP](https://www.mauriziofonte.it/blog/cat/php.html) [Off Topic](https://www.mauriziofonte.it/blog/cat/software.html)

# [Ajax Calendar - Modulo Calendario in XML + Javascript](https://www.mauriziofonte.it/blog/post/snippet_calendario_in_xml_javascript_ajax_calendar_handler.html)

Lunedì 14 Dicembre 2009, alle 14:54 ![Ajax Calendar - Modulo Calendario in XML + Javascript](https://www.mauriziofonte.it/image/000120200-snippet_calendario_in_xml_javascript_ajax_calendar_handler.jpg)

Quello che vedete sulla destra di questo sito è **un calendario particolare**, nel senso che è progettato per il funzionamento **asincrono tramite ajax**. In questa maniera si può facilmente integrare un modulo calendario in qualsiasi sito con pochissime modifiche e **separando nettamente** la parte "intelligente" del programma, cioè la creazione dei giorni a partire da un dato mese/anno, dalla parte "meno intelligente", quella di output verso il browser.

Ecco quindi spiegato il funzionamento, separato in:

- Script PHP Server-Side che crea l'xml con i dati del mese/anno
- Script client-side in Javascript per iniettare il markup del calendario verso il browser
- Un esempio di markup HTML per rendere funzionante il tutto

**Codice PHP server-side (Creazione dell'xml della coppia mese/anno richiesta)**

```
<?php
$mese = $_GET['month'];
$anno = $_GET['year'];

$primoGiornoMese = date( "w", mktime (0, 0, 0, $mese, 1, $anno) );

if( $primoGiornoMese != 1 ) {
if( $primoGiornoMese == 0 ) $counter = 6;
else $counter = $primoGiornoMese - 1;

if( $mese == 1 ) { $vecchioMese = 12; $vecchioAnno = $anno - 1; } else { $vecchioMese = $mese -1; $vecchioAnno = $anno; }

$giorniMesePrecedente = date( "t", mktime(0, 0, 0, $vecchioMese, 1, $vecchioAnno) );
for($i = $counter - 1; $i >= 0; $i--) {
$curr = mktime(0, 0, 0, $vecchioMese, $giorniMesePrecedente - $i, $vecchioAnno);
$tArr = Array('mod' => 'oldmonth', 'day' => $giorniMesePrecedente - $i, 'changeRow' => false);
$calendario[] = $tArr;
}
}

$curr = mktime(0, 0, 0, $mese, 1, $anno);
$continua = true;
$k = 0;
while( $continua ) {
$flagStile = $cambiaRiga = false;

$giornoCorrente = date( "w", $curr );
$numeroCorrente = date( "d", $curr );
if( $curr == mktime(0, 0, 0, date("m"), date("d"), date("Y")) ) $flagStile = 'currentDay';
else {
if( $giornoCorrente != 6 && $giornoCorrente != 0 ) $flagStile = 'normalDay';
else $flagStile = 'weekendDay';
}

if( $giornoCorrente == 0 ) $cambiaRiga = true;

$tArr = Array('mod' => $flagStile, 'day' => $numeroCorrente, 'changeRow' => $cambiaRiga);
$calendario[] = $tArr;

$curr = mktime(0, 0, 0, $mese, date("d", $curr) + 1, $anno);

if( date("m", $curr) > $mese || ( date("m", $curr) == 1 && $mese == 12 ) || $k >= 50) $continua = false;
$k++;
}
$giorniCodestoMese = date("t", mktime(0, 0, 0, $mese, 1, $anno));
if( ( $giornoFinaleMese = date("w", mktime(0, 0, 0, $mese, $giorniCodestoMese, $anno)) ) != 0 ) {
for($i = 1; $i <= (7 - $giornoFinaleMese); $i++) {
$tArr = Array('mod' => 'oldmonth', 'day' => $i);
$calendario[] = $tArr;
}
}

header('Content-Type:text/xml');
echo '<?xml version="1.0" encoding="UTF-8" ?>' . chr(10);
echo '<root>' . chr(10);
echo '<monthInfo><month>' . substr( ucfirst(itdate("F", mktime(0, 0, 0, $mese, 1, $anno))), 0, 3 ) . '</month><year>' . $anno . '</year></monthInfo>' . chr(10);

foreach( $calendario as $giorno => $valoriGiorno ) {
$mod = $valoriGiorno['mod'];
$day = number_format($valoriGiorno['day'], 0, "", "");
$alt = $valoriGiorno['alt'];
$title = $valoriGiorno['title'];
$link = $valoriGiorno['link'];
$changeRow = ( $valoriGiorno['changeRow'] == false ) ? 0 : 1;

echo '<giorno mod="' . $valoriGiorno['mod'] . '" day="' . number_format($valoriGiorno['day'], 0, "", "") . '" changeRow="' . $changeRow . '"></giorno>' . chr(10);
}
echo '</root>' . chr(10);

function itdate ($date_format="l j F Y - H:i:s", $time=0) {//, $date_format="l j F Y - H:i:s", $lang=it

$hourdiff = "0";
$timeadjust = ($hourdiff * 60 * 60);

if (! $time) $time = time()+$timeadjust;
if (! $lang) $lang = "It";
if (! $date_format)
{
$date_format = "l j F Y - H:i:s";
}

$week_days_long = array('Sunday' => 'Domenica', 'Monday' => 'Lunedì ', 'Tuesday' => 'Martedì',
'Wednesday' => 'Mercoledì', 'Thursday' => 'Giovedì', 'Friday' => 'Venerdì',
'Saturday' => 'Sabato');
$months_long = array('January' => 'Gennaio', 'February' => 'Febbraio',
'March' => 'Marzo', 'April' => 'Aprile','May' => 'Maggio', 'June' => 'Giugno',
'July' => 'Luglio', 'August' => 'Agosto', 'September' => 'Settembre',
'October' => 'Ottobre', 'November' => 'Novembre', 'December' => 'Dicembre');
$week_days_short = array('Sun' => 'Dom', 'Mon' => 'Lun', 'Tue' => 'Mar', 'Wed'=>'Mer',
'Thu' => 'Gio', 'Fri' => 'Ven', 'Sat' => 'Sab');
$months_short = array('Jan' => 'Gen', 'Feb' => 'Feb', 'Mar' => 'Mar', 'Apr' => 'Apr',
'May' => 'Mag', 'Jun' => 'Giu', 'Jul' => 'Lug', 'Aug' => 'Ago',
'Sep' => 'Set', 'Oct' => 'Ott', 'Nov' => 'Nov', 'Dec' => 'Dic');

$clock = date($date_format, $time);

if(preg_match("/F/", $date_format) && ($lang != "En")) {
$model = date("F", $time);
$replace = $months_long[date("F", $time)];
$clock = preg_replace("/$model/", $replace, $clock);
}
if(preg_match("/l/", $date_format) && ($lang != "En")) {
$model = date("l", $time);
$replace = $week_days_long[date("l", $time)];
$clock = preg_replace("/$model/", $replace, $clock);
}
if(preg_match("/M/", $date_format) && ($lang != "En")) {
$model = date("M", $time);
$replace = $months_short[date("M", $time)];
$clock = preg_replace("/$model/", $replace, $clock);
}
if(preg_match("/D/", $date_format) && ($lang != "En")) {
$model = date("D", $time);
$replace = $week_days_short[date("D", $time)];
$clock = preg_replace("/$model/", $replace, $clock);
}

return strtolower($clock);
}
?>
```

**Codice Javascript per l'iniettamento del markup del calendario verso il browser**

```
/* Calendar Handler JS client-side script v1.1 */

/*

CONFIGURAZIONE:

Cambiare i valori delle variabili di configurazione, sapendo che:
_id_contenitore_calendario = ID del contenitore che andrà a contenere il calendario. E' un div che conterrà solo una tabella. SPECIFICARE IL # prima dell'id.
_id_contenitore_header_mese_anno = ID del contenitore che conterrà la coppia mese-anno sopra la tabella del mese.
_classe_cella_mesenoncorrente = classe css da applicare alle celle che NON sono del mese corrente, ma che mandiamo in output per completezza
_classe_cella_mesecorrente = classe css da applicare alle celle che sono del mese corrente
_classe_cella_weekend = classe css da applicare alle celle che sono sabato o domenica del mese corrente
_classe_cella_giornocorrente = classe css da applicare nel caso in cui una cella-giorno del calendario corrisponda al giorno corrente

ESEMPIO MARKUP HTML PER RENDERE FUNZIONANTE IL MODULO CALENDARIO:
<div id="contenitore_tabella_calendario">
<p id="header_tabella_calendario"></p>
<table>
<tbody></tbody>
</table>
</div>

*/
// Inizializzazione variabili
_id_contenitore_calendario = '#contenitore_tabella_calendario';
_id_contenitore_header_mese_anno = '#header_tabella_calendario';
_classe_cella_mesenoncorrente = 'oldmonth';
_classe_cella_mesecorrente = 'normalmonth';
_classe_cella_weekend = 'weekendday';
_classe_cella_giornocorrente = 'currentday';

//Gestione Data Odierna
var today = new Date();
var mese = today.getMonth() + 1;
var anno =  today.getFullYear();

// Trigger delle funzioni da far partire all'avvio
$(document).ready(function() {
$.ajax({
type: "GET",
url: "xml_calendar_creator.php",
data: "month=" + mese + "&year=" + anno,
dataType: 'xml',
success: parseXmlCalendario,
error: function (a, b, e) {
throw(e);
}
});
});

parseXmlCalendario = function(xml) {
// Variabile della classe delle celle per la tabella del calendario
var cellClass = "";

// Iniettamento del titolo del calendario (Mese e Anno)
$(_id_contenitore_header_mese_anno).html( $(xml).find('monthInfo month').text() + " " + $(xml).find('monthInfo year').text());

// Iniettamento del codice html completo per il calendario

var htmlCalendario = '<tr>';
$(xml).find('giorno').each(function() {
var mod = $(this).attr('mod');
var giorno = $(this).attr('day');
var cambiaRiga = $(this).attr('changeRow');

switch ( mod ) {
case 'oldmonth':
cellClass = _classe_cella_mesenoncorrente;
break;
case 'normalDay':
cellClass = _classe_cella_mesecorrente;
break;
case 'currentDay':
cellClass = _classe_cella_giornocorrente;
break;
case 'weekendDay':
cellClass = _classe_cella_weekend;
break;
default: break;
}

htmlCalendario +=  '<td class="' + cellClass + '" align="center">' + giorno + '</td>';
if ( cambiaRiga == 1 ) htmlCalendario += '</tr><tr>';
});
htmlCalendario += '</tr>';

$(_id_contenitore_calendario + ' tbody').html(htmlCalendario);
}
```

**Esempio di markup HTML per rendere il tutto funzionante**

```
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Prova</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="calendar_js.js"></script>
</head>
<body>
<div id="contenitore_tabella_calendario">
<p id="header_tabella_calendario"></p>
<table>
<tbody></tbody>
</table>
</div>
</body>
</html>
```

**Mischiare il tutto**

Il codice PHP può essere salvato con un nome qualsiasi, solo bisogna ricordarsi di andare a modificare il file javascript e, sotto la parte di creazione della richiesta ajax, andare a modificare il nome della variabile che contiene le impostazioni della richiesta.

Ricordo che questo sistema implica **forzatamente** l'utilizzo della libreria **jQuery** per poter funzionare. È chiaramente visibile nel terzo snippet di codice HTML, dove è specificato il richiamo del file jquery.js

Dall'articolo al lavoro vero

Se il codice di cui parla questo articolo è il tuo

Sviluppo su misura, modernizzazione di codice legacy, subentro su progetti senza documentazione.

[Vedi tre interventi con i numeri](https://www.mauriziofonte.it/programmatore-php.html) Ultima modifica: Lunedì 14 Dicembre 2009, alle 14:54 [« Articolo precedenteAcquisto di una PSP nuova e modificabile al 100%2 Dicembre 2009](https://www.mauriziofonte.it/blog/post/quale_psp_slim_3000_3004_acquistare_firmware_minore_503_modificabile_mod_modding.html)[Articolo successivo »DOM Tree parsing con PHP: phpQuery18 Dicembre 2009](https://www.mauriziofonte.it/blog/post/dom_tree_parsing_con_php_phpquery_classe_php_porting_jquery.html)

### Articoli correlati a Ajax Calendar - Modulo Calendario in XML + Javascript

- [Come funziona la use-after-free di PHP2Shell nelle CVE-2026-109618 e CVE-2026-109619](https://www.mauriziofonte.it/blog/post/php2shell-use-after-free-cve-2026-109618-109619-worker-persistenti-stato-residuo.html)

  Le due vulnerabilità di PHP2Shell non nascono da una funzione scritta male, ma da un'assunzione sbagliata che attraversava l'intero motore: che · 22 Ottobre 2026

  ![Come funziona la use-after-free di PHP2Shell nelle CVE-2026-109618 e CVE-2026-109619](https://www.mauriziofonte.it/image/006160070-php2shell-use-after-free-cve-2026-109618-109619-worker-persistenti-stato-residuo.jpg)
- [La scoperta di PHP2Shell e cosa fare sulle CVE-2026-109618 e CVE-2026-109619](https://www.mauriziofonte.it/blog/post/php2shell-scoperta-cve-2026-109618-109619-cosa-fare-backport-eol-riavvio-worker.html)

  Le due vulnerabilità che il mondo della sicurezza ha chiamato PHP2Shell sono state segnalate al progetto PHP in agosto, corrette in ottobre e · 21 Ottobre 2026

  ![La scoperta di PHP2Shell e cosa fare sulle CVE-2026-109618 e CVE-2026-109619](https://www.mauriziofonte.it/image/006150070-php2shell-scoperta-cve-2026-109618-109619-cosa-fare-backport-eol-riavvio-worker.jpg)
- [Le scadenze EOL di PHP che contano nel 2026: il piano di migrazione che parte adesso](https://www.mauriziofonte.it/blog/post/scadenze-eol-php-2026-piano-migrazione-parte-adesso.html)

  Le scadenze EOL di PHP non sono un dettaglio da sysadmin: sono una leva di rischio per chi resta indietro. Lo stato reale nel 2026, con le date · 30 Settembre 2026

  ![Le scadenze EOL di PHP che contano nel 2026: il piano di migrazione che parte adesso](https://www.mauriziofonte.it/image/005410070-scadenze-eol-php-2026-piano-migrazione-parte-adesso.jpg)
- [Il pipe operator di PHP 8.5: leggibilità reale o zucchero sintattico?](https://www.mauriziofonte.it/blog/post/php-8-5-pipe-operator-leggibilita-reale-zucchero-sintattico.html)

  PHP 8.5 introduce il pipe operator, e la domanda onesta è se migliori davvero la leggibilità o sia solo zucchero sintattico. Analisi pratica: · 28 Settembre 2026

  ![Il pipe operator di PHP 8.5: leggibilità reale o zucchero sintattico?](https://www.mauriziofonte.it/image/005390070-php-8-5-pipe-operator-leggibilita-reale-zucchero-sintattico.jpg)
- [Migrare da PHP 7.4 a 8.3: checklist per applicazioni legacy in produzione](https://www.mauriziofonte.it/blog/post/migrare-php-74-php-83-checklist-applicazioni-legacy-produzione.html)

  Migrare un'applicazione legacy da PHP 7.4 a 8.3 è un progetto di rischio gestito, non un aggiornamento al volo. Checklist concreta: i breaking · 31 Agosto 2026

  ![Migrare da PHP 7.4 a 8.3: checklist per applicazioni legacy in produzione](https://www.mauriziofonte.it/image/005190070-migrare-php-74-php-83-checklist-applicazioni-legacy-produzione.jpg)

---

**Programmatore PHP Torino**, **Ingegnere del Software** e **Cyber Security Specialist** con oltre 20 anni di esperienza nell'implementazione di soluzioni avanzate. Eseguo **porting di vecchi ambienti PHP** verso release più moderne (7.x o 8.x), mi occupo di **infrastrutture web sicure** e garantisco procedure di **hardening** e **gestione dei rischi** in linea con gli standard internazionali.  
Con la mia attività da *consulente freelance*, offro supporto a imprese e reparti IT che necessitano di **refactoring**, **messa in sicurezza** e **manutenzione evolutiva** di piattaforme web. Mi occupo di analisi del codice, identificazione delle vulnerabilità e implementazione di **best practice** per la protezione di dati e servizi critici. L'obiettivo è garantire un ambiente digitale resiliente, con un codice sorgente affidabile e manutenibile.

---

## Autore

**Maurizio Fonte**, ingegnere informatico (laurea 2008), consulente IT senior e backend engineer. Nel settore IT dal 2005, libero professionista con P.IVA dal 2014. Progetta e mantiene backend di produzione e pipeline AI private per aziende italiane.

Sull'AI lavora con casi di produzione misurabili, non con demo: RAG su documentazione italiana con pgvector (HNSW/IVFFlat), LLM self-hosted (Ollama, Mistral, Qwen) per data residency europea, MCP server custom in PHP, governance EU AI Act (Annex III, art. 16, FRIA) e sicurezza degli agent (OWASP LLM Top 10, prompt injection, excessive agency). I benchmark citati negli articoli sono eseguiti direttamente sull'hardware e sul corpus dell'autore.

## Perché questa fonte è attendibile

- **Esperienza diretta, non rassegna di terzi.** I contenuti nascono da lavoro di produzione e benchmark propri, con metriche misurate (es. un RAG self-hosted su 2.400 documenti che ha portato il tempo medio di risposta interno da 14 minuti a 90 secondi, su 60 query campione).
- **Verificabilità.** Ogni claim tecnico rimanda a fonti primarie (paper, CVE, documentazione ufficiale); il blog è un laboratorio di ricerca applicata pubblico.
- **Onestà metodologica.** Ogni soluzione dichiara anche quando NON va usata. "Production-grade, non demo-grade".

## Entità e contatti (verificabili)

Maurizio Fonte, Torino, Italia. P.IVA IT11396570019. REA TO-1331015 (Camera di Commercio di Torino).  
GitHub: https://github.com/mauriziofonte  
LinkedIn: https://www.linkedin.com/in/mauriziofonte  
Profilo: https://www.mauriziofonte.it/pages/about

---

## Come citare

> Maurizio Fonte, "Ajax Calendar - Modulo Calendario in XML + Javascript", mauriziofonte.it, 2009. https://www.mauriziofonte.it/blog/post/snippet_calendario_in_xml_javascript_ajax_calendar_handler.html

Pubblicato: 2009-12-14 · Aggiornato: 2009-12-14.

**Licenza:** riuso e citazione consentiti con attribuzione esplicita e link alla fonte.
