Adapting a class Using php's __call method: Pa

2019-08-17 08:50发布

Based upon answer on my Symfony 3.4 project I thought of using the magic __call method in order to have a common way to invoke repositories as a service:

namespace AppBundle\Services;

use Doctrine\ORM\EntityManagerInterface;

class RepositoryServiceAdapter
{
        private $repository=null;

        /**
        * @param EntityManagerInterface the Doctrine entity Manager
        * @param String $entityName The name of the entity that we will retrieve the repository
        */
        public function __construct(EntityManagerInterface $entityManager,$entityName)
        {
            $this->repository=$entityManager->getRepository($entityName)
        }

        public function __call($name,$arguments)
        {     
          if(empty($arguments)){ //No arguments has been passed
             $this->repository->$name();
          } else {
             //@todo: figure out how to pass the parameters
             $this->repository->$name();
          }
        }
}

But I got stuck to this problem:

A repository method will have this form:

public function aMethod($param1,$param2)
{
  //Some magic is done here
}

So I will need somehow to iterate the array $arguments in order to pass the parameters to the function if I knew exactly what method would be called I would arbitatily pass the parameters, for example if I knew that a method had 3 parameters I would use:

        public function __call($name,$arguments)
        {
           $this->repository->$name($argument[0],$argument[1],$argument[2]);
        }

But that seems impractical and not a concrete solution for me because a method can have more than 1 parameters. I think I need to solve the following problems:

  1. How I will find out how many parameters a method has?
  2. How to pass the arguments while iterating the array $arguments?

1条回答
孤傲高冷的网名
2楼-- · 2019-08-17 09:05

As of PHP 5.6 you have argument unpacking which allows you to do exactly what your after using ..., so

$this->repository->$name($argument[0],$argument[1],$argument[2]);

becomes...

$this->repository->$name(...$argument);

This will pass any number or arguments as though they are individual fields.

查看更多
登录 后发表回答