Type Juggling

PHP does not require (or support) explicit type definition in variable
declaration; a variable's type is determined by the context in which the
variable is used. That is to say, if a string value is assigned
to variable $var, $var becomes a
string. If an integer value is then assigned to
$var, it becomes an integer.

An example of PHP's automatic type conversion is the multiplication operator '*'.
If either operand is a float, then both operands are evaluated as
floats, and the result will be a float. Otherwise,
the operands will be interpreted as integers, and the result will
also be an integer. Note that this does not
change the types of the operands themselves; the only change is in how the
operands are evaluated and what the type of the expression itself is.

User Contributed Notes 33 notes

Uneven division of an integer variable by another integer variable will result in a float by automatic conversion -- you do not have to cast the variables to floats in order to avoid integer truncation (as you would in C, for example):

/* checks if a string is an integer with possible whitespace before and/or after, and also isolates the integer */$isInt=preg_match('/^\s*([0-9]+)\s*$/', $myString, $myInt);

echo 'Is Integer? ', ($isInt) ? 'Yes: '.$myInt[1] : 'No', "\n";

/* checks if a string is an integer with no whitespace before or after */$isInt=preg_match('/^[0-9]+$/', $myString);

echo 'Is Integer? ', ($isInt) ? 'Yes' : 'No', "\n";

/* When checking for floats, we assume the possibility of no decimals needed. If you MUST require decimals (forcing the user to type 7.0 for example) replace the sequence:[0-9]+(\.[0-9]+)? with [0-9]+\.[0-9]+ */

/* checks if a string is a float with possible whitespace before and/or after, and also isolates the number */$isFloat=preg_match('/^\s*([0-9]+(\.[0-9]+)?)\s*$/', $myString, $myNum);

echo 'Is Number? ', ($isFloat) ? 'Yes: '.$myNum[1] : 'No', "\n";

/* checks if a string is a float with no whitespace before or after */$isInt=preg_match('/^[0-9]+(\.[0-9]+)?$/', $myString);

namaroulis stated "I found it tricky to check if a posted value was an integer"; to test if a variable is a number or a numeric string (such as form input, which is always a string), you must use is_numeric():

Looks like type-casting user-defined objects is a real pain, and ya gotta be nuttin' less than a brain jus ta cypher-it. But since PHP supports OOP, you can add the capabilities right now. Start with any simple class.<?phpclass Point { protected $x, $y;

$p = new Point(25, 35);echo $p->getX(); // 25echo $p->getY(); // 35?>Ok, now we need extra powers. PHP gives us several options: A. We can tag on extra properties on-the-fly using everyday PHP syntax... $p->z = 45; // here, $p is still an object of type [Point] but gains no capability, and it's on a per-instance basis, blah. B. We can try type-casting it to a different type to access more functions... $p = (SuperDuperPoint) $p; // if this is even allowed, I doubt it. But even if PHP lets this slide, the small amount of data Point holds would probably not be enough for the extra functions to work anyway. And we still need the class def + all extra data. We should have just instantiated a [SuperDuperPoint] object to begin with... and just like above, this only works on a per-instance basis. C. Do it the right way using OOP - and just extend the Point class already.<?phpclass Point3D extends Point { protected $z; // add extra properties...

$p3d = new Point3D(25, 35, 45); // more data, more functions, more everything...echo $p3d->getX(); // 25echo $p3d->getY(); // 35echo $p3d->getZ(); // 45?>Once the new class definition is written, you can make as many Point3D objects as you want. Each of them will have more data and functions already built-in. This is much better than trying to beef-up any "single lesser object" on-the-fly, and it's way easier to do.

If you want to do not only typecasting between basic data types but between classes, try this function. It converts any class into another. All variables that equal name in both classes will be copied.

The code listed in some of the comments here for supposedly "casting" from one class to another using unserialize/serialize does not actually change the class of the existing object; it creates a new object. So it's not the same as a cast.

In my much of my coding I have found it necessary to type-cast between objects of different class types.

More specifically, I often want to take information from a database, convert it into the class it was before it was inserted, then have the ability to call its class functions as well.

The following code is much shorter than some of the previous examples and seems to suit my purposes. It also makes use of some regular expression matching rather than string position, replacing, etc. It takes an object ($obj) of any type and casts it to an new type ($class_type). Note that the new class type must exist:

It would be useful to know the precedence (for lack of a better word) for type juggling. This entry currently explains that "if either operand is a float, then both operands are evaluated as floats, and the result will be a float" but could (and I think should) provide a hierarchy that indicates, for instance, "between an int and a boolean, int wins; between a float and an int, float wins; between a string and a float, string wins" and so on (and don't count on my example accurately capturing the true hierarchy, as I haven't actually done the tests to figure it out). Thanks!

For some reason the code-fix posted by philip_snyder at hotmail dot com [27-Feb-2004 02:08]didn't work for me neither with long_class_names nor with short_class_names. I'm using PHP v4.3.5 for Linux.Anyway here's what I wrote to solve the long_named_classes problem: