tekwork/framework 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

tekwork/framework

最新稳定版本:v0.6.0

Composer 安装命令:

composer require tekwork/framework

包简介

Mini framework PHP MVC avec routing avancé

README 文档

README

Packagist Version Packagist Downloads PHP Version License

Mini framework PHP MVC avec système de routing avancé, extrait de TekNotes.

⚠️ Note: Ceci est un projet d'apprentissage personnel. Il est fonctionnel mais n'a pas été audité pour une utilisation en production critique.

📋 Table des matières

✨ Caractéristiques

  • Architecture MVC légère et flexible
  • Routing dynamique avec paramètres et regex
  • Gestion des erreurs avec pages personnalisables (mode DEBUG/PRODUCTION)
  • Configuration par environnement (dev/staging/prod)
  • PSR-4 Autoloading via Composer
  • Controller/View pattern avec injection de dépendances
  • Patterns de sécurité prédéfinis pour validation
  • Aucune dépendance externe (PHP pur)

🚀 Installation

Démarrage rapide (recommandé)

La manière la plus rapide de démarrer avec Tekwork :

composer create-project tekwork/skeleton mon-projet
cd mon-projet

Projet prêt à l'emploi ! Structure complète, config auto-générée, exemples fonctionnels inclus.

👉 Voir tekwork/skeleton sur GitHub

Installation manuelle du framework seul

Si vous préférez construire votre structure vous-même :

Prérequis

  • PHP >= 8.0
  • Composer
  • Serveur web (Apache/Nginx) ou Laragon

Étapes

# 1. Installer via Composer
composer require tekwork/framework

# 2. Créer votre structure
mkdir -p app/Controllers app/views public

# 3. Créer le fichier de configuration
cp vendor/tekwork/framework/config.example.php config.php

# 4. Éditer config.php selon votre environnement
nano config.php

# 5. Configurer votre serveur web (voir ci-dessous)

Configuration serveur web

Nginx

server {
    listen 80;
    server_name monsite.local;
    root /chemin/vers/projet/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

Apache (.htaccess dans /public)

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]

⚙️ Configuration

Le fichier config.php (à la racine) gère les environnements :

<?php
return [
    // Mode debug
    // true  = Affichage détaillé des erreurs (développement)
    // false = Pages d'erreur personnalisées (production)
    'debug' => true,

    // Chemin vers les vues d'erreur personnalisées
    'error_views_path' => path_it(ROOT, 'app', 'views', 'errors'),

    // Chemin du fichier de logs
    'log_path' => path_it(ROOT, 'log', 'app_errors.log'),
];

Important :

  • config.php est dans .gitignore (jamais versionné)
  • config.example.php sert de modèle
  • Chaque environnement a sa propre configuration

📖 Utilisation

Structure du projet

projet/
├── src/                    # Framework core (ne pas modifier)
│   ├── Router.php
│   ├── Road.php
│   ├── Dispatcher.php
│   ├── Controller.php
│   ├── View.php
│   ├── ErrorHandler.php
│   └── ...
├── app/                    # Votre application
│   ├── bootstrap.php       # Définition des routes
│   ├── Controllers/        # Vos contrôleurs
│   └── views/              # Vos templates
│       └── errors/         # Pages d'erreur personnalisées (404.php, 500.php)
├── public/                 # Point d'entrée web
│   └── index.php
├── config.php              # Configuration (non versionné)
└── config.example.php      # Template de config

1. Définir des routes

Dans app/bootstrap.php :

use Tekwork\Router;
use Tekwork\Road;
use Tekwork\Dispatcher;
use Tekwork\Request;
use Tekwork\SecurityPatterns;

$router = new Router();

// Route simple (page d'accueil)
$router->add(
    new Road('', 'App\Controllers@HomeController:index', 'home')
);

// Route avec paramètre
$router->add(
    (new Road('article/{:slug}', 'App\Controllers@ArticleController:show', 'article.show'))
        ->rule('slug', SecurityPatterns::SLUG)
);

// Route avec wildcard (multi-segments)
$router->add(
    (new Road('docs/{:*path}', 'App\Controllers@DocsController:show', 'docs.show'))
        ->rule('path', SecurityPatterns::SAFE_PATH)
);

// Route avec valeurs par défaut
$router->add(
    (new Road('blog/{:page}', 'App\Controllers@BlogController:index', 'blog'))
        ->rule('page', '[0-9]+')
        ->default('page', '1')
);

// Dispatching
$request = new Request();
$dispatcher = new Dispatcher($router);
$dispatcher->dispatch($request->get_uri());

⚠️ Important: Les URIs ne commencent PAS par / :

  • Page d'accueil : '' (chaîne vide)
  • Autres routes : 'about', 'user/{:id}'

2. Créer un contrôleur

Dans app/Controllers/ArticleController.php :

<?php
namespace App\Controllers;

use Tekwork\Controller;
use Tekwork\View;

class ArticleController extends Controller
{
    public function show(): void
    {
        // Accès aux paramètres de route
        $slug = $this->params['slug'] ?? null;

        // Créer une vue avec chemin absolu
        $view = new View(path_it(ROOT, 'app', 'views', 'article.php'));

        // Injecter des variables
        $view->add_vars([
            'title' => 'Mon Article',
            'slug' => $slug,
            'content' => 'Lorem ipsum...'
        ]);

        // Rendu avec layout
        $layout = path_it(ROOT, 'app', 'views', 'layout.php');
        echo $this->render($layout, $view);
    }
}

3. Créer une vue

Dans app/views/article.php :

<article>
    <h1><?= htmlspecialchars($title) ?></h1>
    <p><?= htmlspecialchars($content) ?></p>
</article>

4. Créer un layout

Dans app/views/layout.php :

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>Mon Site</title>
</head>
<body>
    <header>
        <nav><!-- Menu --></nav>
    </header>
    <main>
        <?= $content ?> <!-- Contenu de la vue injectée -->
    </main>
    <footer>
        <p>&copy; 2025</p>
    </footer>
</body>
</html>

5. Pages d'erreur personnalisées

Créez app/views/errors/404.php et 500.php :

<!DOCTYPE html>
<html lang="fr">
<head>
    <title>404 - Page non trouvée</title>
</head>
<body>
    <h1>Page non trouvée</h1>
    <a href="/">Retour à l'accueil</a>
</body>
</html>

Hiérarchie de recherche des vues d'erreur :

  1. app/views/errors/{code}.php (ex: 404.php, 500.php)
  2. app/views/errors/error.php (vue générique)
  3. Vue par défaut intégrée au framework

🛡️ Sécurité

Bonnes pratiques

  • Toujours échapper les sorties HTML : htmlspecialchars($var)
  • Utiliser les SecurityPatterns pour valider les paramètres de route
  • Mettre debug = false en production dans config.php
  • Ne JAMAIS versionner config.php (déjà dans .gitignore)
  • ⚠️ CSRF protection : pas encore implémentée (à faire manuellement)
  • ⚠️ Validation des inputs utilisateur : à implémenter dans vos contrôleurs

SecurityPatterns disponibles

use Tekwork\SecurityPatterns;

SecurityPatterns::SAFE_PATH       // [a-zA-Z0-9_\-\/]+
SecurityPatterns::SAFE_FILENAME   // [a-zA-Z0-9_\-]+
SecurityPatterns::ALPHA_NUM       // [a-zA-Z0-9]+
SecurityPatterns::SLUG            // [a-zA-Z0-9\-]+

Reporter une vulnérabilité

Si vous découvrez une faille de sécurité, merci de la signaler de manière responsable via les Issues GitHub (en privé si possible).

📚 Documentation

Fonctions helpers

// Dump formaté pour debug
dump($variable);

// Construction de chemins multi-OS
path_it('app', 'views', 'home.php'); // app/views/home.php (ou app\views\home.php sur Windows)

Objet Request

$request = new Request();

// URI courante (sans slash initial)
$request->get_uri(); // "article/mon-slug"

// Segment par position (commence à 1)
$request->get_param(1); // "article"
$request->get_param(2); // "mon-slug"

// URLs
$request->get_base_url();  // "https://monsite.com"
$request->get_full_url();  // "https://monsite.com/article/mon-slug"
$request->get_host();      // "monsite.com" ou "monsite.com:8080"

Génération d'URLs

$router->url('article.show', ['slug' => 'mon-article']);
// Retourne : "article/mon-article"

Format des contrôleurs

Format : Namespace@Classe:methode

Exemples :

  • App\Controllers@HomeController:indexApp\Controllers\HomeController::index()
  • Admin@UserController:editAdmin\UserController::edit()

Le framework cherchera automatiquement :

  • Tekwork\ → dans /src/
  • Autre namespace → dans /{namespace_lowercase}/

🗺️ Roadmap

✅ Implémenté

  • Architecture MVC
  • Routing avancé avec paramètres dynamiques
  • ErrorHandler avec mode DEBUG/PRODUCTION
  • Configuration par environnement
  • Gestion des exceptions typées (NotFoundException)

🔮 Améliorations futures

  • Middleware support (before/after)
  • Session management sécurisée
  • CSRF protection
  • Database abstraction layer (PDO wrapper)
  • Template engine (Twig/Blade)
  • Logging system avancé
  • CLI commands support
  • Unit tests (PHPUnit)
  • Validation des inputs utilisateur
  • Rate limiting

🤝 Contribution

Les contributions sont les bienvenues ! N'hésitez pas à :

  1. Fork le projet
  2. Créer une branche (git checkout -b feature/amelioration)
  3. Commit vos changements (git commit -m 'Add: nouvelle feature')
  4. Push vers la branche (git push origin feature/amelioration)
  5. Ouvrir une Pull Request

📝 Notes

  • Ce framework est un projet d'apprentissage extrait de TekNotes
  • Il privilégie la simplicité et la compréhensibilité à la sur-architecture
  • Parfait pour petits/moyens projets ou pour apprendre les concepts MVC
  • Pour des projets critiques, préférez Laravel, Symfony ou Slim

🎓 Crédits

  • Extrait et adapté depuis TekNotes (système de documentation technique)
  • Développé avec l'assistance de Claude AI (Anthropic)
  • Auteur : Florian

📄 Licence

Ce projet est sous licence MIT. Voir le fichier LICENSE pour plus de détails.

Philosophie : Minimaliste mais extensible. 🚀

统计信息

  • 总下载量: 14
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-10-12