Regex overflow?
Nu lijkt echter dat wanneer de string langer is dan een x aantal karakters, dat ik een 'error 500 interne server fout' krijg. Met kortere strings is er echter geen probleem
Zowel de preg_match_all als de preg_split geven zo'n fout bij een te lange string.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
<?php
$string = "UPDATE `#_module_webpage` SET `content` = 'Lorem ipsum..' WHERE `id` = '3' LIMIT 1;";
$expr = '/([^\']+)|(\'((\\\\.)|([^\']))+\')/i';
$matches = array();
preg_match_all($expr, $string, $matches);
print_r($matches);
?>
$string = "UPDATE `#_module_webpage` SET `content` = 'Lorem ipsum..' WHERE `id` = '3' LIMIT 1;";
$expr = '/([^\']+)|(\'((\\\\.)|([^\']))+\')/i';
$matches = array();
preg_match_all($expr, $string, $matches);
print_r($matches);
?>
Weet iemand toevallig of dit opgelost kan worden (er kan zoveel geconfigureerd worden ;))
Geven je error logs misschien meer informatie? Apache zal toch wel ergens vermelden wat er mis ging...
Wat doen die hekjes in je tabel namen ? waarom geen mooiere namen
Wat doen die back-ticks in je query ? gewoon wegpleuren
Baarr schreef op 13.04.2007 10:33:
Waarom doe je overigens een regex op een complete query ?
Wat doen die hekjes in je tabel namen ? waarom geen mooiere namen
Wat doen die back-ticks in je query ? gewoon wegpleuren
Wat doen die hekjes in je tabel namen ? waarom geen mooiere namen
Wat doen die back-ticks in je query ? gewoon wegpleuren
Die backticks kan je anders wel gebruiken voor gereserveerde worden in mysql... Kan je die worden toch nog gebruiken:) link
Edit:
Moet ie die worden wel gebruiken anders hebben die backticks inderdaad geen nut
Gewijzigd op 01/01/1970 01:00:00 door Mebus Hackintosh
Ik weet niet precies hoe het zit, maar die error heeft volgens mij niet met de duur van je uitvoer te maken. Je kan wel proberen om je string in stukjes te knippen. (gebruik hiervoor bijvoorbeeld het script dat strings afkort op een aantal tekens, maar wel de woorden in tact laat. Staat in de script lib)
Edit:
Offtopic:
@mebus
Het is voor jezelf veel gemakkelijker om gewoon goede namen te kiezen die niet overeenkomen met gereserveerde woorden. Een simpele query kan daardoor toch verkeerd worden gelezen/ begrepen wanneer je hem terugleest, en als je een keer backticks vergeet werkt het niet, bijv:
Een setup voor een tabel met shows die worden gegeven. Waarbij het ook mogelijk is om de weergave van een show te blokkeren, omdat die bijv nog niet vast staat.
TABLE: Show
id
name
description
show (laat zien of niet)
Snap je wat ik bedoel? Als je nu een show (weergave) in MySQL zou willen doen van deze tabel, dan krijg je een query waarin het woord Show nogal vaak voorkomt, wat voor je eigen overzicht niet handig is.
Kies dan als tabelnaam bijvoorbeeld: Show_Info (heb je geen backticks bij nodig, en je tabelnaam beschrijft ook nog eens beter wat voor informatie erin zit)
En voor de kolom show -> maak daar bijvoorbeeld viewable van. Ook hierbij heb je dan geen backticks nodig, en het beschrijft ook het doel van die kolom beter.
Door op zo'n manier met je database om te gaan hou je je tabellen en query's eigenlijk heel eenvoudig. En door juiste namen te gebruiken kan je ook heel snel de bedoeling van een query begrijpen, zonder dat je daar andere informatie dan de query zelf voor nodig bent.
Verder lijkt het me beter maar weer ontopic verder te gaan. :)
@mebus
Het is voor jezelf veel gemakkelijker om gewoon goede namen te kiezen die niet overeenkomen met gereserveerde woorden. Een simpele query kan daardoor toch verkeerd worden gelezen/ begrepen wanneer je hem terugleest, en als je een keer backticks vergeet werkt het niet, bijv:
Een setup voor een tabel met shows die worden gegeven. Waarbij het ook mogelijk is om de weergave van een show te blokkeren, omdat die bijv nog niet vast staat.
TABLE: Show
id
name
description
show (laat zien of niet)
Snap je wat ik bedoel? Als je nu een show (weergave) in MySQL zou willen doen van deze tabel, dan krijg je een query waarin het woord Show nogal vaak voorkomt, wat voor je eigen overzicht niet handig is.
Kies dan als tabelnaam bijvoorbeeld: Show_Info (heb je geen backticks bij nodig, en je tabelnaam beschrijft ook nog eens beter wat voor informatie erin zit)
En voor de kolom show -> maak daar bijvoorbeeld viewable van. Ook hierbij heb je dan geen backticks nodig, en het beschrijft ook het doel van die kolom beter.
Door op zo'n manier met je database om te gaan hou je je tabellen en query's eigenlijk heel eenvoudig. En door juiste namen te gebruiken kan je ook heel snel de bedoeling van een query begrijpen, zonder dat je daar andere informatie dan de query zelf voor nodig bent.
Verder lijkt het me beter maar weer ontopic verder te gaan. :)
Gewijzigd op 01/01/1970 01:00:00 door Robert Deiman
De queries vorden verwerkt in een CMS systeem.
Dit CMS hanteerd een tabel-naam-prefix die in queries steeds wordt aangeduid met een hekje.
Deze functie vervangt vervolgens de hekjes met de geconfigureerde prefix.
Om te voorkomen dat hekjes in data niet worden vervangen door de ingestelde prefix, wordt in de query de boel gesplits naar waarden tussen single quotes (data), en alle overige waarden (tabelnamen e.d.). Op deze laatste wordt een str_replace losgelaten die alle hekjes vervangt door de ingestelde prefix.
Op mijn server gaat dat goed, maar op een andere server (waar ik het CMS heb geinstalleerd) treden er problemen op als de query te lang is.
Zie de __setPrefix() functie onderin..
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
<?php
class Database
{
var $resource; // Stores the resource identifier of the connection to the SQL server.
var $user; // username
var $pass; // password
var $name; // name of the database
var $host; // host (An IP or 'localhost')
var $prefix; // Table prefix (replace "#" for "[prefix]").
var $charset; // communication charset
// Creates a new database
function Database($user, $pass, $name, $host = "localhost", $prefix = false, $charset = false)
{
// Connect to database server
if($this->resource = mysql_connect($host, $user, $pass))
{
// Select a database on the MySQL Server
if(mysql_select_db($name))
{
// Locked to requested database
$this->user = $user;
$this->pass = "**********"; // $this->pass = $pass;
$this->name = $name;
$this->host = $host;
$this->prefix = $prefix;
$this->charset = $charset;
if($charset)
{
// Set communication characterset
$sQuery = "SET CHARACTER SET '" . $charset . "';";
$this->execute($sQuery, __FILE__, __LINE__);
}
}
else
{
// Error while selecting database
exit("Error while connecting to database\nFile: " . __FILE__ . ", Line: " . __LINE__ . ".");
}
}
else
{
// Error while connection to server
exit("Error while connecting to database.\nFile: " . __FILE__ . ", Line: " . __LINE__ . ".");
}
}
// Function to execute a SQL stetement (eg. DELETE/INSERT/UPDATE).
function execute($sQuery, $sFile = false, $iLine = 0)
{
$sQuery = $this->__setPrefix($sQuery);
if(mysql_query($sQuery, $this->resource))
{
return true;
}
else
{
$this->__reportError($sQuery, $sFile, $iLine);
}
}
// Returns the list of fieldnames within a table.
function getColumns($sTableName, $bSort = true)
{
$aColumns = array();
$sQuery = "SHOW COLUMNS FROM `" . $sTableName . "`;";
$rsResults = $this->getRecords($sQuery, true, __FILE__, __LINE__);
for($i = 1; $i < sizeof($rsResults); $i++)
{
$aColumns[] = $rsResults[$i][$rsResults[0][0]];
}
if($bSort)
{
if(sizeof($aColumns) > 1)
{
usort($aColumns, "strcasecmp");
}
}
return $aColumns;
}
// Returns the last created record-id (only works after an INSERT-statement).
function getId()
{
return mysql_insert_id($this->resource);
}
// Returns upto 1 record after running a SQL-statement.
// No results will return FALSE.
function getRecord($sQuery, $sFile = false, $iLine = 0)
{
$rsResults = $this->getRecords($sQuery, false, $sFile, $iLine);
if(sizeof($rsResults) > 0)
{
return $rsResults[0];
}
return false;
}
// Returns all records after running a SQL-statement.
// The columnnames are stored at index
// No results will return an array with only the columnnames (at index 0).
function getRecords($sQuery, $bAddHeader = false, $sFile = false, $iLine = 0)
{
$sQuery = $this->__setPrefix($sQuery);
$aResults = array();
if($rsResults = mysql_query($sQuery, $this->resource))
{
if($bAddHeader)
{
$aHeader = array();
if(mysql_num_rows($rsResults) > 0)
{
$aResult = mysql_fetch_array($rsResults, MYSQL_ASSOC);
foreach($aResult AS $sKey => $sVal)
{
$aHeader[] = $sKey;
}
$aResults[] = $aHeader;
$aResults[] = $aResult;
}
else
{
while($aField = mysql_fetch_field($rsResults))
{
$aHeader[] = $aField->name;
}
$aResults[] = $aHeader;
}
}
while($aResult = mysql_fetch_array($rsResults, MYSQL_ASSOC))
{
$aResults[] = $aResult;
}
mysql_free_result($rsResults);
}
else
{
$this->__reportError($sQuery, $sFile, $iLine);
}
return $aResults;
}
// Returns the list of tables within the current database.
function getTables($bSort = true)
{
$aTables = array();
$sQuery = "SHOW TABLES FROM `" . $this->name . "`;";
$rsResults = $this->getRecords($sQuery, true, __FILE__, __LINE__);
for($i = 1; $i < sizeof($rsResults); $i++)
{
$aTables[] = $rsResults[$i][$rsResults[0][0]];
}
if($bSort)
{
if(sizeof($aTables) > 1)
{
usort($aTables, "strcasecmp");
}
}
return $aTables;
}
// Returns true if a column exists, false otherwise.
// Note: Columnnames are CASE SENSITIVE in MySQL!!
function isColumn($sTableName, $sFieldName)
{
// Get all fields withing table
$aFields = $this->getColumns($sTableName);
return in_array($sFieldName, $aFields);
}
// Returns true if a field table, false otherwise.
// Note: Tablenames are CASE SENSITIVE in MySQL!!
function isTable($sTableName)
{
if($this->prefix !== false)
{
if(strcasecmp(substr($sTableName, 0, 1), '#') === 0) // Tablename starts with #
{
$sTableName = $this->prefix . substr($sTableName, 1);
}
}
// Get all tables withing database
$aTables = $this->getTables();
return in_array($sTableName, $aTables);
}
// Print SQL output into a HTML based table.
// Note: This function was added to support the testing of SQL queries.
function printSQL($sQuery)
{
// Execute SQL and retrieve records
$rsRecords = $this->getRecords($sQuery, true, __FILE__, __LINE__);
$result = highlight_sql($sQuery, true)
. '<table border="1" cellpadding="5" cellspacing="0">';
// Create header
$result .= '<tr>';
for($col = 0; $col < sizeof($rsRecords[0]); $col++)
{
$result .= '<th align="left" valign="top">' . str_replace("\n", "<br>", htmlentities($rsRecords[0][$col])) . ' </th>';
}
$result .= '</tr>';
// Create records
for($row = 1; $row < sizeof($rsRecords); $row++)
{
$result .= '<tr>';
for($col = 0; $col < sizeof($rsRecords[0]); $col++)
{
$result .= '<td align="left" valign="top">' . str_replace("\n", "<br>", htmlentities($rsRecords[$row][$rsRecords[0][$col]])) . ' </td>';
}
$result .= '</tr>';
}
$result .= '</table>';
// Print output
exit($result);
}
// Replace tablenames with # for the given prefix
function __setPrefix($query)
{
$result = '';
if($this->prefix !== false)
{
$expr = '/(\'((\\\\.)|[^\\\\\\\'])*\')|(\`((\\\\.)|[^\\\\\\\`])*\`)|([a-z0-9_]+)|([\s\n]+)|(.)/i';
preg_match_all($expr, $query, $matches);
for($i = 0; $i < sizeof($matches[0]); $i++)
{
if(strcasecmp($match = $matches[0][$i], "") !== 0)
{
if(strcasecmp(substr($match, 0, 1), "'") === 0)
{
$result .= $match;
}
else
{
$result .= str_replace("#", $this->prefix, $match);
}
}
}
}
return $result;
}
function __reportError($sQuery, $sFile = false, $iLine = 0)
{
$result = '<h1>Error in query:</h1>'
. '<p><b>Query:</b></p>'
. (function_exists('highlight_sql') ? highlight_sql($sQuery, true) : $sQuery)
. '<p><b>Error number:</b><br>' . htmlentities(mysql_errno($this->resource)) . '</p>'
. '<p><b>Error message:</b><br>' . htmlentities(mysql_error($this->resource)) . '</p>';
if($sFile !== false)
{
$result .= '<h1>Query invoked in:</h1>'
. '<p><b>File:</b><br>' . htmlentities($sFile) . '</p>'
. '<p><b>Line:</b><br>' . htmlentities($iLine) . '</p>';
}
exit($result);
}
}
?>
class Database
{
var $resource; // Stores the resource identifier of the connection to the SQL server.
var $user; // username
var $pass; // password
var $name; // name of the database
var $host; // host (An IP or 'localhost')
var $prefix; // Table prefix (replace "#" for "[prefix]").
var $charset; // communication charset
// Creates a new database
function Database($user, $pass, $name, $host = "localhost", $prefix = false, $charset = false)
{
// Connect to database server
if($this->resource = mysql_connect($host, $user, $pass))
{
// Select a database on the MySQL Server
if(mysql_select_db($name))
{
// Locked to requested database
$this->user = $user;
$this->pass = "**********"; // $this->pass = $pass;
$this->name = $name;
$this->host = $host;
$this->prefix = $prefix;
$this->charset = $charset;
if($charset)
{
// Set communication characterset
$sQuery = "SET CHARACTER SET '" . $charset . "';";
$this->execute($sQuery, __FILE__, __LINE__);
}
}
else
{
// Error while selecting database
exit("Error while connecting to database\nFile: " . __FILE__ . ", Line: " . __LINE__ . ".");
}
}
else
{
// Error while connection to server
exit("Error while connecting to database.\nFile: " . __FILE__ . ", Line: " . __LINE__ . ".");
}
}
// Function to execute a SQL stetement (eg. DELETE/INSERT/UPDATE).
function execute($sQuery, $sFile = false, $iLine = 0)
{
$sQuery = $this->__setPrefix($sQuery);
if(mysql_query($sQuery, $this->resource))
{
return true;
}
else
{
$this->__reportError($sQuery, $sFile, $iLine);
}
}
// Returns the list of fieldnames within a table.
function getColumns($sTableName, $bSort = true)
{
$aColumns = array();
$sQuery = "SHOW COLUMNS FROM `" . $sTableName . "`;";
$rsResults = $this->getRecords($sQuery, true, __FILE__, __LINE__);
for($i = 1; $i < sizeof($rsResults); $i++)
{
$aColumns[] = $rsResults[$i][$rsResults[0][0]];
}
if($bSort)
{
if(sizeof($aColumns) > 1)
{
usort($aColumns, "strcasecmp");
}
}
return $aColumns;
}
// Returns the last created record-id (only works after an INSERT-statement).
function getId()
{
return mysql_insert_id($this->resource);
}
// Returns upto 1 record after running a SQL-statement.
// No results will return FALSE.
function getRecord($sQuery, $sFile = false, $iLine = 0)
{
$rsResults = $this->getRecords($sQuery, false, $sFile, $iLine);
if(sizeof($rsResults) > 0)
{
return $rsResults[0];
}
return false;
}
// Returns all records after running a SQL-statement.
// The columnnames are stored at index
// No results will return an array with only the columnnames (at index 0).
function getRecords($sQuery, $bAddHeader = false, $sFile = false, $iLine = 0)
{
$sQuery = $this->__setPrefix($sQuery);
$aResults = array();
if($rsResults = mysql_query($sQuery, $this->resource))
{
if($bAddHeader)
{
$aHeader = array();
if(mysql_num_rows($rsResults) > 0)
{
$aResult = mysql_fetch_array($rsResults, MYSQL_ASSOC);
foreach($aResult AS $sKey => $sVal)
{
$aHeader[] = $sKey;
}
$aResults[] = $aHeader;
$aResults[] = $aResult;
}
else
{
while($aField = mysql_fetch_field($rsResults))
{
$aHeader[] = $aField->name;
}
$aResults[] = $aHeader;
}
}
while($aResult = mysql_fetch_array($rsResults, MYSQL_ASSOC))
{
$aResults[] = $aResult;
}
mysql_free_result($rsResults);
}
else
{
$this->__reportError($sQuery, $sFile, $iLine);
}
return $aResults;
}
// Returns the list of tables within the current database.
function getTables($bSort = true)
{
$aTables = array();
$sQuery = "SHOW TABLES FROM `" . $this->name . "`;";
$rsResults = $this->getRecords($sQuery, true, __FILE__, __LINE__);
for($i = 1; $i < sizeof($rsResults); $i++)
{
$aTables[] = $rsResults[$i][$rsResults[0][0]];
}
if($bSort)
{
if(sizeof($aTables) > 1)
{
usort($aTables, "strcasecmp");
}
}
return $aTables;
}
// Returns true if a column exists, false otherwise.
// Note: Columnnames are CASE SENSITIVE in MySQL!!
function isColumn($sTableName, $sFieldName)
{
// Get all fields withing table
$aFields = $this->getColumns($sTableName);
return in_array($sFieldName, $aFields);
}
// Returns true if a field table, false otherwise.
// Note: Tablenames are CASE SENSITIVE in MySQL!!
function isTable($sTableName)
{
if($this->prefix !== false)
{
if(strcasecmp(substr($sTableName, 0, 1), '#') === 0) // Tablename starts with #
{
$sTableName = $this->prefix . substr($sTableName, 1);
}
}
// Get all tables withing database
$aTables = $this->getTables();
return in_array($sTableName, $aTables);
}
// Print SQL output into a HTML based table.
// Note: This function was added to support the testing of SQL queries.
function printSQL($sQuery)
{
// Execute SQL and retrieve records
$rsRecords = $this->getRecords($sQuery, true, __FILE__, __LINE__);
$result = highlight_sql($sQuery, true)
. '<table border="1" cellpadding="5" cellspacing="0">';
// Create header
$result .= '<tr>';
for($col = 0; $col < sizeof($rsRecords[0]); $col++)
{
$result .= '<th align="left" valign="top">' . str_replace("\n", "<br>", htmlentities($rsRecords[0][$col])) . ' </th>';
}
$result .= '</tr>';
// Create records
for($row = 1; $row < sizeof($rsRecords); $row++)
{
$result .= '<tr>';
for($col = 0; $col < sizeof($rsRecords[0]); $col++)
{
$result .= '<td align="left" valign="top">' . str_replace("\n", "<br>", htmlentities($rsRecords[$row][$rsRecords[0][$col]])) . ' </td>';
}
$result .= '</tr>';
}
$result .= '</table>';
// Print output
exit($result);
}
// Replace tablenames with # for the given prefix
function __setPrefix($query)
{
$result = '';
if($this->prefix !== false)
{
$expr = '/(\'((\\\\.)|[^\\\\\\\'])*\')|(\`((\\\\.)|[^\\\\\\\`])*\`)|([a-z0-9_]+)|([\s\n]+)|(.)/i';
preg_match_all($expr, $query, $matches);
for($i = 0; $i < sizeof($matches[0]); $i++)
{
if(strcasecmp($match = $matches[0][$i], "") !== 0)
{
if(strcasecmp(substr($match, 0, 1), "'") === 0)
{
$result .= $match;
}
else
{
$result .= str_replace("#", $this->prefix, $match);
}
}
}
}
return $result;
}
function __reportError($sQuery, $sFile = false, $iLine = 0)
{
$result = '<h1>Error in query:</h1>'
. '<p><b>Query:</b></p>'
. (function_exists('highlight_sql') ? highlight_sql($sQuery, true) : $sQuery)
. '<p><b>Error number:</b><br>' . htmlentities(mysql_errno($this->resource)) . '</p>'
. '<p><b>Error message:</b><br>' . htmlentities(mysql_error($this->resource)) . '</p>';
if($sFile !== false)
{
$result .= '<h1>Query invoked in:</h1>'
. '<p><b>File:</b><br>' . htmlentities($sFile) . '</p>'
. '<p><b>Line:</b><br>' . htmlentities($iLine) . '</p>';
}
exit($result);
}
}
?>
Gewijzigd op 01/01/1970 01:00:00 door Martijn Wieringa
Maar ik snap wat je bedoelt:)
Over backticks:
Backticks zijn in mijn ogen een standaard onderdeel van de SQL syntax..
Net als dat de openingtag van PHP officieel "< ? php" is, en niet "< ?". Toch werken ze allebei ;)
Door backticks voor kolomnamen expliciet te gebruiken worden (in mijn ogen) queries leesbaarder. 't is een questie van smaak, gewoonte en (mogelijk) gemakzucht dan wel het een of het ander te gebruiken..
Tevens worden door gebruik van backticks spaties, speciale tekens en gereserveerde 'keywords' toegankelijk als/in tabelnamen. Niet dat ik hierbij een discussie aan wil gaan of het gebruik van spaties o.i.d. aan te raden is in een tabelnaam.. maar de 'technische beperking' is in ieder geval geen excuus meer..
</offtopic>
Gewijzigd op 01/01/1970 01:00:00 door Martijn Wieringa
Wat kunnen die regex toch efficient zijn ;)
Vergelijk
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
<?php
function __splitQuery($sQuery)
{
$expr = '/(\'((\\\\.)|[^\\\\\\\'])*\')|(\`((\\\\.)|[^\\\\\\\`])*\`)|([a-z0-9_]+)|([\s\n]+)|(.)/i';
preg_match_all($expr, $sQuery, $matches);
return $matches[0];
}
?>
function __splitQuery($sQuery)
{
$expr = '/(\'((\\\\.)|[^\\\\\\\'])*\')|(\`((\\\\.)|[^\\\\\\\`])*\`)|([a-z0-9_]+)|([\s\n]+)|(.)/i';
preg_match_all($expr, $sQuery, $matches);
return $matches[0];
}
?>
maar eens met de code:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<?php
function __splitQuery($sQuery)
{
$aResult = array();
$bEscaped = false;
$bQuoted = false;
$bBackticked = false;
$sBuffer = '';
$iLength = strlen($sQuery);
for($i = 0; $i < $iLength; $i++)
{
$char = $sQuery[$i];
if((strcmp($char, "'") === 0) && ($bEscaped === false) && ($bBackticked === false)) // Quotes
{
if($bQuoted)
{
$sBuffer .= $char; // Add closing quote to buffer
$aResult[] = $sBuffer; // Add buffer to result
$sBuffer = ''; // Clear buffer
$bQuoted = false; // Set quoted flag
}
else
{
$aResult[] = $sBuffer; // Add buffer to result
$sBuffer = ''; // Clear buffer
$sBuffer .= $char; // Add opening quote to buffer
$bQuoted = true; // Set quoted flag
}
}
elseif((strcmp($char, "`") === 0) && ($bEscaped === false) && ($bQuoted === false)) // Backticks
{
if($bBackticked)
{
$sBuffer .= $char; // Add closing backtick to buffer
$aResult[] = $sBuffer; // Add buffer to result
$sBuffer = ''; // Clear buffer
$bBackticked = false; // Set backtick flag
}
else
{
$aResult[] = $sBuffer; // Add buffer to result
$sBuffer = ''; // Clear buffer
$sBuffer .= $char; // Add opening backtick to buffer
$bBackticked = true; // Set backtick flag
}
}
else
{
// Backslashes
if((strcmp($char, "\\") === 0) && ($bQuoted || $bBackticked))
{
$bEscaped = ($bEscaped === false);
}
else
{
$bEscaped = false;
}
$sBuffer .= $char;
}
}
if(strlen($sBuffer) > 0)
{
$aResult[] = $sBuffer;
}
return $aResult;
}
?>
function __splitQuery($sQuery)
{
$aResult = array();
$bEscaped = false;
$bQuoted = false;
$bBackticked = false;
$sBuffer = '';
$iLength = strlen($sQuery);
for($i = 0; $i < $iLength; $i++)
{
$char = $sQuery[$i];
if((strcmp($char, "'") === 0) && ($bEscaped === false) && ($bBackticked === false)) // Quotes
{
if($bQuoted)
{
$sBuffer .= $char; // Add closing quote to buffer
$aResult[] = $sBuffer; // Add buffer to result
$sBuffer = ''; // Clear buffer
$bQuoted = false; // Set quoted flag
}
else
{
$aResult[] = $sBuffer; // Add buffer to result
$sBuffer = ''; // Clear buffer
$sBuffer .= $char; // Add opening quote to buffer
$bQuoted = true; // Set quoted flag
}
}
elseif((strcmp($char, "`") === 0) && ($bEscaped === false) && ($bQuoted === false)) // Backticks
{
if($bBackticked)
{
$sBuffer .= $char; // Add closing backtick to buffer
$aResult[] = $sBuffer; // Add buffer to result
$sBuffer = ''; // Clear buffer
$bBackticked = false; // Set backtick flag
}
else
{
$aResult[] = $sBuffer; // Add buffer to result
$sBuffer = ''; // Clear buffer
$sBuffer .= $char; // Add opening backtick to buffer
$bBackticked = true; // Set backtick flag
}
}
else
{
// Backslashes
if((strcmp($char, "\\") === 0) && ($bQuoted || $bBackticked))
{
$bEscaped = ($bEscaped === false);
}
else
{
$bEscaped = false;
}
$sBuffer .= $char;
}
}
if(strlen($sBuffer) > 0)
{
$aResult[] = $sBuffer;
}
return $aResult;
}
?>
Gewijzigd op 01/01/1970 01:00:00 door Martijn Wieringa
Ja, dat scheelt nogal een slok op een borrel. Maar misschien is de code van jouw eigen functie wel veel korter dan de source code voor preg_match_all. (vermoed van wel)