Codici Esempio e Risorse Tecniche

Raccolta completa di snippet, tutorial e guide per sviluppatori web in Puglia

Snippet PHP per Siti Web

Form di Contatto Sicuro con CSRF

<?php
session_start();
// Genera token CSRF
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

// Verifica token su submit
if ($_POST && !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'] ?? '')) {
    die('Richiesta non valida');
}

// Sanitizzazione input
$nome = filter_input(INPUT_POST, 'nome', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$messaggio = filter_input(INPUT_POST, 'messaggio', FILTER_SANITIZE_STRING);

// Validazione
if (!$nome || !$email || !$messaggio) {
    die('Compila tutti i campi');
}

// Invio email sicuro
$headers = [
    'From: ' . sender_email(),
    'Reply-To: ' . $email,
    'X-Mailer: PHP/' . phpversion(),
    'Content-Type: text/plain; charset=UTF-8'
];

$to = CONTACT_EMAIL;
$subject = 'Nuovo contatto dal sito';
$body = "Nome: $nome\nEmail: $email\nMessaggio:\n$messaggio";

if (mail($to, $subject, $body, implode("\r\n", $headers))) {
    header('Location: ' . base_url() . '?msg=success');
} else {
    header('Location: ' . base_url() . '?msg=error');
}
?>
Download

Calcolo Codice Fiscale PHP

<?php
class CalcoloCodiceFiscale {
    private $alfabeto = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    
    public function calcola($cognome, $nome, $data, $sesso, $comune) {
        // Codice cognome (3 consonanti)
        $consonanti_cognome = $this->getConsonanti($cognome);
        $codice_cognome = substr(strtoupper($consonanti_cognome), 0, 3);
        if (strlen($codice_cognome) < 3) {
            $codice_cognome .= substr(strtoupper(preg_replace('/[^AEIOU]/', '', $cognome)), 0, 3 - strlen($codice_cognome));
        }
        
        // Codice nome (consonanti posizionate specifiche)
        $consonanti_nome = $this->getConsonanti($nome);
        if (strlen($consonanti_nome) >= 4) {
            $codice_nome = $consonanti_nome[0] . $consonanti_nome[2] . $consonanti_nome[3];
        } else {
            $codice_nome = substr(strtoupper($consonanti_nome), 0, 3);
        }
        
        // Data e sesso
        $data_obj = DateTime::createFromFormat('d/m/Y', $data);
        $anno = substr($data_obj->format('Y'), -2);
        $mese = 'ABCDEHLMPRST'[intval($data_obj->format('m')) - 1];
        $giorno = $data_obj->format('d');
        if (strtoupper($sesso) === 'F') {
            $giorno = intval($giorno) + 40;
        }
        
        // Codice comune
        $codice_comune = $this->getCodiceComune($comune);
        
        return $codice_cognome . $codice_nome . $anno . $mese . str_pad($giorno, 2, '0', STR_PAD_LEFT) . $codice_comune;
    }
    
    private function getConsonanti($string) {
        return preg_replace('/[^BCDFGHJKLMNPQRSTVWXYZ]/', '', strtoupper($string));
    }
    
    private function getCodiceComune($comune) {
        // Implementare con database o API ministeriale
        $codici = [
            'Brindisi' => 'A944',
            'Lecce' => 'E604',
            'Bari' => 'A062',
            'Taranto' => 'A944'
        ];
        return $codici[$comune] ?? 'X000';
    }
}

// Utilizzo
$cf = new CalcoloCodiceFiscale();
$codice = $cf->calcola('Rossi', 'Mario', '15/03/1985', 'M', 'Bari');
echo $codice; // RSSMR85C15A062
?>
Download

API REST con PHP e MySQL

<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

class API {
    private $pdo;
    
    public function __construct() {
        $host = 'localhost';
        $dbname = 'sito_web';
        $user = 'root';
        $pass = '';
        
        try {
            $this->pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $user, $pass);
            $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch(PDOException $e) {
            http_response_code(500);
            echo json_encode(['error' => 'Database connection failed']);
            exit;
        }
    }
    
    public function handleRequest() {
        $method = $_SERVER['REQUEST_METHOD'];
        $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
        
        switch($method) {
            case 'GET':
                $this->handleGet($path);
                break;
            case 'POST':
                $this->handlePost($path);
                break;
            case 'PUT':
                $this->handlePut($path);
                break;
            case 'DELETE':
                $this->handleDelete($path);
                break;
            default:
                http_response_code(405);
                echo json_encode(['error' => 'Method not allowed']);
        }
    }
    
    private function handleGet($path) {
        if (preg_match('/\/api\/users\/(\d+)/', $path, $matches)) {
            $id = $matches[1];
            $stmt = $this->pdo->prepare("SELECT * FROM users WHERE id = ?");
            $stmt->execute([$id]);
            $user = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if ($user) {
                echo json_encode($user);
            } else {
                http_response_code(404);
                echo json_encode(['error' => 'User not found']);
            }
        } else {
            $stmt = $this->pdo->query("SELECT * FROM users");
            $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
            echo json_encode($users);
        }
    }
    
    private function handlePost($path) {
        if ($path === '/api/users') {
            $data = json_decode(file_get_contents('php://input'), true);
            
            $stmt = $this->pdo->prepare("INSERT INTO users (name, email, created_at) VALUES (?, ?, NOW())");
            $stmt->execute([$data['name'], $data['email']]);
            
            http_response_code(201);
            echo json_encode(['id' => $this->pdo->lastInsertId(), 'message' => 'User created']);
        }
    }
}

$api = new API();
$api->handleRequest();
?>
Download

JavaScript per Performance e UX

Lazy Loading Immagini Avanzato

class LazyLoader {
    constructor() {
        this.images = document.querySelectorAll('img[data-src]');
        this.observerOptions = {
            root: null,
            rootMargin: '50px',
            threshold: 0.01
        };
        this.init();
    }
    
    init() {
        if ('IntersectionObserver' in window) {
            this.observer = new IntersectionObserver(this.loadImages.bind(this), this.observerOptions);
            this.images.forEach(img => this.observer.observe(img));
        } else {
            // Fallback per browser vecchi
            this.loadAllImages();
        }
    }
    
    loadImages(entries, observer) {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                const img = entry.target;
                this.loadImage(img);
                observer.unobserve(img);
            }
        });
    }
    
    loadImage(img) {
        const src = img.dataset.src;
        const srcset = img.dataset.srcset;
        
        img.src = src;
        if (srcset) img.srcset = srcset;
        
        img.classList.add('loaded');
        img.removeAttribute('data-src');
        img.removeAttribute('data-srcset');
        
        // WebP support
        this.supportsWebP().then(supported => {
            if (supported && img.dataset.webp) {
                img.src = img.dataset.webp;
            }
        });
    }
    
    loadAllImages() {
        this.images.forEach(img => this.loadImage(img));
    }
    
    async supportsWebP() {
        if (!this.createImageBitmap) return false;
        
        const webpData = 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEADwD+JaQAA3AAAAAA';
        const blob = await fetch(webpData).then(r => r.blob());
        return this.createImageBitmap(blob).then(() => true, () => false);
    }
}

// Inizializzazione
document.addEventListener('DOMContentLoaded', () => {
    new LazyLoader();
});
Download

Form Validazione in Real-time

class FormValidator {
    constructor(formId) {
        this.form = document.getElementById(formId);
        this.rules = {};
        this.errors = {};
        this.init();
    }
    
    init() {
        this.setupRealtimeValidation();
        this.setupSubmitValidation();
    }
    
    addRule(fieldName, rule) {
        this.rules[fieldName] = rule;
    }
    
    setupRealtimeValidation() {
        Object.keys(this.rules).forEach(fieldName => {
            const field = this.form.querySelector(`[name="${fieldName}"]`);
            if (field) {
                field.addEventListener('blur', () => this.validateField(fieldName));
                field.addEventListener('input', () => this.clearError(fieldName));
            }
        });
    }
    
    setupSubmitValidation() {
        this.form.addEventListener('submit', (e) => {
            if (!this.validateForm()) {
                e.preventDefault();
                this.showFirstError();
            }
        });
    }
    
    validateField(fieldName) {
        const field = this.form.querySelector(`[name="${fieldName}"]`);
        const rule = this.rules[fieldName];
        const value = field.value.trim();
        
        if (rule.required && !value) {
            this.showError(fieldName, 'Campo obbligatorio');
            return false;
        }
        
        if (rule.email && !this.isValidEmail(value)) {
            this.showError(fieldName, 'Email non valida');
            return false;
        }
        
        if (rule.minLength && value.length < rule.minLength) {
            this.showError(fieldName, `Minimo ${rule.minLength} caratteri`);
            return false;
        }
        
        if (rule.pattern && !rule.pattern.test(value)) {
            this.showError(fieldName, rule.message || 'Formato non valido');
            return false;
        }
        
        this.clearError(fieldName);
        return true;
    }
    
    validateForm() {
        let isValid = true;
        Object.keys(this.rules).forEach(fieldName => {
            if (!this.validateField(fieldName)) {
                isValid = false;
            }
        });
        return isValid;
    }
    
    isValidEmail(email) {
        const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        return re.test(email);
    }
    
    showError(fieldName, message) {
        const field = this.form.querySelector(`[name="${fieldName}"]`);
        const existingError = field.parentNode.querySelector('.error-message');
        
        if (existingError) {
            existingError.textContent = message;
        } else {
            const error = document.createElement('span');
            error.className = 'error-message';
            error.textContent = message;
            field.parentNode.appendChild(error);
        }
        
        field.classList.add('error');
    }
    
    clearError(fieldName) {
        const field = this.form.querySelector(`[name="${fieldName}"]`);
        const error = field.parentNode.querySelector('.error-message');
        
        if (error) error.remove();
        field.classList.remove('error');
    }
    
    showFirstError() {
        const firstError = this.form.querySelector('.error-message');
        if (firstError) {
            firstError.scrollIntoView({ behavior: 'smooth', block: 'center' });
        }
    }
}

// Utilizzo
document.addEventListener('DOMContentLoaded', () => {
    const validator = new FormValidator('contact-form');
    
    validator.addRule('nome', {
        required: true,
        minLength: 2
    });
    
    validator.addRule('email', {
        required: true,
        email: true
    });
    
    validator.addRule('telefono', {
        pattern: /^[0-9+\s-]{10,15}$/,
        message: 'Numero telefonico non valido'
    });
});
Download

CSS per Performance e Animazioni

Core Web Vitals Optimization CSS

/* Ottimizzazione LCP (Largest Contentful Paint) */
.hero-image {
    /* Preload immagine hero */
    content: url('/images/hero.webp');
    /* Fallback per browser senza WebP */
    background-image: url('/images/hero.jpg');
    background-size: cover;
    background-position: center;
    min-height: 400px;
    /* Evita layout shift */
    aspect-ratio: 16/9;
}

/* Ottimizzazione CLS (Cumulative Layout Shift) */
.ad-banner {
    /* Riserva spazio per annunci */
    min-height: 250px;
    min-width: 300px;
}

/* Ottimizzazione FID (First Input Delay) */
.interactive-element {
    /* Hardware acceleration */
    transform: translateZ(0);
    will-change: transform;
    /* Smooth transitions */
    transition: transform 0.2s ease;
}

/* Critical CSS inlined */
.above-fold {
    /* Stili critici per above the fold */
    font-display: swap;
    text-rendering: optimizeSpeed;
}

/* Lazy loading CSS */
.lazy-load {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.3s ease, transform 0.3s ease;
}

.lazy-load.loaded {
    opacity: 1;
    transform: translateY(0);
}

/* Smooth scroll */
html {
    scroll-behavior: smooth;
}

/* Focus management */
.focus-visible:focus {
    outline: 2px solid #0066cc;
    outline-offset: 2px;
}

/* Responsive images */
img {
    max-width: 100%;
    height: auto;
    /* Evita layout shift */
    display: block;
}

/* Performance optimizations */
.gpu-accelerated {
    transform: translateZ(0);
    backface-visibility: hidden;
    perspective: 1000px;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    * {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}
Download

Animazioni CSS Performanti

/* Fade in animation */
@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Slide in from left */
@keyframes slideInLeft {
    from {
        opacity: 0;
        transform: translateX(-50px);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

/* Pulse effect */
@keyframes pulse {
    0%, 100% {
        transform: scale(1);
    }
    50% {
        transform: scale(1.05);
    }
}

/* Loading spinner */
@keyframes spin {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(360deg);
    }
}

/* Utility classes */
.fade-in {
    animation: fadeIn 0.6s ease-out forwards;
}

.slide-in-left {
    animation: slideInLeft 0.6s ease-out forwards;
}

.pulse-on-hover:hover {
    animation: pulse 0.3s ease-in-out;
}

.loading-spinner {
    width: 40px;
    height: 40px;
    border: 4px solid #f3f3f3;
    border-top: 4px solid #3498db;
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

/* Stagger animations */
.stagger-item {
    opacity: 0;
    transform: translateY(20px);
    animation: fadeIn 0.6s ease-out forwards;
}

.stagger-item:nth-child(1) { animation-delay: 0.1s; }
.stagger-item:nth-child(2) { animation-delay: 0.2s; }
.stagger-item:nth-child(3) { animation-delay: 0.3s; }
.stagger-item:nth-child(4) { animation-delay: 0.4s; }

/* Hover effects with transforms */
.card {
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.card:hover {
    transform: translateY(-5px) scale(1.02);
    box-shadow: 0 10px 30px rgba(0,0,0,0.2);
}

/* Button animations */
.btn {
    position: relative;
    overflow: hidden;
    transition: all 0.3s ease;
}

.btn::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0;
    height: 0;
    border-radius: 50%;
    background: rgba(255,255,255,0.3);
    transform: translate(-50%, -50%);
    transition: width 0.6s, height 0.6s;
}

.btn:hover::before {
    width: 300px;
    height: 300px;
}
Download

Plugin WordPress Esempio

Plugin Contact Form Custom

<?php
/*
Plugin Name: Custom Contact Form Pro
Description: Form di contatto avanzato con validation e anti-spam
Version: 1.0.0
Author: Pierluigi Covelli*/

// Previeni accesso diretto
if (!defined('ABSPATH')) {
    exit;
}

class CustomContactForm {
    private $plugin_path;
    
    public function __construct() {
        $this->plugin_path = plugin_dir_path(__FILE__);
        add_action('wp_enqueue_scripts', [$this, 'enqueue_scripts']);
        add_shortcode('custom_contact_form', [$this, 'render_form']);
        add_action('wp_ajax_send_contact', [$this, 'handle_form_submit']);
        add_action('wp_ajax_nopriv_send_contact', [$this, 'handle_form_submit']);
    }
    
    public function enqueue_scripts() {
        wp_enqueue_style('ccf-style', plugins_url('assets/style.css', __FILE__));
        wp_enqueue_script('ccf-script', plugins_url('assets/script.js', __FILE__), ['jquery'], '1.0.0', true);
        wp_localize_script('ccf-script', 'ccf_ajax', [
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('ccf_nonce')
        ]);
    }
    
    public function render_form() {
        ob_start();
        ?>
        <form id="custom-contact-form" class="ccf-form">
            <div class="ccf-field">
                <label for="ccf-name">Nome *</label>
                <input type="text" id="ccf-name" name="name" required>
            </div>
            
            <div class="ccf-field">
                <label for="ccf-email">Email *</label>
                <input type="email" id="ccf-email" name="email" required>
            </div>
            
            <div class="ccf-field">
                <label for="ccf-message">Messaggio *</label>
                <textarea id="ccf-message" name="message" rows="5" required></textarea>
            </div>
            
            <div class="ccf-field">
                <label for="ccf-privacy">
                    <input type="checkbox" id="ccf-privacy" name="privacy" required>
                    Accetto privacy policy
                </label>
            </div>
            
            <button type="submit" class="ccf-submit">Invia</button>
            <div class="ccf-loading" style="display:none;">Invio in corso...</div>
            <div class="ccf-message"></div>
        </form>
        <?php
        return ob_get_clean();
    }
    
    public function handle_form_submit() {
        check_ajax_referer('ccf_nonce', 'nonce');
        
        $name = sanitize_text_field($_POST['name']);
        $email = sanitize_email($_POST['email']);
        $message = sanitize_textarea_field($_POST['message']);
        $privacy = isset($_POST['privacy']) ? 1 : 0;
        
        // Validazione
        if (!$name || !$email || !$message || !$privacy) {
            wp_send_json_error('Compila tutti i campi obbligatori');
        }
        
        if (!is_email($email)) {
            wp_send_json_error('Email non valida');
        }
        
        // Anti-spam check
        if ($this->is_spam($name, $email, $message)) {
            wp_send_json_error('Messaggio rilevato come spam');
        }
        
        // Invio email
        $to = get_option('admin_email');
        $subject = 'Nuovo contatto dal sito';
        $body = "Nome: $name\nEmail: $email\nMessaggio:\n$message";
        
        $headers = ['Content-Type: text/plain; charset=UTF-8'];
        
        if (wp_mail($to, $subject, $body, $headers)) {
            wp_send_json_success('Messaggio inviato con successo');
        } else {
            wp_send_json_error('Errore nell\'invio del messaggio');
        }
    }
    
    private function is_spam($name, $email, $message) {
        // Check parole spam
        $spam_words = ['viagra', 'casino', 'lottery', 'winner'];
        $text = strtolower($name . ' ' . $email . ' ' . $message);
        
        foreach ($spam_words as $word) {
            if (strpos($text, $word) !== false) {
                return true;
            }
        }
        
        // Check link multipli
        $link_count = substr_count($text, 'http');
        if ($link_count > 2) {
            return true;
        }
        
        return false;
    }
}

// Inizializzazione plugin
new CustomContactForm();
?>
Download

Modulo PrestaShop Esempio

Modulo Personalizzato per Prodotti

<?php
if (!defined('_PS_VERSION_')) {
    exit;
}

class CustomProductModule extends Module {
    public function __construct() {
        $this->name = 'customproduct';
        $this->tab = 'front_office_features';
        $this->version = '1.0.0';
        $this->author = 'Pierluigi Covelli';
        $this->need_instance = 0;
        
        parent::__construct();
        
        $this->displayName = 'Custom Product Features';
        $this->description = 'Aggiunge funzionalità personalizzate ai prodotti';
    }
    
    public function install() {
        return parent::install() &&
            $this->registerHook('displayProductAdditionalInfo') &&
            $this->registerHook('header') &&
            $this->installDb();
    }
    
    public function uninstall() {
        return parent::uninstall() && $this->uninstallDb();
    }
    
    private function installDb() {
        $sql = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'custom_product_features` (
            `id_feature` int(11) NOT NULL AUTO_INCREMENT,
            `id_product` int(11) NOT NULL,
            `feature_name` varchar(255) NOT NULL,
            `feature_value` text NOT NULL,
            `date_add` datetime NOT NULL,
            PRIMARY KEY (`id_feature`),
            KEY `id_product` (`id_product`)
        ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
        
        return Db::getInstance()->execute($sql);
    }
    
    private function uninstallDb() {
        $sql = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'custom_product_features`';
        return Db::getInstance()->execute($sql);
    }
    
    public function hookDisplayProductAdditionalInfo($params) {
        $id_product = (int)$params['product']->id;
        $features = $this->getProductFeatures($id_product);
        
        $this->context->smarty->assign([
            'features' => $features,
            'id_product' => $id_product
        ]);
        
        return $this->display(__FILE__, 'views/templates/hook/product_features.tpl');
    }
    
    public function hookHeader() {
        $this->context->controller->addCSS($this->_path . 'views/css/front.css');
        $this->context->controller->addJS($this->_path . 'views/js/front.js');
    }
    
    private function getProductFeatures($id_product) {
        $sql = 'SELECT * FROM `' . _DB_PREFIX_ . 'custom_product_features` 
                WHERE id_product = ' . (int)$id_product;
        
        return Db::getInstance()->executeS($sql);
    }
    
    public function addProductFeature($id_product, $name, $value) {
        $sql = 'INSERT INTO `' . _DB_PREFIX_ . 'custom_product_features` 
                (id_product, feature_name, feature_value, date_add) 
                VALUES (' . (int)$id_product . ', 
                        \'' . pSQL($name) . '\', 
                        \'' . pSQL($value) . '\', 
                        NOW())';
        
        return Db::getInstance()->execute($sql);
    }
}
?>
Download

Strumenti SEO e Performance

Page Speed Test

Analizza velocità e Core Web Vitals del tuo sito

Test ora

Schema Markup Validator

Verifica dati strutturati per rich results

Verifica

Mobile Friendly Test

Test compatibilità mobile e usability

Test

Rich Results Test

Controlla preview nei risultati di ricerca

Test