douqiao4450 2015-06-12 19:49
浏览 33
已采纳

使用PHP输入参数的动态方法

I have the PHP legacy code below that intends to return the name of a method dynamically.

public function getMethod($fieldName){
    //do stuff
    return $methodName;
}

The returned method names are something like:

setClient

setName

setAge

All right here. The problem is when I use these methods. I have a class named Model, that has the folowing method:

class Model {
    public function find () {
        $nameClass = get_called_class();
        $instance  = new $nameClass;

        $result = $this->conn->select();//the select method returns a SQL SELECT from the database

        if (isset($result[0])) {
            foreach ($result[0] as $key => $val) {
                $methodProp = $this->getMethod(key);
                $instance->$methodProp($val);
            }
        } else {
            throw new Exception('You have a error in your class');
        }
    }

}

Here is the var_dump($result) as requested:

array (size=1)
    0 => 
    object(stdClass)[6]
         public 'id' => string '1' (length=1)
         public 'id_erp' => string '0' (length=1)
         public 'name' => string 'Derp' (length=18)
         public 'email' => null
         public 'type_ota' => null
         public 'user' => string 'derp_derp' (length=7)
         public 'password' => string '1234' (length=4)
         public 'url_logo' => null
         public 'status' => string '1' (length=1)
         public 'date' => string '2015-06-08 14:41:50' (length=19)

Then I have some classes that extends this Model:

class Company extends Model {
    public function setClient (Client $cli) {
       //do stuff
    }
    public function setName($name) {
       //do stuff
    }
    public function setAge($age) {
       //do stuff
    }
}
//here I use the class
$myCompany = new Company();
$myCompany->find();

The methods setName() and setAge() works fine, but setClient() returns

Catchable fatal error: Argument 1 passed to setClient() must be an instance of Client, string given

In short, how can I deal with dynamic methods and typing in PHP? Looking for help, I found something about Reflection, but I never used this class before and the examples that I found didn't help me, although I think that it's the right way.

Has anyone had a similar experience?

UPDATE

I tried to put some code in my question to clarify my problem.

  • 写回答

2条回答 默认 最新

  • doubu7134 2015-08-06 19:52
    关注

    If I understand your question correctly, you want to check what typehint the method wants. I took this code snippet from the docs.

    <?php
    //Target our class
    $reflector = new ReflectionClass('MyClass');
    
    //Get the parameters of a method
    $parameters = $reflector->getMethod('FireCannon')->getParameters();
    
    //Loop through each parameter and get the type
    foreach($parameters as $param)
    {
         //Before you call getClass() that class must be defined!
         echo $param->getClass()->name;
    }
    

    To add the code above to your code. This would check if the parameter in the method is an object, if is an object it will check that the class is the same as the value given. If the parameter is not an object, you can either just call the method, or if you typehint your non-object parameters, you can check that they are equal as well. This code should definitely be modified and cleaned up, but I thought it would be enough to get my point across.

    class Model {
        public function find () {
            $nameClass = get_called_class();
            $instance  = new $nameClass;
    
            $result = $this->conn->select();//the select method returns a SQL SELECT from the database
    
            if (!isset($result[0])) {
                throw new Exception('You have a error in your class');
            }
            foreach ($result[0] as $key => $val) {
                $methodProp = $this->getMethod($key);
    
                $reflector = new ReflectionClass($nameClass);
                $reflectorMethod = $reflector->getMethod($methodProp);
    
                // Make sure method doesn't require more than one param,
                // and it has defined at least one param.
                if ($reflectorMethod->getNumberOfRequiredParameters() > 1 ||
                    $reflectorMethod->getNumberOfParameters() < 1
                ) {
                    // Throw error
                }
    
                //Get the parameters of a method
                $parameters = $reflectorMethod->getParameters();
    
               if (is_object($parameters[0])) {
                   if (!is_object($val) {
                       // Throw error
                   }
                   //Before you call get_class() that class must be defined!
                   //Use either class_exists($nameClass); or 
                   //in_array($nameClass, get_declared_classes()); to check.
                   if ($val->getClass()->name !== get_class($parameters[0])) {
                       // Throw error
                   }
               } else if (gettype($parameters[0]) !== gettype($val)) {
                   // Throw error
               }
               $instance->$methodProp($val);
            }
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 springboot 3.0 实现Security 6.x版本集成
  • ¥15 PHP-8.1 镜像无法用dockerfile里的CMD命令启动 只能进入容器启动,如何解决?(操作系统-ubuntu)
  • ¥15 请帮我解决一下下面六个代码
  • ¥15 关于资源监视工具的e-care有知道的嘛
  • ¥35 MIMO天线稀疏阵列排布问题
  • ¥60 用visual studio编写程序,利用间接平差求解水准网
  • ¥15 Llama如何调用shell或者Python
  • ¥20 谁能帮我挨个解读这个php语言编的代码什么意思?
  • ¥15 win10权限管理,限制普通用户使用删除功能
  • ¥15 minnio内存占用过大,内存没被回收(Windows环境)