giovanni-venturelli/sophia
Composer 安装命令:
composer require giovanni-venturelli/sophia
包简介
Sophia is a lightweight component-based PHP framework with native PHP templates.
README 文档
README
Minimal, production‑oriented PHP framework with:
- Component-based rendering with native PHP templates
- Angular‑inspired Dependency Injection system
- Simple Router (components, API callbacks, parameters, guards)
- Optional database layer with fluent QueryBuilder and Active Record ORM
Components are plain PHP classes (annotated), services are auto‑wired, routes map to components (views) or callbacks (APIs).
Quick navigation
- What you get (features)
- Architecture at a glance
- Installation
- Project structure
- Quick start (index.php + routes.php)
- Create your first component
- Dependency Injection (services)
- Routing basics (components, params, urls)
- Performance & Build System
- Database integration (optional)
- Troubleshooting
- Deep dives (module READMEs)
- Migration from Twig to native PHP
What you get (features)
- Components rendered with native PHP templates and helper functions
- Property injection in components and constructor injection in services
- Root singletons via
#[Injectable(providedIn: 'root')] - Route configuration with parameters, named routes, redirects, nested routes, guards
- Optional database service with fluent QueryBuilder and Active Record entities
Architecture at a glance
- Components:
core/component(attributes, registry, renderer) - DI (Injector):
core/injector(root singletons + per‑component scoped providers) - Router:
core/router(maps requests to components or callbacks) - Database (optional):
core/database(connection service + ORM)
Flow for a component route:
Routermatches the incoming path → selects a component classComponentRegistrylazily registers it andRenderercreates aComponentProxyComponentProxyopens a DI scope, warms providers, creates the component, runs property injection, thenonInit()Renderercollects public properties/zero‑arg getters and renders the PHP template
Installation
- PHP 8.1+
- Composer
composer install
If you use environment variables, add a .env file (Dotenv is included in composer.json) and configure the database as needed (see Database integration).
Project structure
.
├─ core/
│ ├─ component/ # Component system (attributes, registry, renderer)
│ ├─ injector/ # DI container + attributes
│ ├─ router/ # Router + middleware
│ └─ database/ # Optional DB service + ORM
├─ pages/ # Your component classes and PHP templates
├─ routes.php # Route table
├─ index.php # App bootstrap
└─ vendor/ # Composer dependencies
Quick start (index.php + routes.php)
Minimal bootstrap in index.php:
<?php use Sophia\Component\ComponentRegistry; use Sophia\Component\Renderer; use Sophia\Database\ConnectionService; use Sophia\Injector\Injector; use Sophia\Router\Router; require __DIR__ . '/vendor/autoload.php'; // Optional env (if your app uses Dotenv in your project) // $dotenv = Dotenv\Dotenv::createImmutable(__DIR__); // $dotenv->load(); // Optional DB (root singleton) $dbConfig = file_exists('config/database.php') ? require 'config/database.php' : ['driver' => 'sqlite', 'credentials' => ['database' => 'database/app.db']]; $db = Injector::inject(ConnectionService::class); $db->configure($dbConfig); $registry = ComponentRegistry::getInstance(); /** @var Renderer $renderer */ $renderer = Injector::inject(Renderer::class); $renderer->setRegistry($registry); $renderer->configure(__DIR__ . '/pages', '', 'it', true); $renderer->addGlobalStyle('css/style.css'); $renderer->addGlobalScripts('js/scripts.js'); /** @var Router $router */ $router = Injector::inject(Router::class); $router->setComponentRegistry($registry); $router->setRenderer($renderer); $router->setBasePath('/sophia'); // optional, if app lives in a subfolder require __DIR__ . '/routes.php'; $router->dispatch();
Define routes in routes.php:
<?php use App\Pages\Home\HomeComponent; use Sophia\Router\Router; $router = Router::getInstance(); $router->configure([ [ 'path' => 'home/:id', // URL with param 'component' => HomeComponent::class, // Component class 'name' => 'home', // Named route 'data' => [ 'title' => 'Home Page' ], // Route-scoped data ], ]);
Create your first component
Component class under pages/... and a PHP template next to it:
<?php namespace App\Pages\Home; use Sophia\Component\Component; #[Component(selector: 'app-home', template: 'home.php')] class HomeComponent { public string $title = 'Welcome'; public string $id; public function onInit(): void { // Optionally compute public state for the template } }
Template home.php:
<h1><?= $e($title) ?></h1> <p>User ID: <?= $e($id) ?></p>
The renderer passes route params (:id) as initial data to the root component.
Dependency Injection (services)
- Mark root singletons with
#[Injectable(providedIn: 'root')]. - Use property injection in components:
#[Inject] private Service $service; - Use constructor injection in services; dependencies are resolved by the Injector.
Example service + usage in a component:
use Sophia\Injector\Injectable; use Sophia\Injector\Inject; use Sophia\Component\Component; #[Injectable(providedIn: 'root')] class Logger { public function info(string $m): void {} } #[Injectable] class UserService { public function __construct(private Logger $log) {} } #[Component(selector: 'app-users', template: 'users.php', providers: [UserService::class])] class UsersComponent { #[Inject] private UserService $users; public array $active = []; public function onInit(): void { $this->active = $this->users->getActive(); } }
See the full DI reference: Injector (DI).
Routing basics (components, params, urls)
- Define paths like
post/:idto capture params; available to components and templates - Name routes with
nameand generate URLs using theurl()helper - Provide
dataon routes; read them withroute_data()
Template helpers:
<a href="<?= $e($url('home', ['id' => 123])) ?>">Go home</a> <p>Title: <?= $e($route_data('title')) ?></p>
More details: Router.
Redirections and Guards
(Existing content for Routing basics...)
Performance & Build System
Sophia includes a build system to optimize performance in production (up to 40% faster).
How it works
In development mode (DEBUG=true), the framework scans folders and uses the Reflection API on every request. In production (DEBUG=false), the framework loads pre-generated static maps.
CLI Commands
From the project root:
# Generate structural cache (components, routes, DI) php sophia build # Clear the build cache php sophia clear
When to run the build?
The build is only necessary when the structure of the application changes:
- Creating new components or services.
- Modifying routes or selectors.
- Modifying
providersin Dependency Injection.
Note: It is not necessary to rebuild if you only modify the database content, the logic code inside a method, or the HTML markup of an existing template.
Database integration (optional)
The ConnectionService is a root‑provided service with a fluent QueryBuilder and an Active Record‑style ORM via Entity.
Example entity:
use Sophia\Database\Entity; class Post extends Entity { protected static string $table = 'posts'; protected static array $fillable = ['title', 'content', 'status']; }
Query examples:
$posts = Post::where('status', 'published')->orderBy('created_at', 'DESC')->limit(10)->get(); $one = Post::find(1);
Full guide: Database.
Troubleshooting
- Template not found: ensure the file exists next to the component class or in a path added to the renderer
- Undefined variable: expose data via public properties or zero‑arg getters
- Injection error: add
#[Inject]to typed component properties; mark services as#[Injectable]and/or list them inproviders - Routing mismatch: check
basePath, path normalization, and that names/params match when callingurl()
Deep dives (module READMEs)
- Components: Components
- Injector (DI): Injector (DI)
- Router: Router
- Database: Database
- Templates: Templates Guide
- Forms: Forms Guide
Using this repository as a package + demo
This repo is organized so that the core framework (package) is published to Packagist, while the demo app stays in-repo only.
- Package (library):
giovanni-venturelli/sophia(root of this repo)- Namespaces exported:
Sophia\\*(component, injector, router, form, database) - Packagist dist excludes the demo and app assets via
.gitattributes
- Namespaces exported:
- Demo app:
/demo(not included in the Packagist dist)- Depends on the package via Composer repository of type
pathto the repo root - Autoloads the demo namespaces from the project folders (
../pages,../Shared,../services)
- Depends on the package via Composer repository of type
Install the package (as a dependency) in another project
composer require giovanni-venturelli/sophia
Run the demo locally from this repo
- Install dependencies for the demo (uses a path repo to the root library):
cd demo
composer install
- Start a PHP dev server pointing to the demo folder (or your web server root to
demo/):
php -S localhost:8080 -t demo
Then open:
- http://localhost:8080/index.php/home/123 (adjust paths if needed)
Notes
- The demo reuses the project folders
pages/,Shared/,services/,config/,css/,js/,cache/from the repo root. - The router base path in the demo is set to
/sophia/demo. If you serve it at a different path, update$basePathindemo/index.phpand the global asset paths. - The package requires PHP >= 8.1; the demo also requires
vlucas/phpdotenvfor.envloading.
Publishing to Packagist
- Push this repository to GitHub under
giovanni-venturelli/sophia. - Create a version tag, e.g.:
git tag v0.1.0 git push origin v0.1.0
- Submit the repository URL to Packagist and set up the GitHub Service Hook so Packagist auto-updates on new tags.
After publish, consumers can composer require giovanni-venturelli/sophia.
Forms — end-to-end example
Route (already present in routes.php):
[ 'path' => 'forms/submit/:token', 'callback' => [\Sophia\Form\FormController::class, 'handle'], 'name' => 'forms.submit' ],
Template:
<form method="post" action="<?= $e($form_action('send')) ?>"> <?= $csrf_field() ?> <!-- fields --> </form>
The $form_action('send') helper generates a URL like /sophia/forms/submit/<token>. Make sure the base path is set in index.php.
Named routes — quick tip
Always add name to routes you want to link to from templates:
[ 'path' => 'about', 'component' => App\Pages\About\AboutLayoutComponent::class, 'name' => 'about', 'children' => include __DIR__ . '/pages/About/routes.php' ]
Then in templates:
<a href="<?= $e($url('about')) ?>">About</a>
giovanni-venturelli/sophia 适用场景与选型建议
giovanni-venturelli/sophia 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 60 次下载、GitHub Stars 达 1, 最近一次更新时间为 2025 年 12 月 27 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「framework」 「php」 「router」 「component」 「native-php」 「angular-like」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 giovanni-venturelli/sophia 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 giovanni-venturelli/sophia 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 giovanni-venturelli/sophia 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
PHP Framework HLEB2 is the foundation of the web application. Provides ease of development and application performance.
Router
PMVC App Action Router
Database alias router extension for Nette Framework
Alfabank REST API integration
PHP Router
统计信息
- 总下载量: 60
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 31
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-12-27