@@ -90,37 +90,65 @@ public function notify($method, array $arguments = null): self
90
90
}
91
91
92
92
/**
93
- * Encodes the requests as a valid JSON-RPC 2.0 string
93
+ * Encodes the request(s) as a valid JSON-RPC 2.0 string
94
94
*
95
- * This also resets the Client, so you can perform more queries using
96
- * the same Client object .
95
+ * This also resets the Client, so you can use the same Client object
96
+ * to perform more queries .
97
97
*
98
- * @return null| string
98
+ * @return string|null
99
99
* Returns a valid JSON-RPC 2.0 message string
100
100
* Returns null if there is nothing to encode
101
101
*/
102
102
public function encode ()
103
103
{
104
- $ count = count ( $ this ->requests );
104
+ $ input = $ this ->preEncode ( );
105
105
106
- if ($ count === 0 ) {
106
+ if ($ input === null ) {
107
107
return null ;
108
108
}
109
109
110
- if ($ count === 1 ) {
111
- $ input = array_shift ($ this ->requests );
110
+ return json_encode ($ input );
111
+ }
112
+
113
+ /**
114
+ * Encodes the request(s) as a JSON-RPC 2.0 array, but does NOT perform
115
+ * the final "json_encode" step which is necessary to turn the array
116
+ * into a valid JSON-RPC 2.0 string. This gives you the opportunity
117
+ * to inspect or modify the raw data, or to alter the encoding algorithm.
118
+ *
119
+ * When you're finished manipulating the request, you are responsible for
120
+ * JSON-encoding the value to construct the final JSON-RPC 2.0 string.
121
+ * @see self::encode()
122
+ *
123
+ * This also resets the Client, so you can use the same Client object
124
+ * to perform more queries.
125
+ *
126
+ * @return array|null
127
+ * Returns a JSON-RPC 2.0 request array
128
+ * Returns null if no requests have been queued
129
+ */
130
+ public function preEncode ()
131
+ {
132
+ $ n = count ($ this ->requests );
133
+
134
+ if ($ n === 0 ) {
135
+ return null ;
136
+ }
137
+
138
+ if ($ n === 1 ) {
139
+ $ input = $ this ->requests [0 ];
112
140
} else {
113
141
$ input = $ this ->requests ;
114
142
}
115
143
116
144
$ this ->reset ();
117
145
118
- return json_encode ( $ input) ;
146
+ return $ input ;
119
147
}
120
148
121
149
/**
122
150
* Translates a JSON-RPC 2.0 server reply into an array of "Response"
123
- * objects
151
+ * objects.
124
152
*
125
153
* @param string $json
126
154
* String reply from a JSON-RPC 2.0 server
@@ -133,21 +161,48 @@ public function encode()
133
161
*/
134
162
public function decode (string $ json )
135
163
{
136
- set_error_handler ( __CLASS__ . ' ::onError ' );
164
+ $ input = json_decode ( $ json , true );
137
165
138
- try {
139
- $ input = json_decode ( $ json , true );
140
- } finally {
141
- restore_error_handler ();
142
- }
166
+ $ errorCode = json_last_error ();
167
+
168
+ if ( $ errorCode !== 0 ) {
169
+ $ errorMessage = json_last_error_msg ();
170
+ $ jsonException = new ErrorException ( $ errorMessage , $ errorCode );
143
171
144
- if (($ input === null ) && (strtolower (trim ($ json )) !== 'null ' )) {
145
172
$ valueText = self ::getValueText ($ json );
146
- throw new ErrorException ("Invalid JSON: {$ valueText }" );
173
+ throw new ErrorException ("Invalid JSON: {$ valueText }" , 0 , E_ERROR , __FILE__ , __LINE__ , $ jsonException );
147
174
}
148
175
176
+ return $ this ->postDecode ($ input );
177
+ }
178
+
179
+ /**
180
+ * Translates a JSON-decoded server reply into an array of "Response"
181
+ * objects.
182
+ *
183
+ * This gives you the opportunity to use your own modified "json_decode"
184
+ * algorithm, or to inspect or modify the server response before it is
185
+ * processed under the JSON-RPC 2.0 specifications. This can be handy
186
+ * if you're tweaking or extending the JSON-RPC 2.0 format.
187
+ *
188
+ * Before calling this method, you are responsible for JSON-decoding
189
+ * the server reply string. You should have that decoded array value
190
+ * to use as the input here.
191
+ * @see self::decode()
192
+ *
193
+ * @param mixed $input
194
+ * An array containing the JSON-decoded server reply
195
+ *
196
+ * @return Response[]
197
+ * Returns a zero-indexed array of "Response" objects
198
+ *
199
+ * @throws ErrorException
200
+ * Throws an "ErrorException" if the reply was not well-formed
201
+ */
202
+ public function postDecode ($ input )
203
+ {
149
204
if (!$ this ->getResponses ($ input , $ responses )) {
150
- $ valueText = self ::getValueText ($ json );
205
+ $ valueText = self ::getValueText ($ input );
151
206
throw new ErrorException ("Invalid JSON-RPC 2.0 response: {$ valueText }" );
152
207
}
153
208
@@ -308,12 +363,4 @@ private function getBatchResponses($input, &$responses)
308
363
309
364
return true ;
310
365
}
311
-
312
- public static function onError ($ level , $ message , $ file , $ line )
313
- {
314
- $ message = trim ($ message );
315
- $ code = 0 ;
316
-
317
- throw new ErrorException ($ message , $ code , $ level , $ file , $ line );
318
- }
319
366
}
0 commit comments