openspring/springphp-framework
Composer 安装命令:
composer require openspring/springphp-framework
包简介
The SpringPHP framework
README 文档
README
A PHP 7.4+ framework inspired by Java Spring, bringing annotation-driven dependency injection, RESTful controllers, ORM, JWT security, and validation to PHP.
Table of Contents
Features
- Annotation-driven architecture — stereotypes (
@Component,@Service,@Configuration), DI (@Autowired,@Value), and REST mappings parsed from PHP docblocks - IoC Container — singleton and prototype scoped beans with lazy loading and cyclic dependency detection
- RESTful routing —
@GetMapping,@PostMapping,@PutMapping,@DeleteMapping,@PatchMappingwith path variables, content negotiation, and automatic parameter binding - ORM — typed column mapping, fluent query builder, parameter binding, and state machine entity lifecycle
- JWT Security — token processing with role-based and group-based access control
- Validation — constraint-based validation (
@NotNull,@NotBlank,@Email,@Min,@Max,@Size,@Regex,@Positive,@Past,@Future, etc.) - HTTP layer — request/response abstraction,
ResponseEntity, message converters (JSON, HTML), cookies, headers, CORS - Interceptors —
preHandle/postHandlehooks for cross-cutting concerns - Logging — built-in logger with Log4p implementation
- Testing —
TestRunnerfor bootstrapping in TEST profile, Mockito-style mocking withwhen/thenReturn - i18n —
ResourceBundleMessageSourcefor multi-language message loading
Requirements
- PHP 7.4 or higher
- Composer
- MySQL (primary supported database)
Installation
For existing projects
composer require openspring/springphp-framework
For new projects
We recommend starting from the springphp-sample boilerplate, which provides a ready-to-use project structure with default configurations.
You can also use the springphp-initializer CLI to scaffold new projects, generate the database access layer, request mappings, API documentation and build deliveries.
Quick Start
1. Create the application entry point
<?php
use Openspring\SpringphpFramework\Core\SpringphpApplication;
/**
* @ComponentScan(baseDirs = ["src/controllers", "src/services"])
* @PropertySource("config/application.properties")
*/
class Application extends SpringphpApplication
{
public function __construct()
{
parent::__construct(__DIR__, 'config/', 'config/test/');
}
}
$app = new Application();
$app->execute();
2. Create a REST controller
<?php
use Openspring\SpringphpFramework\Web\RestController;
use Openspring\SpringphpFramework\Http\ResponseEntity;
use Openspring\SpringphpFramework\Http\HttpStatus;
class UserController extends RestController
{
/**
* @Autowired(true)
* @var UserService
*/
private $userService;
/**
* @GetMapping(value = "/users", consumes = "application/json", produces = "application/json")
*/
public function getUsers()
{
$users = $this->userService->findAll();
return ResponseEntity::ok($users);
}
/**
* @GetMapping(value = "/users/{$id}", consumes = "application/json", produces = "application/json")
*/
public function getUser($id)
{
$user = $this->userService->findById($id);
return ResponseEntity::ok($user);
}
/**
* @PostMapping(value = "/users", consumes = "application/json", produces = "application/json")
*/
public function createUser(RequestBody $body)
{
$user = $this->userService->create($body);
return ResponseEntity::status(HttpStatus::CREATED, $user);
}
}
3. Create a service
<?php
use Openspring\SpringphpFramework\Core\Stereotype\Service;
/**
* @Service
*/
class UserService extends Service
{
/**
* @Autowired(true)
* @var UserDao
*/
private $userDao;
public function findAll(): array
{
return $this->userDao->findAll()->getResultList();
}
public function findById(int $id)
{
return $this->userDao->findById($id);
}
}
4. Create an entity
<?php
use Openspring\SpringphpFramework\Orm\DaoSupport;
use Openspring\SpringphpFramework\Orm\Column;
use Openspring\SpringphpFramework\Orm\Type\DataType;
use Openspring\SpringphpFramework\Orm\Type\PrimaryKey;
class UserDao extends DaoSupport
{
public $id;
public $name;
public $email;
public $password;
public $createdAt;
public function __construct()
{
parent::__construct('#__users');
$this->id = new Column($this, 'id', 11, DataType::INT, new PrimaryKey());
$this->name = new Column($this, 'name', 100, DataType::VARCHAR);
$this->email = new Column($this, 'email', 150, DataType::VARCHAR, null, true);
$this->password = new Column($this, 'password', 255, DataType::HASH);
$this->createdAt = new Column($this, 'created_at', 0, DataType::DATETIME);
$this->initialize();
}
}
Documentation
Application Bootstrap
The framework follows a structured boot sequence:
SpringphpApplicationconstructor loadsapplication.propertiesand sets up theEnvironmentApplicationContext::initialize()reads the.contextcache (bean registry + route mappings)DatabaseContext::initialize()configures data sources- On HTTP request:
Router::route()matches the URL, thenRestController::runAction()dispatches the action
REST Controllers
Controllers extend RestController and use docblock annotations for routing:
/**
* @GetMapping(value = "/products/{$id}", produces = "application/json")
*/
public function getProduct($id) { ... }
/**
* @PostMapping(value = "/products", consumes = "application/json", produces = "application/json")
*/
public function createProduct(RequestBody $body) { ... }
/**
* @PutMapping(value = "/products/{$id}", consumes = "application/json", produces = "application/json")
*/
public function updateProduct($id, RequestBody $body) { ... }
/**
* @DeleteMapping(value = "/products/{$id}", produces = "application/json")
*/
public function deleteProduct($id) { ... }
Available mapping annotations: @RequestMapping, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping
Parameter binding: RequestBody, RequestHeader, RequestCookie, RequestTemporaryFile
Dependency Injection
The IoC container manages beans as lazy-loaded singletons (default) or prototypes.
/**
* @Service
*/
class OrderService extends Service
{
/**
* @Autowired(true)
* @var OrderDao
*/
private $orderDao;
/**
* @Autowired(true)
* @var NotificationService
*/
private $notificationService;
/** @Value("app.order.max-items") */
private $maxItems;
}
@Autowired(true)— injects a bean by type (field injection); requires@varon a separate line@Value("property.key")— injects a value fromapplication.properties- Stereotypes:
@Component,@Service,@Configuration - Cyclic dependency detection is built in
ORM & Entities
Entities extend DaoSupport and define typed columns:
class ProductDao extends DaoSupport
{
public $id;
public $name;
public $price;
public $active;
public function __construct()
{
parent::__construct('#__products');
$this->id = new Column($this, 'id', 11, DataType::INT, new PrimaryKey());
$this->name = new Column($this, 'name', 200, DataType::VARCHAR, null, false, true);
$this->price = new Column($this, 'price', 10, DataType::FLOAT);
$this->active = new Column($this, 'active', 1, DataType::BOOLEAN);
$this->initialize();
}
}
Supported column types: INT, VARCHAR, FLOAT, BOOLEAN, DATE, DATETIME, JSON, GUID, HASH
The #__ prefix in table names is automatically replaced by the configured table prefix from your data source.
Query Builder
Fluent API for building SQL queries with parameter binding:
$results = $productDao->select(['id', 'name', 'price'])
->from()
->where('active', '=', 1)
->and('price', '>', ':minPrice')
->setParameter(':minPrice', 25.00)
->orderBy('name', 'ASC')
->getResultList();
Validation
Constraint-based validation using docblock annotations on method parameters:
| Constraint | Description |
|---|---|
@NotNull | Value must not be null |
@NotBlank | String must not be null or empty |
@NotEmpty | Collection/string must not be empty |
@Email | Must be a valid email address |
@Min(value) | Numeric minimum |
@Max(value) | Numeric maximum |
@Size(min, max) | String/array length bounds |
@Regex(pattern) | Must match the regular expression |
@Positive / @PositiveOrZero | Must be positive (or zero) |
@Negative / @NegativeOrZero | Must be negative (or zero) |
@Past / @PastOrPresent | Date must be in the past |
@Future / @FutureOrPresent | Date must be in the future |
@AssertTrue / @AssertFalse | Boolean assertions |
@URL | Must be a valid URL |
@InArray(values) | Must be one of the specified values |
Security (JWT)
JWT-based authentication with role and group access control:
/**
* @GetMapping(value = "/admin/dashboard", produces = "application/json", groupIn = "1,2", roleIn = "ADMIN")
*/
public function dashboard() { ... }
groupIn— comma-separated list of authorized group IDs ("*"for all authenticated users)roleIn— comma-separated list of authorized roles ("*"for all authenticated users)
Implement IJwtProcessor to handle token extraction and validation, and IUser for the current user model.
Configuration
Configuration is managed through properties files:
# application.properties
#################### COMMON CONFIG #########################
# application display name
springphp.application.name=appName
# project mode; supported (values: DEV|QUALIF|VAL|PPROD|REHEARSAL|PROD)
springphp.profile.active=DEV
# relative web home url; put / if the application is on the www root or something like /app1/ in other case
springphp.application.context.path=/relative/path/to/api/
# base is {rootPath}: application absolute public path
springphp.path.public=/relative/path/to/public/directory/
# base is {rootPath}: main sources relative path
springphp.path.sources=src/main/php/
# base is {rootPath}: test sources relative path
springphp.path.tests=src/test/php/
#################### DATABASE CONFIG ####################
# databases config names to connect to on application startup (config names must be separated by commas)
# Exemples: defaultDatabase, customersDatabase, clientsDatabase, commandesDatabase
springphp.database.targets=defaultDatabase
####################### LOG CONFIG #########################
# enable log. If false all logging is disabled !
springphp.log.enable=false
# error logging file path
springphp.log.file=logs\server_%d.log
# log file max size in KO (example: 1024 ; 2048)
springphp.log.file.maxsize=1024
# log level [SQL | DEBUG | INFO | WARN | ERROR]
springphp.log.level=SQL
# log output format: known var names: %d (date) ; %l (log level) ; %m (message)
springphp.log.format=[%d][%ns][%c][%l] %m
# application.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<orm-configuration>
<datasources>
<!-- default datasource -->
<datasource id="defaultDatabase">
<!-- connection parametrs -->
<dialect>Openspring\SpringphpFramework\Orm\Driver\Mysql\MysqlDriver</dialect>
<host>localhost</host>
<database>db_name</database>
<port>3306</port>
<user>root</user>
<password></password>
<tableprefix>tbl_</tableprefix>
</datasource>
</datasources>
<!-- show sql when executing queries -->
<show_sql>true</show_sql>
</orm-configuration>
Profile-based configuration: Use dev-application.properties, test-application.properties, or prod-application.properties for environment-specific overrides.
Access properties in code:
// Via annotation
/** @Value("app.name") */
private $appName;
// Programmatically
$value = Environment::getProperty("app.name");
Interceptors
Implement HttpInterceptor for cross-cutting concerns like logging, auth checks, or metrics:
/**
* @Component
*/
class AuthInterceptor extends HttpInterceptor
{
public function preHandle(): bool
{
// Return false to halt the request
return true;
}
public function postHandle(): bool
{
return true;
}
}
Logging
Built-in logging with LogFactory:
$logger = LogFactory::getLogger(self::class);
$logger->info('Processing order');
$logger->debug('Order details: ' . $orderId);
$logger->error('Payment failed');
Testing
# Run all tests
vendor/bin/phpunit --configuration phpunit.xml
# Run a specific test class
vendor/bin/phpunit --filter UserServiceTest
# Run a specific test method
vendor/bin/phpunit --filter testCreateUser
# Run with coverage
vendor/bin/phpunit --coverage-text --configuration phpunit.xml
The framework provides a TestRunner that bootstraps the application in TEST profile and allows simulating HTTP requests. A Mockito-style mocking utility is also available:
use Openspring\SpringphpFramework\Mock\Mockito;
$mock = Mockito::mock(UserService::class);
Mockito::when($mock, 'findById')->thenReturn($expectedUser);
Project Structure
springphp-framework/
├── src/
│ ├── main/php/Openspring/SpringphpFramework/
│ │ ├── Annotation/ # Docblock annotation parsing
│ │ ├── Context/ # ApplicationContext, DatabaseContext, Environment
│ │ ├── Core/ # Bean, Component, Service, SpringphpApplication
│ │ ├── Enumeration/ # Framework enums
│ │ ├── Exception/ # Exception hierarchy (HTTP, Bean, Data, IO)
│ │ ├── Http/ # Request, Response, ResponseEntity, converters
│ │ ├── IO/ # File and directory utilities
│ │ ├── Log/ # Logger and Log4p implementation
│ │ ├── Mail/ # Mail sender
│ │ ├── Mock/ # Mockito-style test mocking
│ │ ├── Orm/ # DaoSupport, Column, QueryBuilder, drivers
│ │ ├── Reflection/ # ClassReflection for docblock parsing
│ │ ├── Security/ # JWT processing, access control
│ │ ├── Type/ # ArrayList, Any, DynamicObject
│ │ ├── Utils/ # Strings, Arrays, Dates, Encryption, etc.
│ │ ├── Validation/ # Constraint-based validation
│ │ └── Web/ # RestController, Router, RestTemplate
│ └── test/php/TestCase/ # Unit tests (mirrors main structure)
├── composer.json
├── phpunit.xml
└── LICENSE.txt
The project follows a Maven-style directory layout with PSR-4 autoloading.
Contributing
There are currently a number of outstanding issues that need to be addressed. Please read How to contribute.
You can report bugs and request features on the issue tracker.
License
This project is licensed under the MIT License. See LICENSE.txt for details.
openspring/springphp-framework 适用场景与选型建议
openspring/springphp-framework 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 208 次下载、GitHub Stars 达 1, 最近一次更新时间为 2019 年 11 月 03 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「framework」 「orm」 「rest」 「api」 「oauth」 「web service」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 openspring/springphp-framework 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 openspring/springphp-framework 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 openspring/springphp-framework 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
PHP Framework HLEB2 is the foundation of the web application. Provides ease of development and application performance.
Kinikit - PHP Application development framework MVC component
PHP Database ORM for Symfony1. Do NOT use for new projects: please move to a newest Symfony release and Doctrine2
A PSR-7 compatible library for making CRUD API endpoints
Api bundle
PeskyORM - annoying ORM that contains tons of exceptions and throws them when anything goes wrong
统计信息
- 总下载量: 208
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 2
- 点击次数: 17
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2019-11-03