{"id":18767824,"url":"https://github.com/vdonchev/framework","last_synced_at":"2026-02-23T11:22:44.782Z","repository":{"id":56971020,"uuid":"419238457","full_name":"vdonchev/framework","owner":"vdonchev","description":"Small PHP Framework","archived":false,"fork":false,"pushed_at":"2025-04-12T16:23:23.000Z","size":886,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-20T22:34:18.720Z","etag":null,"topics":["dependency-injection","framework","mysql","php"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vdonchev.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-10-20T08:03:32.000Z","updated_at":"2025-04-12T16:23:26.000Z","dependencies_parsed_at":"2024-11-25T11:39:45.690Z","dependency_job_id":"dde1bb7c-8a4b-4bef-9327-6202aef2e4eb","html_url":"https://github.com/vdonchev/framework","commit_stats":{"total_commits":47,"total_committers":1,"mean_commits":47.0,"dds":0.0,"last_synced_commit":"b055278ade150714522b7399bde0f5fc0da681b8"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/vdonchev/framework","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdonchev%2Fframework","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdonchev%2Fframework/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdonchev%2Fframework/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdonchev%2Fframework/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vdonchev","download_url":"https://codeload.github.com/vdonchev/framework/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdonchev%2Fframework/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29741411,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-23T07:44:07.782Z","status":"ssl_error","status_checked_at":"2026-02-23T07:44:07.432Z","response_time":90,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dependency-injection","framework","mysql","php"],"created_at":"2024-11-07T19:08:48.563Z","updated_at":"2026-02-23T11:22:44.774Z","avatar_url":"https://github.com/vdonchev.png","language":"PHP","readme":"\n# Tiny Framework\n\nA lightweight and expressive PHP framework built for clarity, structure, and extensibility. Ideal for small to mid-sized web applications.\n\n---\n\n## Features\n\n### Built-in functionalities\n\n- Dependency Injection Container (PHP-DI)\n- Routing (FastRoute)\n- Middleware support\n- Templating with Twig\n- Flash messages\n- Database support via MeekroDB\n- SMTP mailer (Nette Mail)\n- Console commands (Symfony Console)\n- Caching (Symfony Cache)\n- Logging (donchev/simple-logger)\n- Data validation and sanitization\n\nIncludes **Bootstrap 5** and **Bootstrap Icons** for UI development.\n\n---\n\n## Requirements\n\n- PHP 8.2 or higher\n\n---\n\n## Installation\n\nYou can install the framework using Composer.\n\n```bash\ncomposer create-project donchev/framework myapp\n```\n\n---\n\n## Configuration\n\nAll application configuration is located in `config/settings.yaml`. Example:\n\n```yaml\napp:\n  env: dev\n  name: Tiny Framework\n  base_url: https://framework.test\n  use_sessions: true\n  log_file: '%var_dir%/log/framework.log'\n\napi:\n  username:\n  password:\n\nmiddleware:\n  dir: '%base_dir%/src/Middleware'\n  namespace: Donchev\\Framework\\Middleware\n\ndb:\n  host: \n  name: \n  username: \n  password: \n  port: 3306\n  charset: utf8mb4\n\nmail:\n  host: smtp.mailtrap.io\n  username: \n  password: \n  secure: null\n  port: 2525\n  from_name: 'Tiny Framework Mailer'\n  from_email: \n```\n\nOverride values via `settings.local.yaml`.\n\n---\n\n## Usage\n\n### Routing\n\nDefine routes in `config/routes.php`:\n\n```php\nreturn static function (RouteCollector $router) {\n    $router-\u003eget('/', [HomeController::class, 'index']);\n    $router-\u003epost('/submit', [ContactController::class, 'submit']);\n    $router-\u003eget('/blog/{slug}', [BlogController::class, 'show']);\n};\n```\n\n---\n\n### Controllers\n\nControllers extend `AbstractController`:\n\n```php\nclass HomeController extends AbstractController\n{\n    public function index(): void\n    {\n        $this-\u003erenderTemplate('home/index.html.twig', [\n            'title' =\u003e 'Welcome!'\n        ]);\n    }\n}\n```\n\n---\n\n### Sending Emails\n\n```php\nuse Nette\\Mail\\Message;\n\n$message = new Message();\n$message-\u003esetFrom('you@site.com')\n        -\u003eaddTo('user@example.com')\n        -\u003esetSubject('Hello')\n        -\u003esetBody('This is a test email.');\n\n$mailer = $container-\u003eget(Mailer::class);\n$mailer-\u003esend($message);\n```\n\n---\n\n### Database (MeekroDB)\n\n```php\n/** @var MeekroDB $db */\n$db = $container-\u003eget(MeekroDB::class);\n\n$users = $db-\u003equery(\"SELECT * FROM users WHERE active = %i\", 1);\n```\n\n---\n\n### Using Cache\n\n```php\nuse Symfony\\Contracts\\Cache\\CacheInterface;\n\n$cache = $container-\u003eget(CacheInterface::class);\n\n$data = $cache-\u003eget('some_key', function () {\n    return 'cached value';\n});\n```\n\n---\n\n### Flash Messages\n\nSet flash messages in controller:\n\n```php\n$flash = new FlashService();\n$flash-\u003eadd('success', 'Saved successfully!');\n```\n\nRender them in Twig:\n\n```twig\n{% include '_flash.html.twig' with {'flashes': flashes} %}\n```\n\n---\n\n### Middleware\n\nImplement `MiddlewareInterface` and drop your class into `src/Middleware`. It will be auto-loaded.\n\n```php\nclass RequestLoggerMiddleware implements MiddlewareInterface\n{\n    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface\n    {\n        // logging logic...\n        return $handler-\u003ehandle($request);\n    }\n}\n```\n\n---\n\n### Twig Template Globals\n\nTwig templates automatically have access to:\n\n- `http_get`, `http_post`, `http_cookie`, `http_session`\n- `settings`\n- `get_flash()` function\n\n---\n\n### Data Validator \u0026 Sanitizer\n\n**Validator:**\n\n```php\n$validator = new DataValidator();\n\n$data = [\n    'name' =\u003e 'John Doe',\n    'age' =\u003e 32\n];\n\n$rules = [\n    'name' =\u003e 'string',\n    'age' =\u003e 'min:30'\n];\n\n$result = $validator-\u003evalidate($data, $rules);\n\n// Output:\n[\n  'age' =\u003e [\n    '\"age\" must have at least 30 characters'\n  ]\n]\n```\n**Validator \u0026 Flash Messages:**\n\n```php\n\nclass AuthController\n{\n    public function login(Post $post, DataValidator $validator, FlashService $flashService): void\n    {\n        $data = [\n            'email' =\u003e $post-\u003eget('email'),\n            'password' =\u003e $post-\u003eget('password'),\n        ];\n\n        $rules = [\n            'email' =\u003e 'required|email',\n            'password' =\u003e 'required|secure',\n        ];\n\n        $errors = $validator-\u003evalidate($data, $rules);\n\n        if (!empty($errors)) {\n            $flashService-\u003eaddError($errors);\n            // return or redirect with errors\n        }\n\n        //...\n    }\n}\n```\n\n**Sanitizer:**\n\n```php\n$sanitizer = new DataSanitizer();\n\n$data = ['asd123', '1.5ds'];\n$sanitized = $sanitizer-\u003esanitize($data, 'float');\n\n// Output: [123.0, 1.5]\n```\n\n---\n\n### Console Commands\n\nDefine commands in `bin/console`. Example:\n\n```php\nclass HelloCommand extends Command\n{\n    protected string $signature = 'hello';\n    protected string $description = 'Says hello';\n\n    public function handle(): void\n    {\n        $this-\u003einfo('Hello from the Tiny Framework!');\n    }\n}\n```\n\nRun them:\n\n```bash\nphp bin/console hello\n```\n\n---\n\n## Code Style\n\nThis project uses **php-cs-fixer**. You can format your code using:\n\n```bash\ncomposer cs-fix\n```\n\nCheck for issues without modifying files:\n\n```bash\ncomposer cs-check\n```\n\n---\n\n## Testing\n\nThe framework includes PHPUnit 12+ test coverage out of the box.\n\nRun tests:\n\n```bash\nvendor/bin/phpunit\n```\n\nAll test files are located in the `tests/` folder and follow PSR-4 autoloading with the `Tests\\` namespace.\n\n---\n\n## Development Mode\n\nSet `app.env: dev` to enable detailed error pages (via Whoops) and debugging tools.\n\n---\n\n## Production\n\nSet `app.env: prod` to enable compiled container and cache.\n\n---\n\n## License\n\nThis project is open-source and licensed under the [MIT License](LICENSE).\n\n---\n\n## Author\n\nDeveloped by Donchev. Contributions are welcome.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvdonchev%2Fframework","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvdonchev%2Fframework","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvdonchev%2Fframework/lists"}