These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
|||||||||||
2 | ||||||||||||
3 | # |
|||||||||||
4 | # |
|||||||||||
5 | # Parsedown |
|||||||||||
6 | # http://parsedown.org |
|||||||||||
7 | # |
|||||||||||
8 | # (c) Emanuil Rusev |
|||||||||||
9 | # http://erusev.com |
|||||||||||
10 | # |
|||||||||||
11 | # For the full license information, please view the LICENSE file that was |
|||||||||||
12 | # distributed with this source code. |
|||||||||||
13 | # |
|||||||||||
14 | # |
|||||||||||
15 | ||||||||||||
16 | /** |
|||||||||||
17 | * Class Parsedown |
|||||||||||
18 | */ |
|||||||||||
19 | class Parsedown |
|||||||||||
20 | { |
|||||||||||
21 | # |
|||||||||||
22 | # Multiton (http://en.wikipedia.org/wiki/Multiton_pattern) |
|||||||||||
23 | # |
|||||||||||
24 | ||||||||||||
25 | /** |
|||||||||||
26 | * @param string $name |
|||||||||||
27 | * @return mixed|Parsedown |
|||||||||||
28 | */ |
|||||||||||
29 | public static function instance($name = 'default') |
|||||||||||
30 | { |
|||||||||||
31 | if (isset(self::$instances[$name])) { |
|||||||||||
32 | return self::$instances[$name]; |
|||||||||||
33 | } |
|||||||||||
34 | ||||||||||||
35 | $instance = new Parsedown(); |
|||||||||||
36 | ||||||||||||
37 | self::$instances[$name] = $instance; |
|||||||||||
38 | ||||||||||||
39 | return $instance; |
|||||||||||
40 | } |
|||||||||||
41 | ||||||||||||
42 | private static $instances = array(); |
|||||||||||
43 | ||||||||||||
44 | # |
|||||||||||
45 | # Setters |
|||||||||||
46 | # |
|||||||||||
47 | ||||||||||||
48 | private $break_marker = " \n"; |
|||||||||||
49 | ||||||||||||
50 | /** |
|||||||||||
51 | * @param $breaks_enabled |
|||||||||||
52 | * @return $this |
|||||||||||
53 | */ |
|||||||||||
54 | public function set_breaks_enabled($breaks_enabled) |
|||||||||||
55 | { |
|||||||||||
56 | $this->break_marker = $breaks_enabled ? "\n" : " \n"; |
|||||||||||
57 | ||||||||||||
58 | return $this; |
|||||||||||
59 | } |
|||||||||||
60 | ||||||||||||
61 | # |
|||||||||||
62 | # Fields |
|||||||||||
63 | # |
|||||||||||
64 | ||||||||||||
65 | private $reference_map = array(); |
|||||||||||
66 | private $escape_sequence_map = array(); |
|||||||||||
67 | ||||||||||||
68 | # |
|||||||||||
69 | # Public Methods |
|||||||||||
70 | # |
|||||||||||
71 | ||||||||||||
72 | /** |
|||||||||||
73 | * @param $text |
|||||||||||
74 | * @return mixed|string |
|||||||||||
75 | */ |
|||||||||||
76 | public function parse($text) |
|||||||||||
77 | { |
|||||||||||
78 | # removes \r characters |
|||||||||||
79 | $text = str_replace("\r\n", "\n", $text); |
|||||||||||
80 | $text = str_replace("\r", "\n", $text); |
|||||||||||
81 | ||||||||||||
82 | # replaces tabs with spaces |
|||||||||||
83 | $text = str_replace("\t", ' ', $text); |
|||||||||||
84 | ||||||||||||
85 | # encodes escape sequences |
|||||||||||
86 | ||||||||||||
87 | if (false !== strpos($text, '\\')) { |
|||||||||||
88 | $escape_sequences = array('\\\\', '\`', '\*', '\_', '\{', '\}', '\[', '\]', '\(', '\)', '\>', '\#', '\+', '\-', '\.', '\!'); |
|||||||||||
89 | ||||||||||||
90 | foreach ($escape_sequences as $index => $escape_sequence) { |
|||||||||||
91 | if (false !== strpos($text, $escape_sequence)) { |
|||||||||||
92 | $code = "\x1A" . '\\' . $index . ';'; |
|||||||||||
93 | ||||||||||||
94 | $text = str_replace($escape_sequence, $code, $text); |
|||||||||||
95 | ||||||||||||
96 | $this->escape_sequence_map[$code] = $escape_sequence; |
|||||||||||
97 | } |
|||||||||||
98 | } |
|||||||||||
99 | } |
|||||||||||
100 | ||||||||||||
101 | # ~ |
|||||||||||
102 | ||||||||||||
103 | $text = trim($text, "\n"); |
|||||||||||
104 | ||||||||||||
105 | $lines = explode("\n", $text); |
|||||||||||
106 | ||||||||||||
107 | $text = $this->parse_block_elements($lines); |
|||||||||||
108 | ||||||||||||
109 | # decodes escape sequences |
|||||||||||
110 | ||||||||||||
111 | foreach ($this->escape_sequence_map as $code => $escape_sequence) { |
|||||||||||
112 | $text = str_replace($code, $escape_sequence[1], $text); |
|||||||||||
113 | } |
|||||||||||
114 | ||||||||||||
115 | # ~ |
|||||||||||
116 | ||||||||||||
117 | $text = rtrim($text, "\n"); |
|||||||||||
118 | ||||||||||||
119 | return $text; |
|||||||||||
120 | } |
|||||||||||
121 | ||||||||||||
122 | # |
|||||||||||
123 | # Private Methods |
|||||||||||
124 | # |
|||||||||||
125 | ||||||||||||
126 | /** |
|||||||||||
127 | * @param array $lines |
|||||||||||
128 | * @param string $context |
|||||||||||
129 | * @return string |
|||||||||||
130 | */ |
|||||||||||
131 | private function parse_block_elements(array $lines, $context = '') |
|||||||||||
132 | { |
|||||||||||
133 | $elements = array(); |
|||||||||||
134 | ||||||||||||
135 | $element = array( |
|||||||||||
136 | 'type' => '' |
|||||||||||
137 | ); |
|||||||||||
138 | ||||||||||||
139 | foreach ($lines as $line) { |
|||||||||||
140 | # fenced elements |
|||||||||||
141 | ||||||||||||
142 | switch ($element['type']) { |
|||||||||||
143 | case 'fenced block': |
|||||||||||
144 | ||||||||||||
145 | if (!isset($element['closed'])) { |
|||||||||||
146 | if (preg_match('/^[ ]*' . $element['fence'][0] . '{3,}[ ]*$/', $line)) { |
|||||||||||
147 | $element['closed'] = true; |
|||||||||||
148 | } else { |
|||||||||||
149 | '' !== $element['text'] and $element['text'] .= "\n"; |
|||||||||||
0 ignored issues
–
show
|
||||||||||||
150 | ||||||||||||
151 | $element['text'] .= $line; |
|||||||||||
152 | } |
|||||||||||
153 | ||||||||||||
154 | continue 2; |
|||||||||||
155 | } |
|||||||||||
156 | ||||||||||||
157 | break; |
|||||||||||
158 | ||||||||||||
159 | case 'block-level markup': |
|||||||||||
160 | ||||||||||||
161 | if (!isset($element['closed'])) { |
|||||||||||
162 | if (false !== strpos($line, $element['start'])) { # opening tag |
|||||||||||
163 | $element['depth']++; |
|||||||||||
164 | } |
|||||||||||
165 | ||||||||||||
166 | if (false !== strpos($line, $element['end'])) { # closing tag |
|||||||||||
167 | $element['depth'] > 0 ? $element['depth']-- : $element['closed'] = true; |
|||||||||||
168 | } |
|||||||||||
169 | ||||||||||||
170 | $element['text'] .= "\n" . $line; |
|||||||||||
171 | ||||||||||||
172 | continue 2; |
|||||||||||
173 | } |
|||||||||||
174 | ||||||||||||
175 | break; |
|||||||||||
176 | } |
|||||||||||
177 | ||||||||||||
178 | # * |
|||||||||||
179 | ||||||||||||
180 | $deindented_line = ltrim($line); |
|||||||||||
181 | ||||||||||||
182 | if ('' === $deindented_line) { |
|||||||||||
183 | $element['interrupted'] = true; |
|||||||||||
184 | ||||||||||||
185 | continue; |
|||||||||||
186 | } |
|||||||||||
187 | ||||||||||||
188 | # composite elements |
|||||||||||
189 | ||||||||||||
190 | switch ($element['type']) { |
|||||||||||
191 | case 'blockquote': |
|||||||||||
192 | ||||||||||||
193 | if (!isset($element['interrupted'])) { |
|||||||||||
194 | $line = preg_replace('/^[ ]*>[ ]?/', '', $line); |
|||||||||||
195 | ||||||||||||
196 | $element['lines'] [] = $line; |
|||||||||||
197 | ||||||||||||
198 | continue 2; |
|||||||||||
199 | } |
|||||||||||
200 | ||||||||||||
201 | break; |
|||||||||||
202 | ||||||||||||
203 | case 'li': |
|||||||||||
204 | ||||||||||||
205 | if (preg_match('/^([ ]{0,3})(\d+[.]|[*+-])[ ](.*)/', $line, $matches)) { |
|||||||||||
206 | if ($element['indentation'] !== $matches[1]) { |
|||||||||||
207 | $element['lines'] [] = $line; |
|||||||||||
208 | } else { |
|||||||||||
209 | unset($element['last']); |
|||||||||||
210 | ||||||||||||
211 | $elements [] = $element; |
|||||||||||
212 | ||||||||||||
213 | $element = array( |
|||||||||||
214 | 'type' => 'li', |
|||||||||||
215 | 'indentation' => $matches[1], |
|||||||||||
216 | 'last' => true, |
|||||||||||
217 | 'lines' => array( |
|||||||||||
218 | preg_replace('/^[ ]{0,4}/', '', $matches[3]) |
|||||||||||
219 | ) |
|||||||||||
220 | ); |
|||||||||||
221 | } |
|||||||||||
222 | ||||||||||||
223 | continue 2; |
|||||||||||
224 | } |
|||||||||||
225 | ||||||||||||
226 | if (isset($element['interrupted'])) { |
|||||||||||
227 | if (' ' === $line[0]) { |
|||||||||||
228 | $element['lines'] [] = ''; |
|||||||||||
229 | ||||||||||||
230 | $line = preg_replace('/^[ ]{0,4}/', '', $line); |
|||||||||||
231 | ||||||||||||
232 | $element['lines'] [] = $line; |
|||||||||||
233 | ||||||||||||
234 | unset($element['interrupted']); |
|||||||||||
235 | ||||||||||||
236 | continue 2; |
|||||||||||
237 | } |
|||||||||||
238 | } else { |
|||||||||||
239 | $line = preg_replace('/^[ ]{0,4}/', '', $line); |
|||||||||||
240 | ||||||||||||
241 | $element['lines'] [] = $line; |
|||||||||||
242 | ||||||||||||
243 | continue 2; |
|||||||||||
244 | } |
|||||||||||
245 | ||||||||||||
246 | break; |
|||||||||||
247 | } |
|||||||||||
248 | ||||||||||||
249 | # indentation sensitive types |
|||||||||||
250 | ||||||||||||
251 | switch ($line[0]) { |
|||||||||||
252 | case ' ': |
|||||||||||
253 | ||||||||||||
254 | # code block |
|||||||||||
255 | ||||||||||||
256 | if (isset($line[3]) and ' ' === $line[3] and ' ' === $line[2] and ' ' === $line[1]) { |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
and instead of && is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
257 | $code_line = substr($line, 4); |
|||||||||||
258 | ||||||||||||
259 | if ('code block' === $element['type']) { |
|||||||||||
260 | if (isset($element['interrupted'])) { |
|||||||||||
261 | $element['text'] .= "\n"; |
|||||||||||
262 | ||||||||||||
263 | unset($element['interrupted']); |
|||||||||||
264 | } |
|||||||||||
265 | ||||||||||||
266 | $element['text'] .= "\n" . $code_line; |
|||||||||||
267 | } else { |
|||||||||||
268 | $elements [] = $element; |
|||||||||||
269 | ||||||||||||
270 | $element = array( |
|||||||||||
271 | 'type' => 'code block', |
|||||||||||
272 | 'text' => $code_line |
|||||||||||
273 | ); |
|||||||||||
274 | } |
|||||||||||
275 | ||||||||||||
276 | continue 2; |
|||||||||||
277 | } |
|||||||||||
278 | ||||||||||||
279 | break; |
|||||||||||
280 | ||||||||||||
281 | case '#': |
|||||||||||
282 | ||||||||||||
283 | # atx heading (#) |
|||||||||||
284 | ||||||||||||
285 | if (isset($line[1])) { |
|||||||||||
286 | $elements [] = $element; |
|||||||||||
287 | ||||||||||||
288 | $level = 1; |
|||||||||||
289 | ||||||||||||
290 | while (isset($line[$level]) and '#' === $line[$level]) { |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
and instead of && is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
291 | ++$level; |
|||||||||||
292 | } |
|||||||||||
293 | ||||||||||||
294 | $element = array( |
|||||||||||
295 | 'type' => 'heading', |
|||||||||||
296 | 'text' => trim($line, '# '), |
|||||||||||
297 | 'level' => $level |
|||||||||||
298 | ); |
|||||||||||
299 | ||||||||||||
300 | continue 2; |
|||||||||||
301 | } |
|||||||||||
302 | ||||||||||||
303 | break; |
|||||||||||
304 | ||||||||||||
305 | case '-': |
|||||||||||
306 | case '=': |
|||||||||||
307 | ||||||||||||
308 | # setext heading |
|||||||||||
309 | ||||||||||||
310 | if ('paragraph' === $element['type'] and false === isset($element['interrupted'])) { |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
and instead of && is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
311 | $chopped_line = rtrim($line); |
|||||||||||
312 | ||||||||||||
313 | $i = 1; |
|||||||||||
314 | ||||||||||||
315 | while (isset($chopped_line[$i])) { |
|||||||||||
316 | if ($chopped_line[$i] !== $line[0]) { |
|||||||||||
317 | break 2; |
|||||||||||
318 | } |
|||||||||||
319 | ||||||||||||
320 | ++$i; |
|||||||||||
321 | } |
|||||||||||
322 | ||||||||||||
323 | $element['type'] = 'heading'; |
|||||||||||
324 | $element['level'] = '-' === $line[0] ? 2 : 1; |
|||||||||||
325 | ||||||||||||
326 | continue 2; |
|||||||||||
327 | } |
|||||||||||
328 | ||||||||||||
329 | break; |
|||||||||||
330 | } |
|||||||||||
331 | ||||||||||||
332 | # indentation insensitive types |
|||||||||||
333 | ||||||||||||
334 | switch ($deindented_line[0]) { |
|||||||||||
335 | case '<': |
|||||||||||
336 | ||||||||||||
337 | $position = strpos($deindented_line, '>'); |
|||||||||||
338 | ||||||||||||
339 | if ($position > 1) { # tag |
|||||||||||
340 | $name = substr($deindented_line, 1, $position - 1); |
|||||||||||
341 | $name = rtrim($name); |
|||||||||||
342 | ||||||||||||
343 | if ('/' === substr($name, -1)) { |
|||||||||||
344 | $self_closing = true; |
|||||||||||
345 | ||||||||||||
346 | $name = substr($name, 0, -1); |
|||||||||||
347 | } |
|||||||||||
348 | ||||||||||||
349 | $position = strpos($name, ' '); |
|||||||||||
350 | ||||||||||||
351 | if ($position) { |
|||||||||||
352 | $name = substr($name, 0, $position); |
|||||||||||
353 | } |
|||||||||||
354 | ||||||||||||
355 | if (!ctype_alpha($name)) { |
|||||||||||
356 | break; |
|||||||||||
357 | } |
|||||||||||
358 | ||||||||||||
359 | if (in_array($name, $this->inline_tags)) { |
|||||||||||
360 | break; |
|||||||||||
361 | } |
|||||||||||
362 | ||||||||||||
363 | $elements [] = $element; |
|||||||||||
364 | ||||||||||||
365 | if (isset($self_closing)) { |
|||||||||||
366 | $element = array( |
|||||||||||
367 | 'type' => 'self-closing tag', |
|||||||||||
368 | 'text' => $deindented_line |
|||||||||||
369 | ); |
|||||||||||
370 | ||||||||||||
371 | unset($self_closing); |
|||||||||||
372 | ||||||||||||
373 | continue 2; |
|||||||||||
374 | } |
|||||||||||
375 | ||||||||||||
376 | $element = array( |
|||||||||||
377 | 'type' => 'block-level markup', |
|||||||||||
378 | 'text' => $deindented_line, |
|||||||||||
379 | 'start' => '<' . $name . '>', |
|||||||||||
380 | 'end' => '</' . $name . '>', |
|||||||||||
381 | 'depth' => 0 |
|||||||||||
382 | ); |
|||||||||||
383 | ||||||||||||
384 | if (strpos($deindented_line, $element['end'])) { |
|||||||||||
385 | $element['closed'] = true; |
|||||||||||
386 | } |
|||||||||||
387 | ||||||||||||
388 | continue 2; |
|||||||||||
389 | } |
|||||||||||
390 | ||||||||||||
391 | break; |
|||||||||||
392 | ||||||||||||
393 | case '>': |
|||||||||||
394 | ||||||||||||
395 | # quote |
|||||||||||
396 | ||||||||||||
397 | if (preg_match('/^>[ ]?(.*)/', $deindented_line, $matches)) { |
|||||||||||
398 | $elements [] = $element; |
|||||||||||
399 | ||||||||||||
400 | $element = array( |
|||||||||||
401 | 'type' => 'blockquote', |
|||||||||||
402 | 'lines' => array( |
|||||||||||
403 | $matches[1] |
|||||||||||
404 | ) |
|||||||||||
405 | ); |
|||||||||||
406 | ||||||||||||
407 | continue 2; |
|||||||||||
408 | } |
|||||||||||
409 | ||||||||||||
410 | break; |
|||||||||||
411 | ||||||||||||
412 | case '[': |
|||||||||||
413 | ||||||||||||
414 | # reference |
|||||||||||
415 | ||||||||||||
416 | if (preg_match('/^\[(.+?)\]:[ ]*(.+?)(?:[ ]+[\'"](.+?)[\'"])?[ ]*$/', $deindented_line, $matches)) { |
|||||||||||
417 | $label = strtolower($matches[1]); |
|||||||||||
418 | ||||||||||||
419 | $this->reference_map[$label] = array( |
|||||||||||
420 | '»' => trim($matches[2], '<>') |
|||||||||||
421 | ); |
|||||||||||
422 | ||||||||||||
423 | if (isset($matches[3])) { |
|||||||||||
424 | $this->reference_map[$label]['#'] = $matches[3]; |
|||||||||||
425 | } |
|||||||||||
426 | ||||||||||||
427 | continue 2; |
|||||||||||
428 | } |
|||||||||||
429 | ||||||||||||
430 | break; |
|||||||||||
431 | ||||||||||||
432 | case '`': |
|||||||||||
433 | case '~': |
|||||||||||
434 | ||||||||||||
435 | # fenced code block |
|||||||||||
436 | ||||||||||||
437 | if (preg_match('/^([`]{3,}|[~]{3,})[ ]*(\S+)?[ ]*$/', $deindented_line, $matches)) { |
|||||||||||
438 | $elements [] = $element; |
|||||||||||
439 | ||||||||||||
440 | $element = array( |
|||||||||||
441 | 'type' => 'fenced block', |
|||||||||||
442 | 'text' => '', |
|||||||||||
443 | 'fence' => $matches[1] |
|||||||||||
444 | ); |
|||||||||||
445 | ||||||||||||
446 | isset($matches[2]) and $element['language'] = $matches[2]; |
|||||||||||
447 | ||||||||||||
448 | continue 2; |
|||||||||||
449 | } |
|||||||||||
450 | ||||||||||||
451 | break; |
|||||||||||
452 | ||||||||||||
453 | case '*': |
|||||||||||
454 | case '+': |
|||||||||||
455 | case '-': |
|||||||||||
456 | case '_': |
|||||||||||
457 | ||||||||||||
458 | # hr |
|||||||||||
459 | ||||||||||||
460 | if (preg_match('/^([-*_])([ ]{0,2}\1){2,}[ ]*$/', $deindented_line)) { |
|||||||||||
461 | $elements [] = $element; |
|||||||||||
462 | ||||||||||||
463 | $element = array( |
|||||||||||
464 | 'type' => 'hr' |
|||||||||||
465 | ); |
|||||||||||
466 | ||||||||||||
467 | continue 2; |
|||||||||||
468 | } |
|||||||||||
469 | ||||||||||||
470 | # li |
|||||||||||
471 | ||||||||||||
472 | if (preg_match('/^([ ]*)[*+-][ ](.*)/', $line, $matches)) { |
|||||||||||
473 | $elements [] = $element; |
|||||||||||
474 | ||||||||||||
475 | $element = array( |
|||||||||||
476 | 'type' => 'li', |
|||||||||||
477 | 'ordered' => false, |
|||||||||||
478 | 'indentation' => $matches[1], |
|||||||||||
479 | 'last' => true, |
|||||||||||
480 | 'lines' => array( |
|||||||||||
481 | preg_replace('/^[ ]{0,4}/', '', $matches[2]) |
|||||||||||
482 | ) |
|||||||||||
483 | ); |
|||||||||||
484 | ||||||||||||
485 | continue 2; |
|||||||||||
486 | } |
|||||||||||
487 | } |
|||||||||||
488 | ||||||||||||
489 | # li |
|||||||||||
490 | ||||||||||||
491 | if ($deindented_line[0] <= '9' and $deindented_line[0] >= '0' and preg_match('/^([ ]*)\d+[.][ ](.*)/', $line, $matches)) { |
|||||||||||
492 | $elements [] = $element; |
|||||||||||
493 | ||||||||||||
494 | $element = array( |
|||||||||||
495 | 'type' => 'li', |
|||||||||||
496 | 'ordered' => true, |
|||||||||||
497 | 'indentation' => $matches[1], |
|||||||||||
498 | 'last' => true, |
|||||||||||
499 | 'lines' => array( |
|||||||||||
500 | preg_replace('/^[ ]{0,4}/', '', $matches[2]) |
|||||||||||
501 | ) |
|||||||||||
502 | ); |
|||||||||||
503 | ||||||||||||
504 | continue; |
|||||||||||
505 | } |
|||||||||||
506 | ||||||||||||
507 | # paragraph |
|||||||||||
508 | ||||||||||||
509 | if ('paragraph' === $element['type']) { |
|||||||||||
510 | if (isset($element['interrupted'])) { |
|||||||||||
511 | $elements [] = $element; |
|||||||||||
512 | ||||||||||||
513 | $element['text'] = $line; |
|||||||||||
514 | ||||||||||||
515 | unset($element['interrupted']); |
|||||||||||
516 | } else { |
|||||||||||
517 | $element['text'] .= "\n" . $line; |
|||||||||||
518 | } |
|||||||||||
519 | } else { |
|||||||||||
520 | $elements [] = $element; |
|||||||||||
521 | ||||||||||||
522 | $element = array( |
|||||||||||
523 | 'type' => 'paragraph', |
|||||||||||
524 | 'text' => $line |
|||||||||||
525 | ); |
|||||||||||
526 | } |
|||||||||||
527 | } |
|||||||||||
528 | ||||||||||||
529 | $elements [] = $element; |
|||||||||||
530 | ||||||||||||
531 | unset($elements[0]); |
|||||||||||
532 | ||||||||||||
533 | # |
|||||||||||
534 | # ~ |
|||||||||||
535 | # |
|||||||||||
536 | ||||||||||||
537 | $markup = ''; |
|||||||||||
538 | ||||||||||||
539 | foreach ($elements as $element) { |
|||||||||||
540 | switch ($element['type']) { |
|||||||||||
541 | case 'paragraph': |
|||||||||||
542 | ||||||||||||
543 | $text = $this->parse_span_elements($element['text']); |
|||||||||||
544 | ||||||||||||
545 | if ('li' === $context and '' === $markup) { |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
and instead of && is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
546 | if (isset($element['interrupted'])) { |
|||||||||||
547 | $markup .= "\n" . '<p>' . $text . '</p>' . "\n"; |
|||||||||||
548 | } else { |
|||||||||||
549 | $markup .= $text; |
|||||||||||
550 | } |
|||||||||||
551 | } else { |
|||||||||||
552 | $markup .= '<p>' . $text . '</p>' . "\n"; |
|||||||||||
553 | } |
|||||||||||
554 | ||||||||||||
555 | break; |
|||||||||||
556 | ||||||||||||
557 | case 'blockquote': |
|||||||||||
558 | ||||||||||||
559 | $text = $this->parse_block_elements($element['lines']); |
|||||||||||
560 | ||||||||||||
561 | $markup .= '<blockquote>' . "\n" . $text . '</blockquote>' . "\n"; |
|||||||||||
562 | ||||||||||||
563 | break; |
|||||||||||
564 | ||||||||||||
565 | case 'code block': |
|||||||||||
566 | ||||||||||||
567 | $text = htmlspecialchars($element['text'], ENT_NOQUOTES, 'UTF-8'); |
|||||||||||
568 | ||||||||||||
569 | false !== strpos($text, "\x1A\\") and $text = strtr($text, $this->escape_sequence_map); |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
and instead of && is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
570 | ||||||||||||
571 | $markup .= isset($element['language']) ? '<pre><code class="language-' . $element['language'] . '">' . $text . '</code></pre>' : '<pre><code>' . $text . '</code></pre>'; |
|||||||||||
572 | ||||||||||||
573 | $markup .= "\n"; |
|||||||||||
574 | ||||||||||||
575 | break; |
|||||||||||
576 | ||||||||||||
577 | case 'fenced block': |
|||||||||||
578 | ||||||||||||
579 | $text = $element['text']; |
|||||||||||
580 | ||||||||||||
581 | false !== strpos($text, "\x1A\\") and $text = strtr($text, $this->escape_sequence_map); |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
and instead of && is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
582 | ||||||||||||
583 | $markup .= rex_highlight_string($text, true) . "\n"; |
|||||||||||
584 | ||||||||||||
585 | $markup .= "\n"; |
|||||||||||
586 | ||||||||||||
587 | break; |
|||||||||||
588 | ||||||||||||
589 | case 'heading': |
|||||||||||
590 | ||||||||||||
591 | $text = $this->parse_span_elements($element['text']); |
|||||||||||
592 | ||||||||||||
593 | $markup .= '<h' . $element['level'] . '>' . $text . '</h' . $element['level'] . '>' . "\n"; |
|||||||||||
594 | ||||||||||||
595 | break; |
|||||||||||
596 | ||||||||||||
597 | case 'hr': |
|||||||||||
598 | ||||||||||||
599 | $markup .= '<hr >' . "\n"; |
|||||||||||
600 | ||||||||||||
601 | break; |
|||||||||||
602 | ||||||||||||
603 | case 'li': |
|||||||||||
604 | ||||||||||||
605 | if (isset($element['ordered'])) { # first |
|||||||||||
606 | $list_type = $element['ordered'] ? 'ol' : 'ul'; |
|||||||||||
607 | ||||||||||||
608 | $markup .= '<' . $list_type . '>' . "\n"; |
|||||||||||
609 | } |
|||||||||||
610 | ||||||||||||
611 | if (isset($element['interrupted']) and !isset($element['last'])) { |
|||||||||||
612 | $element['lines'] [] = ''; |
|||||||||||
613 | } |
|||||||||||
614 | ||||||||||||
615 | $text = $this->parse_block_elements($element['lines'], 'li'); |
|||||||||||
616 | ||||||||||||
617 | $markup .= '<li>' . $text . '</li>' . "\n"; |
|||||||||||
618 | ||||||||||||
619 | isset($element['last']) and $markup .= '</' . $list_type . '>' . "\n"; |
|||||||||||
620 | ||||||||||||
621 | break; |
|||||||||||
622 | ||||||||||||
623 | case 'block-level markup': |
|||||||||||
624 | ||||||||||||
625 | $markup .= $element['text'] . "\n"; |
|||||||||||
626 | ||||||||||||
627 | break; |
|||||||||||
628 | ||||||||||||
629 | default: |
|||||||||||
630 | ||||||||||||
631 | $markup .= $element['text'] . "\n"; |
|||||||||||
632 | } |
|||||||||||
633 | } |
|||||||||||
634 | ||||||||||||
635 | return $markup; |
|||||||||||
636 | } |
|||||||||||
637 | ||||||||||||
638 | /** |
|||||||||||
639 | * @param $text |
|||||||||||
640 | * @param array $markers |
|||||||||||
641 | * @return string |
|||||||||||
642 | */ |
|||||||||||
643 | private function parse_span_elements($text, $markers = array('![', '&', '*', '<', '[', '_', '`', 'http', '~~')) |
|||||||||||
644 | { |
|||||||||||
645 | if (false === isset($text[2]) or $markers === array()) { |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
or instead of || is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
646 | return $text; |
|||||||||||
647 | } |
|||||||||||
648 | ||||||||||||
649 | # ~ |
|||||||||||
650 | ||||||||||||
651 | $markup = ''; |
|||||||||||
652 | ||||||||||||
653 | while ($markers) { |
|||||||||||
654 | $closest_marker = null; |
|||||||||||
655 | $closest_marker_index = 0; |
|||||||||||
656 | $closest_marker_position = null; |
|||||||||||
657 | ||||||||||||
658 | foreach ($markers as $index => $marker) { |
|||||||||||
659 | $marker_position = strpos($text, $marker); |
|||||||||||
660 | ||||||||||||
661 | if (false === $marker_position) { |
|||||||||||
662 | unset($markers[$index]); |
|||||||||||
663 | ||||||||||||
664 | continue; |
|||||||||||
665 | } |
|||||||||||
666 | ||||||||||||
667 | if (null === $closest_marker or $marker_position < $closest_marker_position) { |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
or instead of || is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
668 | $closest_marker = $marker; |
|||||||||||
669 | $closest_marker_index = $index; |
|||||||||||
670 | $closest_marker_position = $marker_position; |
|||||||||||
671 | } |
|||||||||||
672 | } |
|||||||||||
673 | ||||||||||||
674 | # ~ |
|||||||||||
675 | ||||||||||||
676 | if (null === $closest_marker or false === isset($text[$closest_marker_position + 2])) { |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
or instead of || is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
677 | $markup .= $text; |
|||||||||||
678 | ||||||||||||
679 | break; |
|||||||||||
680 | } else { |
|||||||||||
681 | $markup .= substr($text, 0, $closest_marker_position); |
|||||||||||
682 | } |
|||||||||||
683 | ||||||||||||
684 | $text = substr($text, $closest_marker_position); |
|||||||||||
685 | ||||||||||||
686 | # ~ |
|||||||||||
687 | ||||||||||||
688 | unset($markers[$closest_marker_index]); |
|||||||||||
689 | ||||||||||||
690 | # ~ |
|||||||||||
691 | ||||||||||||
692 | switch ($closest_marker) { |
|||||||||||
693 | case '![': |
|||||||||||
694 | case '[': |
|||||||||||
695 | ||||||||||||
696 | if (strpos($text, ']') and preg_match('/\[((?:[^][]|(?R))*)\]/', $text, $matches)) { |
|||||||||||
697 | $element = array( |
|||||||||||
698 | '!' => '!' === $text[0], |
|||||||||||
699 | 'a' => $matches[1] |
|||||||||||
700 | ); |
|||||||||||
701 | ||||||||||||
702 | $offset = strlen($matches[0]); |
|||||||||||
703 | ||||||||||||
704 | $element['!'] and ++$offset; |
|||||||||||
705 | ||||||||||||
706 | $remaining_text = substr($text, $offset); |
|||||||||||
707 | ||||||||||||
708 | if ('(' === $remaining_text[0] and preg_match('/\([ ]*(.*?)(?:[ ]+[\'"](.+?)[\'"])?[ ]*\)/', $remaining_text, $matches)) { |
|||||||||||
709 | $element['»'] = $matches[1]; |
|||||||||||
710 | ||||||||||||
711 | if (isset($matches[2])) { |
|||||||||||
712 | $element['#'] = $matches[2]; |
|||||||||||
713 | } |
|||||||||||
714 | ||||||||||||
715 | $offset += strlen($matches[0]); |
|||||||||||
716 | } elseif ($this->reference_map) { |
|||||||||||
717 | $reference = $element['a']; |
|||||||||||
718 | ||||||||||||
719 | if (preg_match('/^\s*\[(.*?)\]/', $remaining_text, $matches)) { |
|||||||||||
720 | $reference = $matches[1] ?: $element['a']; |
|||||||||||
721 | ||||||||||||
722 | $offset += strlen($matches[0]); |
|||||||||||
723 | } |
|||||||||||
724 | ||||||||||||
725 | $reference = strtolower($reference); |
|||||||||||
726 | ||||||||||||
727 | if (isset($this->reference_map[$reference])) { |
|||||||||||
728 | $element['»'] = $this->reference_map[$reference]['»']; |
|||||||||||
729 | ||||||||||||
730 | if (isset($this->reference_map[$reference]['#'])) { |
|||||||||||
731 | $element['#'] = $this->reference_map[$reference]['#']; |
|||||||||||
732 | } |
|||||||||||
733 | } else { |
|||||||||||
734 | unset($element); |
|||||||||||
735 | } |
|||||||||||
736 | } else { |
|||||||||||
737 | unset($element); |
|||||||||||
738 | } |
|||||||||||
739 | } |
|||||||||||
740 | ||||||||||||
741 | if (isset($element)) { |
|||||||||||
742 | $element['»'] = str_replace('&', '&', $element['»']); |
|||||||||||
743 | $element['»'] = str_replace('<', '<', $element['»']); |
|||||||||||
744 | ||||||||||||
745 | if ($element['!']) { |
|||||||||||
746 | $markup .= '<img alt="' . $element['a'] . '" src="' . $element['»'] . '" >'; |
|||||||||||
747 | } else { |
|||||||||||
748 | $element['a'] = $this->parse_span_elements($element['a'], $markers); |
|||||||||||
749 | ||||||||||||
750 | $markup .= isset($element['#']) ? '<a href="' . $element['»'] . '" title="' . $element['#'] . '">' . $element['a'] . '</a>' : '<a href="' . $element['»'] . '">' . $element['a'] . '</a>'; |
|||||||||||
751 | } |
|||||||||||
752 | ||||||||||||
753 | unset($element); |
|||||||||||
754 | } else { |
|||||||||||
755 | $markup .= $closest_marker; |
|||||||||||
756 | ||||||||||||
757 | $offset = '![' === $closest_marker ? 2 : 1; |
|||||||||||
758 | } |
|||||||||||
759 | ||||||||||||
760 | break; |
|||||||||||
761 | ||||||||||||
762 | case '&': |
|||||||||||
763 | ||||||||||||
764 | if (preg_match('/^&#?\w+;/', $text, $matches)) { |
|||||||||||
765 | $markup .= $matches[0]; |
|||||||||||
766 | ||||||||||||
767 | $offset = strlen($matches[0]); |
|||||||||||
768 | } else { |
|||||||||||
769 | $markup .= '&'; |
|||||||||||
770 | ||||||||||||
771 | $offset = 1; |
|||||||||||
772 | } |
|||||||||||
773 | ||||||||||||
774 | break; |
|||||||||||
775 | ||||||||||||
776 | case '*': |
|||||||||||
777 | case '_': |
|||||||||||
778 | ||||||||||||
779 | if ($text[1] === $closest_marker and preg_match($this->strong_regex[$closest_marker], $text, $matches)) { |
|||||||||||
780 | $matches[1] = $this->parse_span_elements($matches[1], $markers); |
|||||||||||
781 | ||||||||||||
782 | $markup .= '<strong>' . $matches[1] . '</strong>'; |
|||||||||||
783 | } elseif (preg_match($this->em_regex[$closest_marker], $text, $matches)) { |
|||||||||||
784 | $matches[1] = $this->parse_span_elements($matches[1], $markers); |
|||||||||||
785 | ||||||||||||
786 | $markup .= '<em>' . $matches[1] . '</em>'; |
|||||||||||
787 | } elseif ($text[1] === $closest_marker and preg_match($this->strong_em_regex[$closest_marker], $text, $matches)) { |
|||||||||||
788 | $matches[2] = $this->parse_span_elements($matches[2], $markers); |
|||||||||||
789 | ||||||||||||
790 | $matches[1] and $matches[1] = $this->parse_span_elements($matches[1], $markers); |
|||||||||||
791 | $matches[3] and $matches[3] = $this->parse_span_elements($matches[3], $markers); |
|||||||||||
792 | ||||||||||||
793 | $markup .= '<strong>' . $matches[1] . '<em>' . $matches[2] . '</em>' . $matches[3] . '</strong>'; |
|||||||||||
794 | } elseif (preg_match($this->em_strong_regex[$closest_marker], $text, $matches)) { |
|||||||||||
795 | $matches[2] = $this->parse_span_elements($matches[2], $markers); |
|||||||||||
796 | ||||||||||||
797 | $matches[1] and $matches[1] = $this->parse_span_elements($matches[1], $markers); |
|||||||||||
798 | $matches[3] and $matches[3] = $this->parse_span_elements($matches[3], $markers); |
|||||||||||
799 | ||||||||||||
800 | $markup .= '<em>' . $matches[1] . '<strong>' . $matches[2] . '</strong>' . $matches[3] . '</em>'; |
|||||||||||
801 | } |
|||||||||||
802 | ||||||||||||
803 | if (isset($matches) and $matches) { |
|||||||||||
804 | $offset = strlen($matches[0]); |
|||||||||||
805 | } else { |
|||||||||||
806 | $markup .= $closest_marker; |
|||||||||||
807 | ||||||||||||
808 | $offset = 1; |
|||||||||||
809 | } |
|||||||||||
810 | ||||||||||||
811 | break; |
|||||||||||
812 | ||||||||||||
813 | case '<': |
|||||||||||
0 ignored issues
–
show
The case body in a switch statement must start on the line following the statement.
According to the PSR-2, the body of a case statement must start on the line immediately following the case statement. switch ($expr) {
case "A":
doSomething(); //right
break;
case "B":
doSomethingElse(); //wrong
break;
} To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
||||||||||||
814 | ||||||||||||
815 | if (false !== strpos($text, '>')) { |
|||||||||||
816 | if ('h' === $text[1] and preg_match('/^<(https?:[\/]{2}[^\s]+?)>/i', $text, $matches)) { |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
and instead of && is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
817 | $element_url = $matches[1]; |
|||||||||||
818 | $element_url = str_replace('&', '&', $element_url); |
|||||||||||
819 | $element_url = str_replace('<', '<', $element_url); |
|||||||||||
820 | ||||||||||||
821 | $markup .= '<a href="' . $element_url . '">' . $element_url . '</a>'; |
|||||||||||
822 | ||||||||||||
823 | $offset = strlen($matches[0]); |
|||||||||||
824 | } elseif (preg_match('/^<\/?\w.*?>/', $text, $matches)) { |
|||||||||||
825 | $markup .= $matches[0]; |
|||||||||||
826 | ||||||||||||
827 | $offset = strlen($matches[0]); |
|||||||||||
828 | } else { |
|||||||||||
829 | $markup .= '<'; |
|||||||||||
830 | ||||||||||||
831 | $offset = 1; |
|||||||||||
832 | } |
|||||||||||
833 | } else { |
|||||||||||
834 | $markup .= '<'; |
|||||||||||
835 | ||||||||||||
836 | $offset = 1; |
|||||||||||
837 | } |
|||||||||||
838 | ||||||||||||
839 | break; |
|||||||||||
840 | ||||||||||||
841 | case '`': |
|||||||||||
842 | ||||||||||||
843 | if (preg_match('/^`(.+?)`/', $text, $matches)) { |
|||||||||||
844 | $element_text = $matches[1]; |
|||||||||||
845 | $element_text = htmlspecialchars($element_text, ENT_NOQUOTES, 'UTF-8'); |
|||||||||||
846 | ||||||||||||
847 | if ($this->escape_sequence_map and false !== strpos($element_text, "\x1A")) { |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
and instead of && is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
848 | $element_text = strtr($element_text, $this->escape_sequence_map); |
|||||||||||
849 | } |
|||||||||||
850 | ||||||||||||
851 | $markup .= '<code>' . $element_text . '</code>'; |
|||||||||||
852 | ||||||||||||
853 | $offset = strlen($matches[0]); |
|||||||||||
854 | } else { |
|||||||||||
855 | $markup .= '`'; |
|||||||||||
856 | ||||||||||||
857 | $offset = 1; |
|||||||||||
858 | } |
|||||||||||
859 | ||||||||||||
860 | break; |
|||||||||||
861 | ||||||||||||
862 | case 'http': |
|||||||||||
863 | ||||||||||||
864 | if (preg_match('/^https?:[\/]{2}[^\s]+\b/i', $text, $matches)) { |
|||||||||||
865 | $element_url = $matches[0]; |
|||||||||||
866 | $element_url = str_replace('&', '&', $element_url); |
|||||||||||
867 | $element_url = str_replace('<', '<', $element_url); |
|||||||||||
868 | ||||||||||||
869 | $markup .= '<a href="' . $element_url . '">' . $element_url . '</a>'; |
|||||||||||
870 | ||||||||||||
871 | $offset = strlen($matches[0]); |
|||||||||||
872 | } else { |
|||||||||||
873 | $markup .= 'http'; |
|||||||||||
874 | ||||||||||||
875 | $offset = 4; |
|||||||||||
876 | } |
|||||||||||
877 | ||||||||||||
878 | break; |
|||||||||||
879 | ||||||||||||
880 | case '~~': |
|||||||||||
881 | ||||||||||||
882 | if (preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $text, $matches)) { |
|||||||||||
883 | $matches[1] = $this->parse_span_elements($matches[1], $markers); |
|||||||||||
884 | ||||||||||||
885 | $markup .= '<del>' . $matches[1] . '</del>'; |
|||||||||||
886 | ||||||||||||
887 | $offset = strlen($matches[0]); |
|||||||||||
888 | } else { |
|||||||||||
889 | $markup .= '~~'; |
|||||||||||
890 | ||||||||||||
891 | $offset = 2; |
|||||||||||
892 | } |
|||||||||||
893 | ||||||||||||
894 | break; |
|||||||||||
895 | } |
|||||||||||
896 | ||||||||||||
897 | if (isset($offset)) { |
|||||||||||
898 | $text = substr($text, $offset); |
|||||||||||
899 | } |
|||||||||||
900 | ||||||||||||
901 | $markers[$closest_marker_index] = $closest_marker; |
|||||||||||
902 | } |
|||||||||||
903 | ||||||||||||
904 | $markup = str_replace($this->break_marker, '<br >' . "\n", $markup); |
|||||||||||
905 | ||||||||||||
906 | return $markup; |
|||||||||||
907 | } |
|||||||||||
908 | ||||||||||||
909 | # |
|||||||||||
910 | # Read-only |
|||||||||||
911 | # |
|||||||||||
912 | ||||||||||||
913 | private $inline_tags = array( |
|||||||||||
914 | 'a', |
|||||||||||
915 | 'abbr', |
|||||||||||
916 | 'acronym', |
|||||||||||
917 | 'b', |
|||||||||||
918 | 'bdo', |
|||||||||||
919 | 'big', |
|||||||||||
920 | 'br', |
|||||||||||
921 | 'button', |
|||||||||||
922 | 'cite', |
|||||||||||
923 | 'code', |
|||||||||||
924 | 'dfn', |
|||||||||||
925 | 'em', |
|||||||||||
926 | 'i', |
|||||||||||
927 | 'img', |
|||||||||||
928 | 'input', |
|||||||||||
929 | 'kbd', |
|||||||||||
930 | 'label', |
|||||||||||
931 | 'map', |
|||||||||||
932 | 'object', |
|||||||||||
933 | 'q', |
|||||||||||
934 | 'samp', |
|||||||||||
935 | 'script', |
|||||||||||
936 | 'select', |
|||||||||||
937 | 'small', |
|||||||||||
938 | 'span', |
|||||||||||
939 | 'strong', |
|||||||||||
940 | 'sub', |
|||||||||||
941 | 'sup', |
|||||||||||
942 | 'textarea', |
|||||||||||
943 | 'tt', |
|||||||||||
944 | 'var' |
|||||||||||
945 | ); |
|||||||||||
946 | ||||||||||||
947 | # ~ |
|||||||||||
948 | ||||||||||||
949 | private $strong_regex = array( |
|||||||||||
950 | '*' => '/^[*]{2}([^*]+?)[*]{2}(?![*])/s', |
|||||||||||
951 | '_' => '/^__([^_]+?)__(?!_)/s' |
|||||||||||
952 | ); |
|||||||||||
953 | ||||||||||||
954 | private $em_regex = array( |
|||||||||||
955 | '*' => '/^[*]([^*]+?)[*](?![*])/s', |
|||||||||||
956 | '_' => '/^_([^_]+?)[_](?![_])\b/s' |
|||||||||||
957 | ); |
|||||||||||
958 | ||||||||||||
959 | private $strong_em_regex = array( |
|||||||||||
960 | '*' => '/^[*]{2}(.*?)[*](.+?)[*](.*?)[*]{2}/s', |
|||||||||||
961 | '_' => '/^__(.*?)_(.+?)_(.*?)__/s' |
|||||||||||
962 | ); |
|||||||||||
963 | ||||||||||||
964 | private $em_strong_regex = array( |
|||||||||||
965 | '*' => '/^[*](.*?)[*]{2}(.+?)[*]{2}(.*?)[*]/s', |
|||||||||||
966 | '_' => '/^_(.*?)__(.+?)__(.*?)_/s' |
|||||||||||
967 | ); |
|||||||||||
968 | } |
|||||||||||
969 |
PHP has two types of connecting operators (logical operators, and boolean operators):
and
&&
or
||
The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like
&&
, or||
.Let’s take a look at a few examples:
Logical Operators are used for Control-Flow
One case where you explicitly want to use logical operators is for control-flow such as this:
Since
die
introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined withthrow
at this point:These limitations lead to logical operators rarely being of use in current PHP code.