|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* Spiral Framework. |
|
4
|
|
|
* |
|
5
|
|
|
* @license MIT |
|
6
|
|
|
* @author Anton Titov (Wolfy-J) |
|
7
|
|
|
*/ |
|
8
|
|
|
namespace Spiral\Database\Entities\Query; |
|
9
|
|
|
|
|
10
|
|
|
use Spiral\Database\Exceptions\ResultException; |
|
11
|
|
|
|
|
12
|
|
|
/** |
|
13
|
|
|
* Represents simple array. |
|
14
|
|
|
*/ |
|
15
|
|
|
class ArrayResult extends \ArrayIterator |
|
16
|
|
|
{ |
|
17
|
|
|
/** |
|
18
|
|
|
* @var array |
|
19
|
|
|
*/ |
|
20
|
|
|
private $columns = []; |
|
21
|
|
|
|
|
22
|
|
|
/** |
|
23
|
|
|
* Column = variable binding. |
|
24
|
|
|
* |
|
25
|
|
|
* @var array |
|
26
|
|
|
*/ |
|
27
|
|
|
private $bindings = []; |
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* @param array $rowsets |
|
31
|
|
|
*/ |
|
32
|
|
|
public function __construct(array $rowsets) |
|
33
|
|
|
{ |
|
34
|
|
|
parent::__construct($rowsets); |
|
35
|
|
|
|
|
36
|
|
|
if (count($rowsets) > 1) { |
|
37
|
|
|
/* |
|
38
|
|
|
* { |
|
39
|
|
|
* columnA: indexA, |
|
40
|
|
|
* columnB: indexB |
|
41
|
|
|
* } |
|
42
|
|
|
*/ |
|
43
|
|
|
$this->columns = array_flip(array_keys(current($rowsets))); |
|
44
|
|
|
} |
|
45
|
|
|
} |
|
46
|
|
|
|
|
47
|
|
|
/** |
|
48
|
|
|
* {@inheritdoc} |
|
49
|
|
|
*/ |
|
50
|
|
|
public function countColumns(): int |
|
51
|
|
|
{ |
|
52
|
|
|
return count($this->columns); |
|
53
|
|
|
} |
|
54
|
|
|
|
|
55
|
|
|
/** |
|
56
|
|
|
* {@inheritdoc} |
|
57
|
|
|
*/ |
|
58
|
|
|
public function fetch() |
|
59
|
|
|
{ |
|
60
|
|
|
$this->next(); |
|
61
|
|
|
$values = $this->current(); |
|
62
|
|
|
|
|
63
|
|
|
//Filling bindings |
|
64
|
|
|
foreach ($this->bindings as $name => &$variable) { |
|
65
|
|
|
$variable = $values[$name]; |
|
66
|
|
|
} |
|
67
|
|
|
|
|
68
|
|
|
return $values; |
|
69
|
|
|
} |
|
70
|
|
|
|
|
71
|
|
|
/** |
|
72
|
|
|
* Bind a column value to a PHP variable. |
|
73
|
|
|
* |
|
74
|
|
|
* @param int|string $columnID Column number (0 - first column) |
|
75
|
|
|
* @param mixed $variable |
|
76
|
|
|
* |
|
77
|
|
|
* @return self|$this |
|
78
|
|
|
* |
|
79
|
|
|
* @throws ResultException |
|
80
|
|
|
*/ |
|
81
|
|
|
public function bind($columnID, &$variable): ArrayResult |
|
82
|
|
|
{ |
|
83
|
|
|
if ($this->count() == 0) { |
|
84
|
|
|
return $this; |
|
85
|
|
|
} |
|
86
|
|
|
|
|
87
|
|
|
if (is_numeric($columnID)) { |
|
88
|
|
|
//Getting column number |
|
89
|
|
|
foreach ($this->columns as $name => $index) { |
|
90
|
|
|
if ($index == $columnID - 1) { |
|
91
|
|
|
$this->bindings[$name] = &$variable; |
|
92
|
|
|
|
|
93
|
|
|
return $this; |
|
94
|
|
|
} |
|
95
|
|
|
} |
|
96
|
|
|
|
|
97
|
|
|
throw new ResultException("No such column #{$columnID}"); |
|
|
|
|
|
|
98
|
|
|
} else { |
|
99
|
|
|
if (!isset($this->columns[$columnID])) { |
|
100
|
|
|
throw new ResultException("No such column '{$columnID}'"); |
|
|
|
|
|
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
$this->bindings[$columnID] = &$variable; |
|
104
|
|
|
} |
|
105
|
|
|
|
|
106
|
|
|
return $this; |
|
107
|
|
|
} |
|
108
|
|
|
|
|
109
|
|
|
/** |
|
110
|
|
|
* Returns a single column value from the next row of a result set. |
|
111
|
|
|
* |
|
112
|
|
|
* @param int $columnID Column number (0 - first column) |
|
113
|
|
|
* |
|
114
|
|
|
* @return mixed |
|
115
|
|
|
*/ |
|
116
|
|
|
public function fetchColumn($columnID = 0) |
|
117
|
|
|
{ |
|
118
|
|
|
$values = $this->fetch(); |
|
119
|
|
|
|
|
120
|
|
|
if ($values === false) { |
|
121
|
|
|
return null; |
|
122
|
|
|
} |
|
123
|
|
|
|
|
124
|
|
|
if (is_numeric($columnID)) { |
|
125
|
|
|
if ($this->countColumns() > $columnID) { |
|
126
|
|
|
throw new ResultException("No such column #{$columnID}"); |
|
|
|
|
|
|
127
|
|
|
} |
|
128
|
|
|
|
|
129
|
|
|
return array_values($values)[$columnID]; |
|
130
|
|
|
} |
|
131
|
|
|
|
|
132
|
|
|
if (!isset($this->columns[$columnID])) { |
|
133
|
|
|
throw new ResultException("No such column '{$columnID}'"); |
|
|
|
|
|
|
134
|
|
|
} |
|
135
|
|
|
|
|
136
|
|
|
return $values[$columnID]; |
|
137
|
|
|
} |
|
138
|
|
|
|
|
139
|
|
|
/** |
|
140
|
|
|
* {@inheritdoc} |
|
141
|
|
|
*/ |
|
142
|
|
|
public function fetchAll(): array |
|
143
|
|
|
{ |
|
144
|
|
|
$result = []; |
|
145
|
|
|
while (($values = $this->fetch()) !== false) { |
|
146
|
|
|
//This loop is required to make sure that bindings are set |
|
147
|
|
|
$result[] = $values; |
|
148
|
|
|
} |
|
149
|
|
|
|
|
150
|
|
|
return $result; |
|
151
|
|
|
} |
|
152
|
|
|
|
|
153
|
|
|
/** |
|
154
|
|
|
* {@inheritdoc} |
|
155
|
|
|
*/ |
|
156
|
|
|
public function close() |
|
157
|
|
|
{ |
|
158
|
|
|
//Nothing to do |
|
159
|
|
|
} |
|
160
|
|
|
} |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignorePhpDoc annotation to the duplicate definition and it will be ignored.