GithubHelp home page GithubHelp logo

Comments (7)

jbboehr avatar jbboehr commented on June 3, 2024 2

This does appear to be an issue, however the API for describing default parameter values in PHP 7 for extensions doesn't seem to allow it:
https://github.com/php/php-src/blob/caf3c64339791e801b8d9c560e0f05d1d94a0f52/Zend/zend_API.h#L101

Here's where the error is thrown in the reflection module:
https://github.com/php/php-src/blob/caf3c64339791e801b8d9c560e0f05d1d94a0f52/ext/reflection/php_reflection.c#L1397

From what I can tell, reflection is getting the default value by looking at the function opcodes, and, well, since internal functions don't have opcodes there is nothing to look at.

I agree that the current behavior of the extension is not optimal, but I don't really see a solution to the problem on my end. I will have to think about it and research some more.

from php-psr.

jbboehr avatar jbboehr commented on June 3, 2024 1

For reference, here is the commit to php-src that will allow this to work on PHP 8: php/php-src@3709e74

from php-psr.

ihor-sviziev avatar ihor-sviziev commented on June 3, 2024

@jbboehr could you check this issue?

from php-psr.

ihor-sviziev avatar ihor-sviziev commented on June 3, 2024

@jbboehr oh... I got it. Do you thing we have some workaround?

from php-psr.

jbboehr avatar jbboehr commented on June 3, 2024

If it's not too much trouble, can I see a copy of an invalid generated/code/Psr/Log/LoggerInterface/Proxy.php? I tried looking at the magento repo, but it's not committed.

It pains me to say this, but I don't see a practical workaround on my end. PHP 7's reflection will not report a default value for an internal function.

On the bright side, if I understand it correctly, it appears that PHP has implemented this functionality for PHP 8, so the extension will be correct in PHP 8 if I make the appropriate changes.

from php-psr.

jbboehr avatar jbboehr commented on June 3, 2024

I hate to be that guy but the PSR interfaces are, like, super frozen so, in theory, you shouldn't have to call reflection on them.

from php-psr.

ihor-sviziev avatar ihor-sviziev commented on June 3, 2024

@jbboehr In magento we have code generation mechanism that creates "Proxy" class for the original class or interface. The instance of the interface/class will be created through ObjectManager only when some method will be called on proxy.

For creating such Proxy magento uses reflection and it worked fine with all cases, except this one.

Here us two examples:

generated/code/Psr/Log/LoggerInterface/Proxy.php with psr extension
<?php
namespace Psr\Log\LoggerInterface;

/**
 * Proxy class for @see \Psr\Log\LoggerInterface
 */
class Proxy implements \Psr\Log\LoggerInterface, \Magento\Framework\ObjectManager\NoninterceptableInterface
{
    /**
     * Object Manager instance
     *
     * @var \Magento\Framework\ObjectManagerInterface
     */
    protected $_objectManager = null;

    /**
     * Proxied instance name
     *
     * @var string
     */
    protected $_instanceName = null;

    /**
     * Proxied instance
     *
     * @var \Psr\Log\LoggerInterface
     */
    protected $_subject = null;

    /**
     * Instance shareability flag
     *
     * @var bool
     */
    protected $_isShared = null;

    /**
     * Proxy constructor
     *
     * @param \Magento\Framework\ObjectManagerInterface $objectManager
     * @param string $instanceName
     * @param bool $shared
     */
    public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager, $instanceName = '\\Psr\\Log\\LoggerInterface', $shared = true)
    {
        $this->_objectManager = $objectManager;
        $this->_instanceName = $instanceName;
        $this->_isShared = $shared;
    }

    /**
     * @return array
     */
    public function __sleep()
    {
        return ['_subject', '_isShared', '_instanceName'];
    }

    /**
     * Retrieve ObjectManager from global scope
     */
    public function __wakeup()
    {
        $this->_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    }

    /**
     * Clone proxied instance
     */
    public function __clone()
    {
        $this->_subject = clone $this->_getSubject();
    }

    /**
     * Get proxied instance
     *
     * @return \Psr\Log\LoggerInterface
     */
    protected function _getSubject()
    {
        if (!$this->_subject) {
            $this->_subject = true === $this->_isShared
                ? $this->_objectManager->get($this->_instanceName)
                : $this->_objectManager->create($this->_instanceName);
        }
        return $this->_subject;
    }

    /**
     * {@inheritdoc}
     */
    public function emergency($message, array $context)
    {
        return $this->_getSubject()->emergency($message, $context);
    }

    /**
     * {@inheritdoc}
     */
    public function alert($message, array $context)
    {
        return $this->_getSubject()->alert($message, $context);
    }

    /**
     * {@inheritdoc}
     */
    public function critical($message, array $context)
    {
        return $this->_getSubject()->critical($message, $context);
    }

    /**
     * {@inheritdoc}
     */
    public function error($message, array $context)
    {
        return $this->_getSubject()->error($message, $context);
    }

    /**
     * {@inheritdoc}
     */
    public function warning($message, array $context)
    {
        return $this->_getSubject()->warning($message, $context);
    }

    /**
     * {@inheritdoc}
     */
    public function notice($message, array $context)
    {
        return $this->_getSubject()->notice($message, $context);
    }

    /**
     * {@inheritdoc}
     */
    public function info($message, array $context)
    {
        return $this->_getSubject()->info($message, $context);
    }

    /**
     * {@inheritdoc}
     */
    public function debug($message, array $context)
    {
        return $this->_getSubject()->debug($message, $context);
    }

    /**
     * {@inheritdoc}
     */
    public function log($level, $message, array $context)
    {
        return $this->_getSubject()->log($level, $message, $context);
    }
}
generated/code/Psr/Log/LoggerInterface/Proxy.php without psr extension
<?php
namespace Psr\Log\LoggerInterface;

/**
 * Proxy class for @see \Psr\Log\LoggerInterface
 */
class Proxy implements \Psr\Log\LoggerInterface, \Magento\Framework\ObjectManager\NoninterceptableInterface
{
    /**
     * Object Manager instance
     *
     * @var \Magento\Framework\ObjectManagerInterface
     */
    protected $_objectManager = null;

    /**
     * Proxied instance name
     *
     * @var string
     */
    protected $_instanceName = null;

    /**
     * Proxied instance
     *
     * @var \Psr\Log\LoggerInterface
     */
    protected $_subject = null;

    /**
     * Instance shareability flag
     *
     * @var bool
     */
    protected $_isShared = null;

    /**
     * Proxy constructor
     *
     * @param \Magento\Framework\ObjectManagerInterface $objectManager
     * @param string $instanceName
     * @param bool $shared
     */
    public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager, $instanceName = '\\Psr\\Log\\LoggerInterface', $shared = true)
    {
        $this->_objectManager = $objectManager;
        $this->_instanceName = $instanceName;
        $this->_isShared = $shared;
    }

    /**
     * @return array
     */
    public function __sleep()
    {
        return ['_subject', '_isShared', '_instanceName'];
    }

    /**
     * Retrieve ObjectManager from global scope
     */
    public function __wakeup()
    {
        $this->_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    }

    /**
     * Clone proxied instance
     */
    public function __clone()
    {
        $this->_subject = clone $this->_getSubject();
    }

    /**
     * Get proxied instance
     *
     * @return \Psr\Log\LoggerInterface
     */
    protected function _getSubject()
    {
        if (!$this->_subject) {
            $this->_subject = true === $this->_isShared
                ? $this->_objectManager->get($this->_instanceName)
                : $this->_objectManager->create($this->_instanceName);
        }
        return $this->_subject;
    }

    /**
     * {@inheritdoc}
     */
    public function emergency($message, array $context = [])
    {
        return $this->_getSubject()->emergency($message, $context);
    }

    /**
     * {@inheritdoc}
     */
    public function alert($message, array $context = [])
    {
        return $this->_getSubject()->alert($message, $context);
    }

    /**
     * {@inheritdoc}
     */
    public function critical($message, array $context = [])
    {
        return $this->_getSubject()->critical($message, $context);
    }

    /**
     * {@inheritdoc}
     */
    public function error($message, array $context = [])
    {
        return $this->_getSubject()->error($message, $context);
    }

    /**
     * {@inheritdoc}
     */
    public function warning($message, array $context = [])
    {
        return $this->_getSubject()->warning($message, $context);
    }

    /**
     * {@inheritdoc}
     */
    public function notice($message, array $context = [])
    {
        return $this->_getSubject()->notice($message, $context);
    }

    /**
     * {@inheritdoc}
     */
    public function info($message, array $context = [])
    {
        return $this->_getSubject()->info($message, $context);
    }

    /**
     * {@inheritdoc}
     */
    public function debug($message, array $context = [])
    {
        return $this->_getSubject()->debug($message, $context);
    }

    /**
     * {@inheritdoc}
     */
    public function log($level, $message, array $context = [])
    {
        return $this->_getSubject()->log($level, $message, $context);
    }
}

Technically we might add some special case if we're generating Proxy class for the \Psr\Log\LoggerInterface and psr extension is enabled - then add default values, but I think that's not right solution.

As a workaround for now we're going to add info that psr extension is causing issues for Magento 2 and recommend not to use it, till the issue will be resolved on any side - in the extension (I see it's possible only since php 8) or on Magento side.

from php-psr.

Related Issues (20)

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.