Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: thinkphp 框架 container 内置支持 #675

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
parameters:
reportUnmatchedIgnoredErrors: false
excludePaths:
- src/Service/ContainerServiceProvider.php
ignoreErrors:
- '#.* Illuminate\\Container\\Container.*#'
- '#.* Hyperf\\Utils\\ApplicationContext.*#'
- '#.* think\\Container.*#'
41 changes: 28 additions & 13 deletions src/Pay.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Illuminate\Container\Container as LaravelContainer;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
use think\Container as ThinkPHPContainer;
use Throwable;
use Yansongda\Pay\Contract\ServiceProviderInterface;
use Yansongda\Pay\Exception\ContainerException;
Expand Down Expand Up @@ -110,6 +111,8 @@ public static function config(array $config = [], $container = null): bool
}

/**
* @codeCoverageIgnore
*
* @param mixed $value
*
* @throws \Yansongda\Pay\Exception\ContainerException
Expand All @@ -119,24 +122,26 @@ public static function set(string $name, $value): void
try {
$container = Pay::getContainer();

if ($container instanceof LaravelContainer) { // @phpstan-ignore-line
$container->singleton($name, $value instanceof Closure ? $value : static fn () => $value); // @phpstan-ignore-line

return;
}

if (method_exists($container, 'set')) {
$container->set(...func_get_args());

return;
switch (true) {
case $container instanceof LaravelContainer:
$container->singleton($name, $value instanceof Closure ? $value : static fn () => $value);
break;
case $container instanceof ThinkPHPContainer:
$container->delete($name);
$container->bind($name, $value instanceof Closure ? $value : static fn () => $value);
break;
default:
if (!method_exists($container, 'set')) {
throw new ContainerException('Current container does NOT support `set` method');
}

$container->set($name, $value);
}
} catch (ContainerNotFoundException $e) {
throw $e;
} catch (Throwable $e) {
throw new ContainerException($e->getMessage());
}

throw new ContainerException('Current container does NOT support `set` method');
}

/**
Expand Down Expand Up @@ -164,6 +169,8 @@ public static function make(string $service, array $parameters = [])
}

/**
* @codeCoverageIgnore
*
* @return mixed
*
* @throws \Yansongda\Pay\Exception\ServiceNotFoundException
Expand All @@ -172,7 +179,15 @@ public static function make(string $service, array $parameters = [])
public static function get(string $service)
{
try {
return Pay::getContainer()->get($service);
$container = Pay::getContainer();

// thinkphp 在 `get` 中必须是已经 bind 的,否则会报错,所以这里用其 make 替代
switch (true) {
case $container instanceof ThinkPHPContainer:
return $container->make($service);
default:
return $container->get($service);
}
} catch (NotFoundExceptionInterface $e) {
throw new ServiceNotFoundException($e->getMessage());
} catch (ContainerNotFoundException $e) {
Expand Down
4 changes: 3 additions & 1 deletion src/Provider/AbstractProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use GuzzleHttp\Psr7\Utils;
use Psr\Http\Client\ClientInterface;
use Throwable;
use Yansongda\Pay\Contract\ContainerInterface;
use Yansongda\Pay\Contract\HttpClientInterface;
use Yansongda\Pay\Contract\PluginInterface;
use Yansongda\Pay\Contract\ProviderInterface;
Expand Down Expand Up @@ -53,6 +54,7 @@ public function call(string $plugin, array $params = [])
*
* @throws \Yansongda\Pay\Exception\ContainerException
* @throws \Yansongda\Pay\Exception\InvalidParamsException
* @throws \Yansongda\Pay\Exception\ServiceNotFoundException
*/
public function pay(array $plugins, array $params)
{
Expand All @@ -63,7 +65,7 @@ public function pay(array $plugins, array $params)
$this->verifyPlugin($plugins);

/* @var Pipeline $pipeline */
$pipeline = Pay::make(Pipeline::class);
$pipeline = Pay::make(Pipeline::class, [Pay::get(ContainerInterface::class)]);

/* @var Rocket $rocket */
$rocket = $pipeline
Expand Down
34 changes: 28 additions & 6 deletions src/Service/ContainerServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,25 @@
use Closure;
use DI\ContainerBuilder;
use Hyperf\Utils\ApplicationContext as HyperfApplication;
use Illuminate\Container\Container as LaravelContainer;
use Illuminate\Container\Container as LaravelApplication;
use Psr\Container\ContainerInterface;
use think\Container as ThinkPHPApplication;
use Throwable;
use Yansongda\Pay\Contract\ServiceProviderInterface;
use Yansongda\Pay\Exception\ContainerException;
use Yansongda\Pay\Exception\ContainerNotFoundException;
use Yansongda\Pay\Exception\Exception;
use Yansongda\Pay\Pay;

/**
* @codeCoverageIgnore
*/
class ContainerServiceProvider implements ServiceProviderInterface
{
private $detectApplication = [
'laravel' => LaravelContainer::class,
'laravel' => LaravelApplication::class,
'hyperf' => HyperfApplication::class,
'thinkphp' => ThinkPHPApplication::class,
];

/**
Expand Down Expand Up @@ -55,12 +60,12 @@ public function register($data = null): void
*/
protected function laravelApplication(): bool
{
Pay::setContainer(static fn () => LaravelContainer::getInstance());
Pay::setContainer(static fn () => LaravelApplication::getInstance());

Pay::set(\Yansongda\Pay\Contract\ContainerInterface::class, LaravelContainer::getInstance());
Pay::set(\Yansongda\Pay\Contract\ContainerInterface::class, LaravelApplication::getInstance());

if (!Pay::has(ContainerInterface::class)) {
Pay::set(ContainerInterface::class, LaravelContainer::getInstance());
Pay::set(ContainerInterface::class, LaravelApplication::getInstance());
}

return true;
Expand All @@ -81,7 +86,24 @@ protected function hyperfApplication(): bool
Pay::set(\Yansongda\Pay\Contract\ContainerInterface::class, HyperfApplication::getContainer());

if (!Pay::has(ContainerInterface::class)) {
Pay::set(ContainerInterface::class, HyperfApplication::getContainer());
Pay::set(ContainerInterface::class, HyperfApplication::getInstance());
}

return true;
}

/**
* @throws \Yansongda\Pay\Exception\ContainerException
* @throws \Yansongda\Pay\Exception\ContainerNotFoundException
*/
protected function thinkphpApplication(): bool
{
Pay::setContainer(static fn () => ThinkPHPApplication::getInstance());

Pay::set(\Yansongda\Pay\Contract\ContainerInterface::class, ThinkPHPApplication::getInstance());

if (!Pay::has(ContainerInterface::class)) {
Pay::set(ContainerInterface::class, ThinkPHPApplication::getInstance());
}

return true;
Expand Down