Giter Club home page Giter Club logo

laminas-di's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laminas-di's Issues

Improve migration from zend-servicemanager-di

From PR #35

ZF is aiming to allow easy migrations to new component versions whenever possible. For zend-di there is a component that integrated version 2 into zend-servicemanager.
Version 3 introduced a conflict-entry in it's composer.json, that states clearly zend-servicemanager-di is no longer needed. But it will also urge consumers to potentially upgrade many parts of their application.

To make life easier for these users, we should provide a new version for zend-servicemanager-di, that will deprecate it's own usage but allowing the user's to remove it's parts step by step.

Link to the discourse topic

This issue should keep track of this topic after migration to Laminas is complete.


Originally posted by @tux-rampage at zendframework/zend-di#58

Update Coding Standard to v2

There are a lot of new conventions that are not covered by the current phpcs ruleset of zend-coding-standard (v1.x).

Some examples are (incomplete list):

  • Whitespace after cast operators
  • Whitespace after not operator (!)
  • Whitespaces before and after ternary operators
  • Trailing comma for the last element in array declarations

A new coding style and tooling is currently work in progress at zendframework/zend-coding-standard#5. When this PR is merged and v2 is released this zend-di should integrate it.

Depending on my availability, I'll perform the tests as suggested in the mentioned PR.


Originally posted by @tux-rampage at zendframework/zend-di#39

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Repository problems

These problems occurred while renovating this repository. View logs.

  • WARN: Use matchDepNames instead of matchPackageNames

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

composer
composer.json
  • php ~8.1.0 || ~8.2.0 || ~8.3.0
  • laminas/laminas-stdlib ^3.18.0
  • psr/container ^1.1.1
  • psr/log ^1.1.4 || ^2.0.0 || ^3.0.0
  • laminas/laminas-coding-standard ~2.5.0
  • laminas/laminas-servicemanager ^3.22
  • mikey179/vfsstream ^1.6.11@alpha
  • phpbench/phpbench ^1.2.7
  • phpunit/phpunit ^9.5.26
  • psalm/plugin-phpunit ^0.18.0
  • squizlabs/php_codesniffer ^3.7.1
  • vimeo/psalm ^5.0
github-actions
.github/workflows/continuous-integration.yml
.github/workflows/docs-build.yml
.github/workflows/release-on-milestone-closed.yml

  • Check this box to trigger a request for Renovate to run again on this repository

laminas/laminas-crypt:^3.4 provoques Exception

Bug Report

Installing on Symfony 6.2 project with PHP 8.1

Q A
Version(s) 3.0.6

Summary

Get this Exception :

PHP Fatal error: Declaration of Laminas......::has($name) must be compatible with Psr\Container\ContainerInterface::has(string $id): bool in /path/info line int

Same as described here: #78

Expected behavior

Solution: replace laminas/laminas-crypt:^3.4 by laminas/laminas-crypt:^3.10 where bug has been fixed.

[RFC]: Move AoT into a separate component

RFC

Q A
Proposed Version(s) 4.0.0
BC Break? Yes

Goal

Provide users an option to add the AoT compiler as a dev dependency

Background

At the Moment the AoT compiler is part of this package, but it should not be a requirement for running the application.
Therefore the AoT compiler should be extracted and provided in a separate package and all AoT-only code should be stripped from this repo.

Considerations

The existing AoT compiler should be deprecated and Facaded within the AoT Package to provide a migration path without breaking at the first update.

Proposal(s)

  • Create a new repo with an AoT compiler and propose it for transition into the laminas project.
  • This package should receive a proper suggest entry.
  • The documentation should receive a guide on how to migrate to the new AoT, at best there will be tooling to support this

Appendix

PHP 8 union types, [presumably same for 8.1 intersection types].

Bug Report

Q A
Version(s) 3.7.x

Summary

When trying to create an object that depends on a union type in its constructor, a call to Injector::create() results in an error.

Current behavior

The Injector::class forwards the resolveParameters() call to the DependencyResolver::resolveParameters() method, which, at L#280 makes a call to Parameter::getType(). Within this method, a call is made to the underlying object's ReflectionParameter::getType() method is made. The returned object by getType() is a ReflectionUnionType::class, which has no method getName() defined, and hence, it crashes the program due to L#63.

The error message:
Error: Call to undefined method ReflectionUnionType::getName()

How to reproduce

Settings:
PHP 8.0.19 (cli)

Class definition:

class Foo
{
    public function __construct(private string|Stringable $s)
    {
    }

    public function getS(): string|Stringable
    {
        return $this->s;
    }
}

Test case:

public function testCreateClassWithUnionTypeParameterAsConstructorArgument(): void
{
    $injector = new Injector();
    
    $s       = 'Hello, World';
    $foo     = $injector->create(Foo::class, ['s' => $s]);
    $actualS = $foo->getS();

    $this->assertEquals($s, $actualS);
}

Expected behavior

An instance of Foo::class constructed with the property $s set to the string value 'Hello, World'.

PS

I am sorry if this is not considered a bug, but I did not know where to otherwise post this matter. Please let me know what you think of the above stated.

[RFC]: Drop runtime deprecations where possible

RFC

Q A
Proposed Version(s) 3.4.0
BC Break? ?

Goal

Reduce the maintenance Overhead and runtime cost when deprecating elements.

Background

Since static analysis tools like psalm have become quite powerful to analyse the code before it gets executed.
Therefore we should drop every trigger_error of a E_USER_DEPRECATED where a deprecation is already caught by static analysis. We should only keep it, where static analysis tool cannot catch then (for example when config keys have changed).

Another extreme weakness of deprecation notices during runtime is, that they only occur when the code path is actually executed. This means deprecated elements may be still in use undiscovered for a long time until somebody hits the execution path by accident.

Runtime deprecations are also a horror to maintain and they usually require ugly work arounds to be added like in https://github.com/laminas/laminas-di/blob/3.4.x/phpcs.xml#L21

Considerations

Some library consumers may not use static analysis to validate their code which are then cut of from being noted about deprecations.

This is a sign of poor code quality and tech debt. We should encourage users to use static analysis instead relying on runtime behaviour.

Proposal(s)

  • Drop all trigger_error statements from the codebase where a deprecation annotation is used
  • Add @deprecated Doc-Block annotations (usually those are already present)
  • Add @see to point to an alternative or a migration guide for the user
  • Encourage users to use static analysis tools like psalm or phpstan to detect usage of deprecated elements

Appendix

  • Related PR #30

PHP 8.0 support

Feature Request

Q A
New Feature yes

Summary

To be prepared for the december release of PHP 8.0, this repository has some additional TODOs to be tested against the new major version.

In order to make this repository compatible, one has to follow these steps:

  • Modify composer.json to provide support for PHP 8.0 by adding the constraint ~8.0.0
  • Modify composer.json to drop support for PHP less than 7.3
  • Modify composer.json to implement phpunit 9.3 which supports PHP 7.3+
  • Modify .travis.yml to ignore platform requirements when installing composer dependencies (simply add --ignore-platform-reqs to COMPOSER_ARGS env variable)
  • Modify .travis.yml to add PHP 8.0 to the matrix (NOTE: Do not allow failures as PHP 8.0 has a feature freeze since 2020-08-04!)
  • Modify source code in case there are incompatibilities with PHP 8.0

Psalm integration

Feature Request

Q A
QA yes

Summary

As decided during the Technical-Steering-Committee Meeting on August 3rd, 2020, Laminas wants to implement vimeo/psalm in all packages.

Implementing psalm is quite easy.

Required

  • Create a psalm.xml in the project root
  • Copy and paste the contents from this psalm.xml.dist
  • Run $ composer require --dev vimeo/psalm
  • Run $ vendor/bin/psalm --set-baseline=psalm-baseline.xml
  • Add a composer script static-analysis with the command psalm --shepherd --stats
  • Add a new line to script: in .travis.yml: - if [[ $TEST_COVERAGE == 'true' ]]; then composer static-analysis ; fi
  • Remove phpstan from the project (phpstan.neon.dist, .travis.yml entry, composer.json require-dev and scripts)
Optional
  • Fix as many psalm errors as possible.

Better AoT compiler

In order to improve AoT compiler, on my project I've done some changes.

The problem is that with AoT, dependency factories are not created. To accomplish my goal I've made a simple DependencyScanner that try to fetch every dependency classes:

<?php

declare(strict_types=1);

namespace AppAoT\Scanner;

use Zend\Code\Reflection\ClassReflection;

class DependencyScanner
{
    /** @var string[] */
    private $classNamesToScan;

    /** @var string[] */
    private $classNames = [];

    /** @var bool */
    private $isScanned = false;

    /**
     * DependencyScanner constructor.
     *
     * @param string[] $classNamesToScan
     */
    public function __construct(array $classNamesToScan = [])
    {
        $this->classNamesToScan = $classNamesToScan;
    }

    protected function scan(): void
    {
        if ($this->isScanned) {
            return;
        }

        foreach ($this->classNamesToScan as $className)
        {
            $this->scanClass($className);
        }

        $this->isScanned = true;
    }

    protected function scanClass(string $name): void
    {
        if (! \class_exists($name)) {
            return;
        }

        if (\array_key_exists($name, $this->classNames)) {
            return;
        }

        $this->classNames[$name] = true;

        $classReflection = new ClassReflection($name);
        $constructor = $classReflection->getConstructor();

        if (null === $constructor) {
            return;
        }

        $parameters = $constructor->getParameters();

        foreach ($parameters as $parameter) {
            $class = $parameter->getClass();

            if (null === $class) {
                continue;
            }

            $this->scanClass($class->getName());
        }
    }

    /**
     * @return string[]
     */
    public function getClassNames(): array
    {
        $this->scan();
        
        return \array_keys($this->classNames);
    }
}

And changed my di-generate-aot.sh to use it, getting every psr-4 namespace directory (does not support dir arrays yet), and using the previous class to fetch every dependency class.

<?php

namespace AppAoT;

use AppAoT\Scanner\DependencyScanner;
use Psr\Container\ContainerInterface;
use Zend\Code\Scanner\DirectoryScanner;
use Zend\Di\CodeGenerator\InjectorGenerator;
use Zend\Di\ConfigInterface;
use Zend\Di\Definition\RuntimeDefinition;
use Zend\Di\Resolver\DependencyResolver;

require __DIR__ . '/../vendor/autoload.php';

$composerFile = __DIR__ . '/../composer.json';

if (! \is_readable($composerFile)) {
    throw new \RuntimeException('Unable to find composer.json');
}

$composer = \json_decode(\file_get_contents($composerFile), true);
$directories = \array_values($composer['autoload']['psr-4'] ?? []);

/** @var ContainerInterface $container */
$container = require __DIR__ . '/../config/container.php';
$config = $container->get(ConfigInterface::class);

$resolver = new DependencyResolver(new RuntimeDefinition(), $config);
$resolver->setContainer($container);

$scanner = new DirectoryScanner($directories);

$dependencyScanner = new DependencyScanner($scanner->getClassNames());
$classNames = $dependencyScanner->getClassNames();

$generator = new InjectorGenerator($config, $resolver, __NAMESPACE__ . '\Generated');
$generator->setOutputDirectory(__DIR__ . '/../src/AppAoT/gen');
$generator->generate($classNames);

It's just an example, but I think we can include something like that in zend-code and/or here, and improve the documentation in order to provide a better AoT compiler compared to others compiled containers.

P.S. It does not resolve aliases yet.


Originally posted by @thomasvargiu at zendframework/zend-di#42

Documentation AoT - factories + injector decorator

I think the documentation is wrong:
https://docs.zendframework.com/zend-di/cookbook/aot-guide/#5-add-aot-to-the-service-manager

In getDependencies method of ConfigProvider we have:

            'factories' => $this->getGeneratedFactories(),
            'delegators' => [
                InjectorInterface::class => [
                    InjectorDecoratorFactory::class,
                ],
            ],

but I think one of this configuration is useless.
If we inject generated factories in factories key then we don't need to use decorator (which uses GeneratedInjector and in fact is an abstract factory - but uses only generated factories list).

But in case we have factories injected already into service manager the abstract factory for the service is not going to be called as the factory is defined. If the factory is not defined (so for example service was added later and factories were not regenerated) then normal injector is going to be used anyway (generated injector is just the proxy to origin injector in case factory is not defined).

Of course it doesn't change too much, but in case we need use injector (abstract factory) we don't need to check again on generated list, as this is not there.


Originally posted by @michalbundyra at zendframework/zend-di#53

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.