@@ -131,16 +131,22 @@ public function parse($data)
131
131
132
132
return ;
133
133
}
134
+
135
+ $ packet = $ this ->buffer ->readBuffer ($ this ->pctSize );
134
136
$ this ->state = self ::STATE_STANDBY ;
135
- //$this->stream->bufferSize = 4;
137
+
138
+ if ($ this ->debug ) {
139
+ $ this ->debug ('Parse packet# ' . $ this ->seq . ' with ' . ($ len = $ packet ->length ()) . ' bytes: ' . wordwrap (bin2hex ($ b = $ packet ->read ($ len )), 2 , ' ' , true )); $ packet ->append ($ b ); // @codeCoverageIgnore
140
+ }
141
+
136
142
if ($ this ->phase === 0 ) {
137
- $ response = $ this -> buffer ->readInt1 ();
143
+ $ response = $ packet ->readInt1 ();
138
144
if ($ response === 0xFF ) {
139
145
// error packet before handshake means we did not exchange capabilities and error does not include SQL state
140
146
$ this ->phase = self ::PHASE_AUTH_ERR ;
141
147
142
- $ code = $ this -> buffer ->readInt2 ();
143
- $ exception = new Exception ($ this -> buffer -> read ($ this -> pctSize - $ len + $ this -> buffer ->length ()), $ code );
148
+ $ code = $ packet ->readInt2 ();
149
+ $ exception = new Exception ($ packet -> read ($ packet ->length ()), $ code );
144
150
$ this ->debug (sprintf ("Error Packet:%d %s \n" , $ code , $ exception ->getMessage ()));
145
151
146
152
// error during init phase also means we're not currently executing any command
@@ -155,32 +161,32 @@ public function parse($data)
155
161
$ this ->debug (sprintf ("Protocal Version: %d " , $ this ->protocalVersion ));
156
162
157
163
$ options = &$ this ->connectOptions ;
158
- $ options ['serverVersion ' ] = $ this -> buffer ->readStringNull ();
159
- $ options ['threadId ' ] = $ this -> buffer ->readInt4 ();
160
- $ this ->scramble = $ this -> buffer ->read (8 ); // 1st part
161
- $ this -> buffer ->skip (1 ); // filler
162
- $ options ['ServerCaps ' ] = $ this -> buffer ->readInt2 (); // 1st part
163
- $ options ['serverLang ' ] = $ this -> buffer ->readInt1 ();
164
- $ options ['serverStatus ' ] = $ this -> buffer ->readInt2 ();
165
- $ options ['ServerCaps ' ] += $ this -> buffer ->readInt2 () << 16 ; // 2nd part
166
- $ this -> buffer ->skip (11 ); // plugin length, 6 + 4 filler
167
- $ this ->scramble .= $ this -> buffer ->read (12 ); // 2nd part
168
- $ this -> buffer ->skip (1 );
164
+ $ options ['serverVersion ' ] = $ packet ->readStringNull ();
165
+ $ options ['threadId ' ] = $ packet ->readInt4 ();
166
+ $ this ->scramble = $ packet ->read (8 ); // 1st part
167
+ $ packet ->skip (1 ); // filler
168
+ $ options ['ServerCaps ' ] = $ packet ->readInt2 (); // 1st part
169
+ $ options ['serverLang ' ] = $ packet ->readInt1 ();
170
+ $ options ['serverStatus ' ] = $ packet ->readInt2 ();
171
+ $ options ['ServerCaps ' ] += $ packet ->readInt2 () << 16 ; // 2nd part
172
+ $ packet ->skip (11 ); // plugin length, 6 + 4 filler
173
+ $ this ->scramble .= $ packet ->read (12 ); // 2nd part
174
+ $ packet ->skip (1 );
169
175
170
176
if ($ this ->connectOptions ['ServerCaps ' ] & Constants::CLIENT_PLUGIN_AUTH ) {
171
- $ this -> buffer ->readStringNull (); // skip authentication plugin name
177
+ $ packet ->readStringNull (); // skip authentication plugin name
172
178
}
173
179
174
180
// init completed, continue with sending AuthenticateCommand
175
181
$ this ->nextRequest (true );
176
182
} else {
177
- $ fieldCount = $ this -> buffer ->readInt1 ();
183
+ $ fieldCount = $ packet ->readInt1 ();
178
184
179
185
if ($ fieldCount === 0xFF ) {
180
186
// error packet
181
- $ code = $ this -> buffer ->readInt2 ();
182
- $ this -> buffer ->skip (6 ); // skip SQL state
183
- $ exception = new Exception ($ this -> buffer -> read ($ this -> pctSize - $ len + $ this -> buffer ->length ()), $ code );
187
+ $ code = $ packet ->readInt2 ();
188
+ $ packet ->skip (6 ); // skip SQL state
189
+ $ exception = new Exception ($ packet -> read ($ packet ->length ()), $ code );
184
190
$ this ->debug (sprintf ("Error Packet:%d %s \n" , $ code , $ exception ->getMessage ()));
185
191
186
192
$ this ->onError ($ exception );
@@ -193,19 +199,19 @@ public function parse($data)
193
199
$ this ->phase = self ::PHASE_HANDSHAKED ;
194
200
}
195
201
196
- $ this ->affectedRows = $ this -> buffer ->readIntLen ();
197
- $ this ->insertId = $ this -> buffer ->readIntLen ();
198
- $ this ->serverStatus = $ this -> buffer ->readInt2 ();
199
- $ this ->warningCount = $ this -> buffer ->readInt2 ();
202
+ $ this ->affectedRows = $ packet ->readIntLen ();
203
+ $ this ->insertId = $ packet ->readIntLen ();
204
+ $ this ->serverStatus = $ packet ->readInt2 ();
205
+ $ this ->warningCount = $ packet ->readInt2 ();
200
206
201
- $ this ->message = $ this -> buffer -> read ($ this -> pctSize - $ len + $ this -> buffer ->length ());
207
+ $ this ->message = $ packet -> read ($ packet ->length ());
202
208
203
209
$ this ->debug (sprintf ("AffectedRows: %d, InsertId: %d, WarningCount:%d " , $ this ->affectedRows , $ this ->insertId , $ this ->warningCount ));
204
210
$ this ->onSuccess ();
205
211
$ this ->nextRequest ();
206
212
} elseif ($ fieldCount === 0xFE ) {
207
213
// EOF Packet
208
- $ this -> buffer ->skip (4 ); // warn, status
214
+ $ packet ->skip (4 ); // warn, status
209
215
if ($ this ->rsState === self ::RS_STATE_ROW ) {
210
216
// finalize this result set (all rows completed)
211
217
$ this ->debug ('Result set done ' );
@@ -217,54 +223,52 @@ public function parse($data)
217
223
$ this ->debug ('Result set next part ' );
218
224
++$ this ->rsState ;
219
225
}
220
- } elseif ($ fieldCount === 0x00 && $ this ->pctSize === 1 ) {
221
- // Empty data packet during result set => row with only empty strings
222
- $ this ->debug ('Result set empty row data ' );
223
-
224
- $ row = [];
225
- foreach ($ this ->resultFields as $ field ) {
226
- $ row [$ field ['name ' ]] = '' ;
227
- }
228
- $ this ->onResultRow ($ row );
229
226
} else {
230
227
// Data packet
231
- $ this -> buffer -> prepend ($ this -> buffer ->buildInt1 ($ fieldCount ));
228
+ $ packet -> prepend ($ packet ->buildInt1 ($ fieldCount ));
232
229
233
230
if ($ this ->rsState === self ::RS_STATE_HEADER ) {
234
- $ this -> debug ( ' Result set header packet' );
235
- $ this ->buffer -> readIntLen (); // extra
231
+ $ columns = $ packet-> readIntLen (); // extra
232
+ $ this ->debug ( ' Result set with ' . $ columns . ' column(s) ' );
236
233
$ this ->rsState = self ::RS_STATE_FIELD ;
237
234
} elseif ($ this ->rsState === self ::RS_STATE_FIELD ) {
238
- $ this ->debug ('Result set field packet ' );
239
235
$ field = [
240
- 'catalog ' => $ this -> buffer ->readStringLen (),
241
- 'db ' => $ this -> buffer ->readStringLen (),
242
- 'table ' => $ this -> buffer ->readStringLen (),
243
- 'org_table ' => $ this -> buffer ->readStringLen (),
244
- 'name ' => $ this -> buffer ->readStringLen (),
245
- 'org_name ' => $ this -> buffer ->readStringLen ()
236
+ 'catalog ' => $ packet ->readStringLen (),
237
+ 'db ' => $ packet ->readStringLen (),
238
+ 'table ' => $ packet ->readStringLen (),
239
+ 'org_table ' => $ packet ->readStringLen (),
240
+ 'name ' => $ packet ->readStringLen (),
241
+ 'org_name ' => $ packet ->readStringLen ()
246
242
];
247
243
248
- $ this ->buffer ->skip (1 ); // 0xC0
249
- $ field ['charset ' ] = $ this ->buffer ->readInt2 ();
250
- $ field ['length ' ] = $ this ->buffer ->readInt4 ();
251
- $ field ['type ' ] = $ this ->buffer ->readInt1 ();
252
- $ field ['flags ' ] = $ this ->buffer ->readInt2 ();
253
- $ field ['decimals ' ] = $ this ->buffer ->readInt1 ();
254
- $ this ->buffer ->skip (2 ); // unused
244
+ $ packet ->skip (1 ); // 0xC0
245
+ $ field ['charset ' ] = $ packet ->readInt2 ();
246
+ $ field ['length ' ] = $ packet ->readInt4 ();
247
+ $ field ['type ' ] = $ packet ->readInt1 ();
248
+ $ field ['flags ' ] = $ packet ->readInt2 ();
249
+ $ field ['decimals ' ] = $ packet ->readInt1 ();
250
+ $ packet ->skip (2 ); // unused
251
+
252
+ if ($ this ->debug ) {
253
+ $ this ->debug ('Result set column: ' . json_encode ($ field , JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION | JSON_INVALID_UTF8_SUBSTITUTE )); // @codeCoverageIgnore
254
+ }
255
255
$ this ->resultFields [] = $ field ;
256
256
} elseif ($ this ->rsState === self ::RS_STATE_ROW ) {
257
- $ this ->debug ('Result set row data ' );
258
257
$ row = [];
259
258
foreach ($ this ->resultFields as $ field ) {
260
- $ row [$ field ['name ' ]] = $ this ->buffer ->readStringLen ();
259
+ $ row [$ field ['name ' ]] = $ packet ->readStringLen ();
260
+ }
261
+
262
+ if ($ this ->debug ) {
263
+ $ this ->debug ('Result set row: ' . json_encode ($ row , JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION | JSON_INVALID_UTF8_SUBSTITUTE )); // @codeCoverageIgnore
261
264
}
262
265
$ this ->onResultRow ($ row );
263
266
}
264
267
}
265
268
}
266
269
267
- $ this ->buffer ->trim ();
270
+ // finished parsing packet, continue with next packet
271
+ assert ($ packet ->length () === 0 );
268
272
goto packet;
269
273
}
270
274
0 commit comments