hyperf/pimple
hyperf/pimple 是基于 pimple/pimple 的轻量级 PSR-11 容器组件,提供简单的 ContainerFactory 创建容器与 Provider 注册机制,帮助在非 Hyperf 框架中低成本接入 Hyperf 组件(如 translation/config),便于集成与复用。
composer require hyperf/pimple hyperf/translation hyperf/config
use Hyperf\Pimple\ContainerFactory;
$pimpleContainer = (new ContainerFactory())();
$pimpleContainer->register(new class implements \Hyperf\Pimple\ProviderInterface {
public function register(\Psr\Container\ContainerInterface $container) {
$container->set(\Hyperf\Contract\ConfigInterface::class, fn() => new \Hyperf\Config\Config([]));
}
});
$config = $pimpleContainer->get(\Hyperf\Contract\ConfigInterface::class);
$pimpleContainer->register(new \App\Providers\TranslatorProvider());
use Hyperf\Contract\TranslatorInterface;
public function __construct(private TranslatorInterface $translator) {}
public function index() {
return $this->translator->trans('message.hello');
}
Note: Requires Laravel’s DI to resolve Pimple-bound services (see Implementation Patterns).Pattern: Use Pimple as a secondary container for Hyperf services while keeping Laravel’s container primary.
// In a Laravel service provider
public function register() {
$pimple = (new ContainerFactory())->withProviders([
\App\Providers\HyperfTranslationProvider::class,
]);
// Bind Pimple to Laravel's container
$this->app->singleton('hyperf.pimple', fn() => $pimple);
$this->app->bind(\Hyperf\Contract\TranslatorInterface::class, fn($app) =>
$app['hyperf.pimple']->get(\Hyperf\Contract\TranslatorInterface::class)
);
}
When to Use:
Pattern: Extend ProviderInterface to register Hyperf services.
// Example: Hyperf Translation Provider for Laravel
class HyperfTranslationProvider implements \Hyperf\Pimple\ProviderInterface {
public function register(\Psr\Container\ContainerInterface $container) {
$container->set(\Hyperf\Contract\ConfigInterface::class, fn() =>
new \Hyperf\Config\Config(config('hyperf'))
);
$container->set(\Hyperf\Contract\TranslatorLoaderInterface::class, fn($c) => new \Hyperf\Translation\FileLoader(
$c->get(\Hyperf\Utils\Filesystem\Filesystem::class),
storage_path('lang')
));
$container->set(\Hyperf\Contract\TranslatorInterface::class, fn($c) =>
new \Hyperf\Translation\Translator(
$c->get(\Hyperf\Contract\TranslatorLoaderInterface::class),
config('app.locale')
)
);
}
}
Integration Tip:
config() helper to avoid hardcoding paths.Filesystem to Pimple using Laravel’s filesystem:
$container->set(\Hyperf\Utils\Filesystem\Filesystem::class, fn() =>
new \Hyperf\Utils\Filesystem\Filesystem(storage_path())
);
Pattern: Resolve Pimple-bound services in Laravel controllers/services.
// Option 1: Direct Pimple Resolution (if bound to Laravel's container)
public function __construct(private \Psr\Container\ContainerInterface $pimple) {
$this->translator = $pimple->get(\Hyperf\Contract\TranslatorInterface::class);
}
// Option 2: Laravel DI (preferred)
public function __construct(private \Hyperf\Contract\TranslatorInterface $translator) {}
Tip:
Pattern: Share Laravel config with Pimple.
$pimpleContainer->set(\Hyperf\Contract\ConfigInterface::class, fn() =>
new \Hyperf\Config\Config([
'translation' => [
'locale' => config('app.locale'),
'path' => storage_path('lang/hyperf'),
],
])
);
Tip:
config() values.config_path('hyperf.php') for Hyperf-specific settings.Pattern: Mock Pimple services in Laravel tests.
public function testTranslation() {
$pimple = (new ContainerFactory())->withProviders([HyperfTranslationProvider::class]);
$pimple->set(\Hyperf\Contract\TranslatorInterface::class, $this->createMock(TranslatorInterface::class));
$this->app->instance('hyperf.pimple', $pimple);
$this->assertTrue(true); // Test logic using $this->translator
}
Tip:
app()->instance() to override Pimple bindings in tests.TranslatorInterface) to isolate tests.Container Isolation Issues:
hyperf.translator).$pimple->set('hyperf.translator', $translator); // Avoids collision with Laravel's translator
Hyperf-Specific Assumptions:
make() helper or ApplicationContext won’t work in Laravel.app() or manual instantiation:
// Instead of: make(Translator::class)
$translator = new \Hyperf\Translation\Translator($loader, $locale);
Circular Dependencies:
$container->set(ServiceInterface::class, fn($c) => new Service($c->get(DependencyInterface::class)));
Configuration Overrides:
$hyperfConfig = new \Hyperf\Config\Config([
'translation' => array_merge(
config('hyperf.translation', []),
['locale' => config('app.locale')]
),
]);
Performance Overhead:
$this->app->singleton(\Hyperf\Contract\TranslatorInterface::class, fn($app) =>
$app['hyperf.pimple']->get(\Hyperf\Contract\TranslatorInterface::class)
);
Service Not Found:
print_r(array_keys($pimple->getKeys()));
register() method is called.Binding Conflicts:
getKeys() to list all bindings in both containers.hyperf.) to avoid collisions.Hyperf-Specific Errors:
try-catch to isolate issues:
try {
$translator->trans('key');
} catch (\Exception $e) {
Log::error('Hyperf translation failed: '.$e->getMessage());
return 'fallback';
}
Custom Providers:
ProviderInterface to add Hyperf services (e.g., caching, RPC):
class HyperfCacheProvider implements ProviderInterface {
public function register($container) {
$container->set(\Hyperf\Contract\CacheInterface::class, fn() =>
new \Hyperf\Cache\Driver\RedisDriver(config('cache.redis'))
);
}
}
Laravel Service Provider Wrapper:
How can I help you explore Laravel packages today?