Passed
Push — master ( fa7991...10a1b7 )
by 世昌
02:08
created

MethodTarget::getObjectInstance()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 6
nc 3
nop 0
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
namespace nebula\runnable\target;
3
4
use ReflectionClass;
5
use nebula\runnable\target\FileTarget;
6
7
/**
8
 * 可执行命令:类方法
9
 *
10
 */
11
class MethodTarget extends FileTarget
12
{
13
    /**
14
     * 构建方法参数
15
     *
16
     * @var array
17
     */
18
    private $constructParameter;
19
20
    /**
21
     * 类对象
22
     *
23
     * @var object|string
24
     */
25
    private $object;
26
27
    /**
28
     * 类方法
29
     *
30
     * @var string
31
     */
32
    private $method;
33
34
    /**
35
     * 构造对象
36
     *
37
     * @param string|object $object
38
     * @param array|null $constructParameter
39
     * @param string $method
40
     * @param array $parameter
41
     */
42
    public function __construct($object, ?array $constructParameter=null, string $method, array $parameter = [])
43
    {
44
        $this->object = $object;
45
        $this->constructParameter = $constructParameter;
46
        $this->method = $method;
47
        $this->parameter = $parameter;
0 ignored issues
show
Bug Best Practice introduced by
The property parameter does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
48
        $static = $this->isStatic() ? '->' : '::';
49
        $name = \is_object($object)? \get_class($object) : $object;
50
        $this->name = $name.$static.$method;
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
51
    }
52
53
    public function getObjectInstance():object
54
    {
55
        if (\is_object($this->object)) {
56
            return $this->object;
57
        }
58
        if (!is_null($this->requireFile) && !\class_exists($this->object)) {
59
            require_once $this->requireFile;
60
        }
61
        $classRef= new ReflectionClass($this->object);
62
        return $classRef->newInstanceArgs($this->constructParameter);
63
    }
64
65
    public function getRunnableTarget()
66
    {
67
        if (is_null($this->runableTarget)) {
68
            if ($this->isStatic() || \is_object($this->object)) {
69
                $this->runableTarget = [$this->object, $this->method];
0 ignored issues
show
Bug Best Practice introduced by
The property runableTarget does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
70
            }
71
            $this->runableTarget =  [$this->getObjectInstance(), $this->method];
72
        }
73
        return $this->runableTarget;
74
    }
75
76
    /**
77
     * 判断是否为静态方法
78
     *
79
     * @return boolean
80
     */
81
    public function isStatic():bool
82
    {
83
        return !\is_object($this->object) && \is_null($this->constructParameter);
84
    }
85
86
    /**
87
     * Set 需要的文件
88
     *
89
     * @param  string|null  $requireFile  需要的文件
90
     *
91
     * @return  self
92
     */
93
    public function setRequireFile($requireFile)
94
    {
95
        if (is_null($this->requireFile)) {
96
            $this->requireFile = $requireFile;
97
            $this->name = $this->name.'@'.$requireFile;
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
98
        }
99
        return $this;
100
    }
101
102
    /**
103
     * 是否可执行
104
     *
105
     * @return boolean
106
     */
107
    public function isVaild():bool
108
    {
109
        return \class_exists($this->object) || parent::isVaild();
0 ignored issues
show
Bug introduced by
It seems like $this->object can also be of type object; however, parameter $class_name of class_exists() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

109
        return \class_exists(/** @scrutinizer ignore-type */ $this->object) || parent::isVaild();
Loading history...
110
    }
111
112
    /**
113
     * 执行代码
114
     *
115
     * @param array $args
116
     * @return mixed
117
     */
118
    public function invoke(array $args)
119
    {
120
        $runnable = $this->getRunnableTarget();
121
        $method = new \ReflectionMethod($runnable[0], $runnable[1]);
122
        if (!$method->isPublic()) {
123
            $method->setAccessible(true);
124
        }
125
        if (count($parameter) == 0) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $parameter seems to be never defined.
Loading history...
126
            $parameter = $this->getParameter();
127
        }
128
        if (is_object($runnable[0])) {
129
            return $method->invokeArgs($runnable[0], $parameter);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $parameter does not seem to be defined for all execution paths leading up to this point.
Loading history...
130
        } else {
131
            return $method->invokeArgs(null, $parameter);
132
        }
133
    }
134
}
135