Skip to content

Commit

Permalink
Merge pull request #60 from lucatume/wrap-59
Browse files Browse the repository at this point in the history
wrap 59
  • Loading branch information
lucatume authored Sep 1, 2023
2 parents a86c6d3 + a7cf889 commit ff465ea
Show file tree
Hide file tree
Showing 9 changed files with 227 additions and 167 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ to [Semantic Versioning](http://semver.org/).

## [unreleased] Unreleased

### Changed

- Added [PHPStan generics](https://phpstan.org/blog/generics-in-php-using-phpdocs) to multiple classes. IDEs that support them will get autocompletion (.phpstorm.meta.php not required) if a fully-qualified class name is used, e.g. `$instance = $container->get( Test::class );`.

## [3.3.4] 2023-06-20;

### Added
Expand Down
18 changes: 16 additions & 2 deletions config/containers/php/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,23 @@ FROM composer:2.2 as composer

FROM php:${PHP_VERSION}-cli-alpine

ARG XDEBUG_SRC='xdebug'

COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/bin/
RUN install-php-extensions xdebug && apk add gettext && rm -rf /var/cache/apk/*
RUN rm /usr/bin/install-php-extensions
# If the XDEBUG_SRC starts with http, download, extract and prepare it.
RUN if echo ${XDEBUG_SRC} | grep -Eq '^http'; then \
curl -k -o /tmp/xdebug.tgz ${XDEBUG_SRC} && \
XDEBUG_VERSION=$(echo ${XDEBUG_SRC} | sed -e 's/.*xdebug-\(.*\)\.tgz/\1/') && \
tar xzf /tmp/xdebug.tgz -C /tmp && \
mv /tmp/package.xml /tmp/xdebug-${XDEBUG_VERSION} && \
rm /tmp/xdebug.tgz && \
XDEBUG_SRC=/tmp/xdebug-${XDEBUG_VERSION}; \
fi \
&& install-php-extensions ${XDEBUG_SRC} \
&& apk add gettext \
&& rm -rf /var/cache/apk/* \
&& rm /usr/bin/install-php-extensions \
&& rm -rf /tmp/xdebug.tgz /tmp/xdebug-${XDEBUG_VERSION}

ARG XDEBUG_REMOTE_HOST='host.docker.internal'
ARG XDEBUG_REMOTE_PORT='9009'
Expand Down
20 changes: 20 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,37 @@ PROJECT_NAME = $(notdir $(PWD))
#.SILENT:
PHP_VERSION ?= 5.6

# Create a function that will return the xdebug source depending on the PHP version.
define xdebug_src
@if [ "$(1)" = 5.6 ]; \
then echo "https://pecl.php.net/get/xdebug-2.5.5.tgz"; \
elif [ "$(1)" = 7.0 ]; \
then echo "https://pecl.php.net/get/xdebug-2.7.2.tgz"; \
else \
echo "xdebug"; \
fi
endef

php_versions :=5.6 7.0 7.1 7.2 7.3 7.4 8.0 8.1 8.2
build: $(build_php_versions) ## Builds the project PHP images.
mkdir -p var/cache/composer
mkdir -p var/log
# Foreach PHP version build a Docker image.
for version in $(php_versions); do \
if [ "$${version}" = 5.6 ]; \
then export XDEBUG_SRC="https://pecl.php.net/get/xdebug-2.5.5.tgz"; \
elif [ "$${version}" = 7.0 ]; \
then export XDEBUG_SRC="https://pecl.php.net/get/xdebug-2.7.2.tgz"; \
else \
export XDEBUG_SRC="xdebug"; \
fi; \
docker build \
--build-arg PHP_VERSION=$${version} \
--build-arg XDEBUG_REMOTE_HOST=$${XDEBUG_REMOTE_HOST:-host.docker.internal} \
--build-arg XDEBUG_REMOTE_PORT=$${XDEBUG_REMOTE_PORT:-9009} \
--build-arg WORKDIR=${PWD} \
--build-arg XDEBUG_SRC=$${XDEBUG_SRC} \
--progress plain \
config/containers/php \
--tag lucatume/di52-dev:php-v$${version}; \
done
Expand Down
121 changes: 64 additions & 57 deletions src/App.php

Large diffs are not rendered by default.

26 changes: 16 additions & 10 deletions src/Builders/ClassBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use lucatume\DI52\ContainerException;
use lucatume\DI52\NotFoundException;
use ReflectionException;
use ReflectionMethod;

/**
Expand Down Expand Up @@ -37,7 +38,7 @@ class ClassBuilder implements BuilderInterface, ReinitializableBuilderInterface
/**
* The fully-qualified class name the builder should build instances of.
*
* @var string
* @var class-string
*/
protected $className;
/**
Expand Down Expand Up @@ -65,20 +66,20 @@ class ClassBuilder implements BuilderInterface, ReinitializableBuilderInterface
/**
* ClassBuilder constructor.
*
* @param string $id The identifier associated with this builder.
* @param Resolver $resolver A reference to the resolver currently using the builder.
* @param string $className The fully-qualified class name to build instances for.
* @param array<string>|null $afterBuildMethods An optional set of methods to call on the built object.
* @param mixed ...$buildArgs An optional set of build arguments that should be provided to the
* class constructor method.
* @param string|class-string $id The identifier associated with this builder.
* @param Resolver $resolver A reference to the resolver currently using the builder.
* @param string $className The fully-qualified class name to build instances for.
* @param array<string>|null $afterBuildMethods An optional set of methods to call on the built object.
* @param mixed ...$buildArgs An optional set of build arguments that should be provided to
* the class constructor method.
*
* @throws NotFoundException If the class does not exist.
*/
public function __construct($id, Resolver $resolver, $className, array $afterBuildMethods = null, ...$buildArgs)
{
if (!class_exists($className)) {
throw new NotFoundException(
"nothing is bound to the '{$className}' id and it's not an existing or instantiable class."
"nothing is bound to the '$className' id and it's not an existing or instantiable class."
);
}

Expand All @@ -99,6 +100,8 @@ public function __construct($id, Resolver $resolver, $className, array $afterBui
* Builds and returns an instance of the class.
*
* @return object An instance of the class.
*
* @throws ContainerException
*/
public function build()
{
Expand Down Expand Up @@ -145,7 +148,8 @@ protected function resolveConstructorParameters()
/**
* Returns a set of resolved constructor parameters.
*
* @param string $className The fully-qualified class name to get the resolved constructor parameters yet.
* @param class-string $className The fully-qualified class name to get the resolved constructor parameters yet.
*
* @return array<Parameter> A set of resolved constructor parameters.
*
* @throws ContainerException If the resolution of any constructor parameters is problematic.
Expand All @@ -158,7 +162,7 @@ protected function getResolvedConstructorParameters($className)

try {
$constructorReflection = new ReflectionMethod($className, '__construct');
} catch (\ReflectionException $e) {
} catch (ReflectionException $e) {
static::$constructorParametersCache[$className] = [];
// No constructor method, no args.
return [];
Expand All @@ -185,6 +189,8 @@ protected function getResolvedConstructorParameters($className)
* @param mixed $arg The argument id or value to resolve.
*
* @return mixed The resolved build argument.
*
* @throws NotFoundException
*/
protected function resolveBuildArg($arg)
{
Expand Down
13 changes: 6 additions & 7 deletions src/Builders/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,12 @@ public function __construct(Container $container, Resolver $resolver)
/**
* Returns the correct builder for a value.
*
* @param string|mixed $id The string id to provide a builder for, or a value.
* @param mixed $implementation The implementation to build the builder for.
* @param array<string>|null $afterBuildMethods A list of methods that should be called on the built instance
* after
* it's been built.
* @param mixed ...$buildArgs A set of arguments to pass that should be used to build the
* instance, if any.
* @param string|class-string|mixed $id The string id to provide a builder for, or a value.
* @param mixed $implementation The implementation to build the builder for.
* @param string[]|null $afterBuildMethods A list of methods that should be called on the built
* instance after it's been built.
* @param mixed ...$buildArgs A set of arguments to pass that should be used to build
* the instance, if any.
*
* @return BuilderInterface A builder instance.
*
Expand Down
2 changes: 1 addition & 1 deletion src/Builders/Parameter.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ private function isClass()
}

try {
if (function_exists('enum_exists') && enum_exists($this->type)) {
if (function_exists('enum_exists') && enum_exists((string) $this->type)) {
return false;
}
} catch (ParseError $e) {
Expand Down
66 changes: 35 additions & 31 deletions src/Builders/Resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ public function __construct($resolveUnboundAsSingletons = false)
/**
* Binds an implementation for an id, or class name, as prototype (build new each time).
*
* @param string $id The id to register the implementation for.
* @param BuilderInterface $implementation The builder that will provide the implementation for the id.
* @param string|class-string $id The id to register the implementation for.
* @param BuilderInterface $implementation The builder that will provide the implementation for the id.
*
* @return void This method does not return any value.
*/
Expand All @@ -78,9 +78,9 @@ public function bind($id, BuilderInterface $implementation)
/**
* Registers an implementation for an id, or class name, as singleton (build at most once).
*
* @param string $id The id to register the implementation for.
* @param BuilderInterface $implementation The builder that will provide the implementation for
* the id.
* @param string|class-string $id The id to register the implementation for.
* @param BuilderInterface $implementation The builder that will provide the implementation for
* the id.
*
* @return void This method does not return any value.
*/
Expand All @@ -105,7 +105,7 @@ public function isBound($id)
/**
* Removes the relation between an id and a bound implementation from the resolver.
*
* @param string $id The id to unregister the implementation for.
* @param string|class-string $id The id to unregister the implementation for.
*
* @return void This method does not return any value.
*/
Expand All @@ -117,7 +117,7 @@ public function unbind($id)
/**
* Returns whether a specific id is bound as singleton (build at most once), or not.
*
* @param string $id The id to check.
* @param string|class-string $id The id to check.
*
* @return bool Whether a specific id is bound as singleton (build at most once), or not.
*/
Expand All @@ -129,8 +129,8 @@ public function isSingleton($id)
/**
* Transform the canonical class to the class part of a when-needs-give specification, if required.
*
* @param string $id The ID to resolve the when-needs-give case for.
* @param string $paramClass The class of the parameter to solve the when-needs-give case for.
* @param string|class-string $id The ID to resolve the when-needs-give case for.
* @param string $paramClass The class of the parameter to solve the when-needs-give case for.
*
* @return BuilderInterface|string Either the builder for the when-needs-give replacement, or the input parameter
* class if not found.
Expand All @@ -145,10 +145,10 @@ public function whenNeedsGive($id, $paramClass)
/**
* Sets an entry in the when->needs->give chain.
*
* @param string $whenClass The "when" part of the chain, a class name or id.
* @param string $needsClass The "needs" part of the chain, a class name or id.
* @param BuilderInterface $builder The Builder instance that should be returned when a class needs the
* specified id.
* @param string|class-string $whenClass The "when" part of the chain, a class name or id.
* @param string|class-string $needsClass The "needs" part of the chain, a class name or id.
* @param BuilderInterface $builder The Builder instance that should be returned when a class needs the
* specified id.
*
* @return void This method does not return any value.
*/
Expand All @@ -160,11 +160,12 @@ public function setWhenNeedsGive($whenClass, $needsClass, BuilderInterface $buil
/**
* Resolves an ide to an implementation with the input arguments.
*
* @param string|mixed $id The id, class name or built value to resolve.
* @param array<string>|null $afterBuildMethods A list of methods that should run on the built
* @param string|class-string|mixed $id The id, class name or built value to resolve.
* @param string[]|null $afterBuildMethods A list of methods that should run on the built
* instance.
* @param mixed ...$buildArgs A set of build arguments that will be passed to
* @param mixed ...$buildArgs A set of build arguments that will be passed to
* the implementation constructor.
*
* @return BuilderInterface|ReinitializableBuilderInterface|mixed The builder, set up to use the specified set of
* build arguments.
* @throws NotFoundException If the id is a string that does not resolve to an existing, concrete, class.
Expand All @@ -184,11 +185,15 @@ public function resolveWithArgs($id, array $afterBuildMethods = null, ...$buildA
/**
* Resolves an id or input value to a value or object instance.
*
* @param string|mixed $id Either the id of a bound implementation, a class name or an object
* to resolve.
* @param array<string>|null $buildLine The build line to append the resolution leafs to, or `null` to use the
* current one.
* @return mixed The resolved value or instance.
* @template T
*
* @param string|class-string<T>|mixed $id Either the id of a bound implementation, a class name or an
* object to resolve.
* @param string[]|null $buildLine The build line to append the resolution leafs to, or `null` to
* use the current one.
*
* @return T|mixed The resolved value or instance.
* @phpstan-return ($id is class-string ? T : mixed)
*
* @throws NotFoundException If the id is a string that is not bound and is not an existing, concrete, class.
*/
Expand Down Expand Up @@ -218,7 +223,7 @@ public function resolve($id, array $buildLine = null)
/**
* Builds, with auto-wiring, an instance of a not bound class.
*
* @param string $id The class name to build an instance of.
* @param string|class-string $id The class name to build an instance of.
*
* @return object The built class instance.
*
Expand All @@ -239,7 +244,7 @@ private function resolveUnbound($id)
/**
* Resolves a bound implementation to a value or object.
*
* @param string $id The id to resolve the implementation for.
* @param string|class-string $id The id to resolve the implementation for.
*
* @return mixed The resolved instance.
*/
Expand All @@ -255,15 +260,14 @@ private function resolveBound($id)

/**
* Clones the builder assigned to an id and re-initializes it.
*
* The clone operation leverages the already resolved dependencies of a builder to create an up-to-date instance.
*
* @param string $id The id to clone the builder of.
* @param array<string>|null $afterBuildMethods A set of methods to run on the built instance.
* @param mixed ...$buildArgs An optional set of arguments that will be passed to the instance
* constructor.
* @return BuilderInterface A new instance of the builder currently related to the id.
* @param string|class-string $id The id to clone the builder of.
* @param string[]|null $afterBuildMethods A set of methods to run on the built instance.
* @param mixed ...$buildArgs An optional set of arguments that will be passed to the instance
* constructor.
*
* @return BuilderInterface A new instance of the builder currently related to the id.
* @throws NotFoundException If trying to clone the builder for a non existing id or an id that does not map to a
* concrete class name.
*/
Expand Down Expand Up @@ -291,7 +295,7 @@ private function cloneBuilder($id, array $afterBuildMethods = null, ...$buildArg
*/
public function addToBuildLine($type, $parameterName)
{
$this->buildLine[] = trim("{$type} \${$parameterName}");
$this->buildLine[] = trim("$type \$$parameterName");
}

/**
Expand All @@ -300,7 +304,7 @@ public function addToBuildLine($type, $parameterName)
* The build line will return a straight path from the current resolution root to the leaf
* currently being resolved. Used for error logging and formatting.
*
* @return array<string> A set of consecutive items the resolver is currently trying to build.
* @return string[] A set of consecutive items the resolver is currently trying to build.
*/
public function getBuildLine()
{
Expand Down
Loading

0 comments on commit ff465ea

Please sign in to comment.