1. Definition
Als Type Juggling wird PHPs Fähigkeit bezeichnet, die Datentypen von Variablen abhängig vom Kontext in dem sie verwendet werden automatisch zu ändern.
1.1. Beispiel
Im nachfolgenden Beispiel wird zum Integer-Wert 1 der String "1" addiert. Während dies in vielen anderen Programmiersprachen einen Fehler erzeugen würde, wandelt PHP automatisch den String in einen passenden Integer-Wert (hier: 1) um und berechnet das Ergebnis (hier: 1 + 1 = 2).
PHP-Code
<?php $a = (int)1; $b = (string)"1"; $c = $a + $b; var_dump($a, $b, $c); ?>
Ausgabe
int(1) string(1) "1" int(2)
2. Type Juggling mit dem Additionsoperator (+)
Nachfolgend eine Tabelle zur Darstellung des Type Jugglings mit dem +-Operator (doub = double, int = integer, bool = boolean):
+ (int)1 | + (doub)1 | + (string)"0" | + (string)"1" | + (string)"1abc" | + (string)"abc" | + (string)"" | + (bool)false | + (bool)true | + (NULL) | |
---|---|---|---|---|---|---|---|---|---|---|
(int)1 | (int) 2 | (doub) 2 | (int) 1 | (int) 2 | (int) 2 | (int) 1 | (int) 1 | (int) 1 | (int) 2 | (int) 1 |
(doub)1 | (doub) 2 | (doub) 2 | (doub) 1 | (doub) 2 | (doub) 2 | (doub) 1 | (doub) 1 | (doub) 1 | (doub) 2 | (doub) 1 |
(string)"0" | (int) 1 | (doub) 1 | (int) 0 | (int) 1 | (int) 1 | (int) 0 | (int) 0 | (int) 0 | (int) 1 | (int) 0 |
(string)"1" | (int) 2 | (doub) 2 | (int) 1 | (int) 2 | (int) 2 | (int) 1 | (int) 1 | (int) 1 | (int) 2 | (int) 1 |
(string)"1abc" | (int) 2 | (doub) 2 | (int) 1 | (int) 2 | (int) 2 | (int) 1 | (int) 1 | (int) 1 | (int) 2 | (int) 1 |
(string)"abc" | (int) 1 | (doub) 1 | (int) 0 | (int) 1 | (int) 1 | (int) 0 | (int) 0 | (int) 0 | (int) 1 | (int) 0 |
(string)"" | (int) 1 | (doub) 1 | (int) 0 | (int) 1 | (int) 1 | (int) 0 | (int) 0 | (int) 0 | (int) 1 | (int) 0 |
(bool)false | (int) 1 | (doub) 1 | (int) 0 | (int) 1 | (int) 1 | (int) 0 | (int) 0 | (int) 0 | (int) 1 | (int) 0 |
(bool)true | (int) 2 | (doub) 2 | (int) 1 | (int) 2 | (int) 2 | (int) 1 | (int) 1 | (int) 1 | (int) 2 | (int) 1 |
(NULL) | (int) 1 | (doub) 1 | (int) 0 | (int) 1 | (int) 1 | (int) 0 | (int) 0 | (int) 0 | (int) 1 | (int) 0 |
3. Type Juggling mit dem Subtraktionsoperator (-)
- (int)1 | - (doub)1 | - (string)"0" | - (string)"1" | - (string)"1abc" | - (string)"abc" | - (string)"" | - (bool)false | - (bool)true | - (NULL) | |
---|---|---|---|---|---|---|---|---|---|---|
(int)1 | (int) 0 | (doub) 0 | (int) 1 | (int) 0 | (int) 0 | (int) 1 | (int) 1 | (int) 1 | (int) 0 | (int) 1 |
(doub)1 | (doub) 0 | (doub) 0 | (doub) 1 | (doub) 0 | (doub) 0 | (doub) 1 | (doub) 1 | (doub) 1 | (doub) 0 | (doub) 1 |
(string)"0" | (int) -1 | (doub) -1 | (int) 0 | (int) -1 | (int) -1 | (int) 0 | (int) 0 | (int) 0 | (int) -1 | (int) 0 |
(string)"1" | (int) 0 | (doub) 0 | (int) 1 | (int) 0 | (int) 0 | (int) 1 | (int) 1 | (int) 1 | (int) 0 | (int) 1 |
(string)"1abc" | (int) 0 | (doub) 0 | (int) 1 | (int) 0 | (int) 0 | (int) 1 | (int) 1 | (int) 1 | (int) 0 | (int) 1 |
(string)"abc" | (int) -1 | (doub) -1 | (int) 0 | (int) -1 | (int) -1 | (int) 0 | (int) 0 | (int) 0 | (int) -1 | (int) 0 |
(string)"" | (int) -1 | (doub) -1 | (int) 0 | (int) -1 | (int) -1 | (int) 0 | (int) 0 | (int) 0 | (int) -1 | (int) 0 |
(bool)false | (int) -1 | (doub) -1 | (int) 0 | (int) -1 | (int) -1 | (int) 0 | (int) 0 | (int) 0 | (int) -1 | (int) 0 |
(bool)true | (int) 0 | (doub) 0 | (int) 1 | (int) 0 | (int) 0 | (int) 1 | (int) 1 | (int) 1 | (int) 0 | (int) 1 |
(NULL) | (int) -1 | (doub) -1 | (int) 0 | (int) -1 | (int) -1 | (int) 0 | (int) 0 | (int) 0 | (int) -1 | (int) 0 |
4. Type Juggling mit dem Multiplikationsoperator (*)
* (int)1 | * (doub)1 | * (string)"0" | * (string)"1" | * (string)"1abc" | * (string)"abc" | * (string)"" | * (bool)false | * (bool)true | * (NULL) | |
---|---|---|---|---|---|---|---|---|---|---|
(int)1 | (int) 1 | (doub) 1 | (int) 0 | (int) 1 | (int) 1 | (int) 0 | (int) 0 | (int) 0 | (int) 1 | (int) 0 |
(doub)1 | (doub) 1 | (doub) 1 | (doub) 0 | (doub) 1 | (doub) 1 | (doub) 0 | (doub) 0 | (doub) 0 | (doub) 1 | (doub) 0 |
(string)"0" | (int) 0 | (doub) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 |
(string)"1" | (int) 1 | (doub) 1 | (int) 0 | (int) 1 | (int) 1 | (int) 0 | (int) 0 | (int) 0 | (int) 1 | (int) 0 |
(string)"1abc" | (int) 1 | (doub) 1 | (int) 0 | (int) 1 | (int) 1 | (int) 0 | (int) 0 | (int) 0 | (int) 1 | (int) 0 |
(string)"abc" | (int) 0 | (doub) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 |
(string)"" | (int) 0 | (doub) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 |
(bool)false | (int) 0 | (doub) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 |
(bool)true | (int) 1 | (doub) 1 | (int) 0 | (int) 1 | (int) 1 | (int) 0 | (int) 0 | (int) 0 | (int) 1 | (int) 0 |
(NULL) | (int) 0 | (doub) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 | (int) 0 |
5. Type Juggling mit dem Divisionsoperator (/)
DBZ repräsentiert einen Wert, der nicht berechnet werden kann, da durch 0 geteilt werden müsste (division by zero).
/ (int)1 | / (doub)1 | / (string)"0" | / (string)"1" | / (string)"1abc" | / (string)"abc" | / (string)"" | / (bool)false | / (bool)true | / (NULL) | |
---|---|---|---|---|---|---|---|---|---|---|
(int)1 | (int) 1 | (doub) 1 | (-) DBZ | (int) 1 | (int) 1 | (-) DBZ | (-) DBZ | (-) DBZ | (int) 1 | (-) DBZ |
(doub)1 | (doub) 1 | (doub) 1 | (-) DBZ | (doub) 1 | (doub) 1 | (-) DBZ | (-) DBZ | (-) DBZ | (doub) 1 | (-) DBZ |
(string)"0" | (int) 0 | (doub) 0 | (-) DBZ | (int) 0 | (int) 0 | (-) DBZ | (-) DBZ | (-) DBZ | (int) 0 | (-) DBZ |
(string)"1" | (int) 1 | (doub) 1 | (-) DBZ | (int) 1 | (int) 1 | (-) DBZ | (-) DBZ | (-) DBZ | (int) 1 | (-) DBZ |
(string)"1abc" | (int) 1 | (doub) 1 | (-) DBZ | (int) 1 | (int) 1 | (-) DBZ | (-) DBZ | (-) DBZ | (int) 1 | (-) DBZ |
(string)"abc" | (int) 0 | (doub) 0 | (-) DBZ | (int) 0 | (int) 0 | (-) DBZ | (-) DBZ | (-) DBZ | (int) 0 | (-) DBZ |
(string)"" | (int) 0 | (doub) 0 | (-) DBZ | (int) 0 | (int) 0 | (-) DBZ | (-) DBZ | (-) DBZ | (int) 0 | (-) DBZ |
(bool)false | (int) 0 | (doub) 0 | (-) DBZ | (int) 0 | (int) 0 | (-) DBZ | (-) DBZ | (-) DBZ | (int) 0 | (-) DBZ |
(bool)true | (int) 1 | (doub) 1 | (-) DBZ | (int) 1 | (int) 1 | (-) DBZ | (-) DBZ | (-) DBZ | (int) 1 | (-) DBZ |
(NULL) | (int) 0 | (doub) 0 | (-) DBZ | (int) 0 | (int) 0 | (-) DBZ | (-) DBZ | (-) DBZ | (int) 0 | (-) DBZ |
6. Code zum Erzeugen der Tabellen
Der nachfolgende Code erzeugt die vorherigen Tabellen.
PHP-Code
<?php function shortType($var) { if ($var === 'DBZ') { return '-'; } switch (gettype($var)) { case 'integer': return 'int'; case 'double': return 'doub'; case 'boolean': return 'bool'; } return gettype($var); } function valToString($val) { if (is_string($val)) { return '"'.$val.'"'; } else if (is_bool($val)) { return ($val===true ? 'true' : 'false'); } else { return strval($val); } } function calc($v1, $v2, $operator) { switch ($operator) { case '+': return $v1 + $v2; case '-': return $v1 - $v2; case '*': return $v1 * $v2; case '/': return (intval($v2)===0 || floatval($v2)===0 ? 'DBZ' : $v1 / $v2); } } $values = array(1, 1.0, "0", "1", "1abc", "abc", "", false, true, null); $operators = array('+', '-', '*', '/'); ?> <?php foreach ($operators as $operator): ?> <table class="type-juggling-table"> <thead> <tr> <th></th> <?php foreach ($values as $val): ?> <th><?php echo $operator; ?> <?php echo "(" . shortType($val) . ")" . valToString($val); ?></th> <?php endforeach; ?> </tr> </thead> <tbody> <?php foreach ($values as $val1): ?> <tr> <td><?php echo "(" . shortType($val1) . ")" . valToString($val1); ?></td> <?php foreach ($values as $val2): ?> <td> <?php $result = calc($val1, $val2, $operator); ?> (<?php echo shortType($result); ?>) <?php echo $result; ?> </td> <?php endforeach; ?> </tr> <?php endforeach; ?> </tbody> </table> <?php endforeach; ?>