Typecasting VS Function to Convert Variable Type in PHP

Typecasting vs function to convert variable type in PHP

There's no difference in the resulting value, just:

  • (float) is a language feature and very quick
  • floatval() incurs the overhead of a function call (minimal, but nonetheless...)
  • floatval() as a function can be used in ways that (float) cannot, e.g. array_map('floatval', $foo)

The last point is, I believe, the main reason for floatval's existence: so each casting operation has a function equivalent, which can be useful in some circumstances.

Type Hinting vs Type Casting in setters php

They are NOT functionally equivalent.

Type Hinting: You are dictating what type must be passed. If the given value is of the incorrect type, then an error is generated. This does not cast or "convert" the passed value into a specific type.

Type Casting: Regardless of what value is passed, you are "converting" it into the correct type. If your function "needs" an array, then why let a boolean be passed and then cast it to an array?

Also, type hinting allows you to specify an object instance of a specific class. In the following, $bar must be an instance of class Bar or else an error is generated:

public function setBar(Bar $bar)

You can not type cast a variable to an object of a specific class.

PHP Typecasting - Good or bad?

For better or worse, loose-typing is "The PHP Way". Many of the built-ins, and most of the language constructs, will operate on whatever types you give them -- silently (and often dangerously) casting them behind the scenes to make things (sort of) fit together.

Coming from a Java/C/C++ background myself, PHP's loose-typing model has always been a source of frustration for me. But through the years I've found that, if I have to write PHP I can do a better job of it (i.e. cleaner, safer, more testable code) by embracing PHP's "looseness", rather than fighting it; and I end up a happier monkey because of it.

Casting really is fundamental to my technique -- and (IMHO) it's the only way to consistently build clean, readable PHP code that handles mixed-type arguments in a well-understood, testable, deterministic way.

The main point (which you clearly understand as well) is that, in PHP, you can not simply assume that an argument is the type you expect it to be. Doing so, can have serious consequences that you are not likely to catch until after your app has gone to production.

To illustrate this point:

<?php

function displayRoomCount( $numBoys, $numGirls ) {
// we'll assume both args are int

// check boundary conditions
if( ($numBoys < 0) || ($numGirls < 0) ) throw new Exception('argument out of range');

// perform the specified logic
$total = $numBoys + $numGirls;
print( "{$total} people: {$numBoys} boys, and {$numGirls} girls \n" );
}

displayRoomCount(0, 0); // (ok) prints: "0 people: 0 boys, and 0 girls"

displayRoomCount(-10, 20); // (ok) throws an exception

displayRoomCount("asdf", 10); // (wrong!) prints: "10 people: asdf boys, and 10 girls"

One approach to solving this is to restrict the types that the function can accept, throwing an exception when an invalid type is detected. Others have mentioned this approach already. It appeals well to my Java/C/C++ aesthetics, and I followed this approach in PHP for years and years. In short, there's nothing wrong with it, but it does go against "The PHP Way", and after a while, that starts to feel like swimming up-stream.

As an alternative, casting provides a simple and clean way to ensure that the function behaves deterministically for all possible inputs, without having to write specific logic to handle each different type.

Using casting, our example now becomes:

<?php

function displayRoomCount( $numBoys, $numGirls ) {
// we cast to ensure that we have the types we expect
$numBoys = (int)$numBoys;
$numGirls = (int)$numGirls;

// check boundary conditions
if( ($numBoys < 0) || ($numGirls < 0) ) throw new Exception('argument out of range');

// perform the specified logic
$total = $numBoys + $numGirls;
print( "{$total} people: {$numBoys} boys, and {$numGirls} girls \n" );
}

displayRoomCount("asdf", 10); // (ok now!) prints: "10 people: 0 boys, and 10 girls"

The function now behaves as expected. In fact, it's easy to show that the function's behavior is now well-defined for all possible inputs. This is because the the cast operation is well-defined for all possible inputs; the casts ensure that we're always working with integers; and the rest of the function is written so as to be well-defined for all possible integers.

Rules for type-casting in PHP are documented here, (see the type-specific links mid-way down the page - eg: "Converting to integer").

This approach has the added benefit that the function will now behave in a way that is consistent with other PHP built-ins, and language constructs. For example:

// assume $db_row read from a database of some sort
displayRoomCount( $db_row['boys'], $db_row['girls'] );

will work just fine, despite the fact that $db_row['boys'] and $db_row['girls'] are actually strings that contain numeric values. This is consistent with the way that the average PHP developer (who does not know C, C++, or Java) will expect it to work.


As for casting return values: there is very little point in doing so, unless you know that you have a potentially mixed-type variable, and you want to always ensure that the return value is a specific type. This is more often the case at intermediate points in the code, rather than at the point where you're returning from a function.

A practical example:

<?php

function getParam( $name, $idx=0 ) {
$name = (string)$name;
$idx = (int)$idx;

if($name==='') return null;
if($idx<0) $idx=0;

// $_REQUEST[$name] could be null, or string, or array
// this depends on the web request that came in. Our use of
// the array cast here, lets us write generic logic to deal with them all
//
$param = (array)$_REQUEST[$name];

if( count($param) <= $idx) return null;
return $param[$idx];
}

// here, the cast is used to ensure that we always get a string
// even if "fullName" was missing from the request, the cast will convert
// the returned NULL value into an empty string.
$full_name = (string)getParam("fullName");

You get the idea.


There are a couple of gotcha's to be aware of

  • PHP's casting mechanism is not smart enough to optimize the "no-op" cast. So casting always causes a copy of the variable to be made. In most cases, this not a problem, but if you regularly use this approach, you should keep it in the back of your mind. Because of this, casting can cause unexpected issues with references and large arrays. See PHP Bug Report #50894 for more details.

  • In php, a whole number that is too large (or too small) to represent as an integer type, will automatically be represented as a float (or a double, if necessary). This means that the result of ($big_int + $big_int) can actually be a float, and if you cast it to an int the resulting number will be gibberish. So, if you're building functions that need to operate on large whole numbers, you should keep this in mind, and probably consider some other approach.


Sorry for the long post, but it's a topic that I've considered in depth, and through the years, I've accumulated quite a bit of knowledge (and opinion) about it. By putting it out here, I hope someone will find it helpful.

Using settype in PHP instead of typecasting using brackets, What is the difference?

Casting changes what the variable is being treated as in the current context, settype changes it permanently.

$value = "100"; //Value is a string
echo 5 + (int)$value; //Value is treated like an integer for this line
settype($value,'int'); //Value is now an integer

Basically settype is a shortcut for:

$value = (type)$value;

PHP typecasting

(int)$value

saves one function call compares to intval($value) and settype($value, 'int').

And (int)$value is clean enough, so I prefer this way.

When you need to use intval($value) is that when you need to use the specified base for the conversion (the default is base 10). intval accepts a second parameter for the base for the conversion.

Type casting for user defined objects

There is no need to type cast in php.


Edit: Since this topic seems to cause some confusion, I thought I'd elaborate a little.

In languages such as Java, there are two things that may carry type. The compiler has a notion about type, and the run time has another idea about types. The compilers types are tied to variables, whereas the run time engine tracks the type of values (Which are assigned to variables). The variable types are known at compile time, whereas the value types are only known at run time.

If a piece of input code violates the compilers type system, the compiler will barf and halt compilation. In other words, it's impossible to compile a piece of code that violates the static type system. This catches a certain class of errors. For example, take the following piece of (simplified) Java code:

class Alpha {}

class Beta extends Alpha {
public void sayHello() {
System.out.println("Hello");
}
}

If we now did this:

Alpha a = new Beta();

we would be fine, since Beta is a subclass of Alpha, and therefore a valid value for the variable a of type Alpha. However, if we proceed to do:

a.sayHello();

The compiler would give an error, since the method sayHello isn't a valid method for Alpha - Regardless that we know that a is actually a Beta.

Enter type casting:

((Beta) a).sayHello();

Here we tell the compiler that the variable a should - in this case - be treated as a Beta. This is known as type casting. This loophole is very useful, because it allows polymorphism in the language, but obviously it is also a back door for all sorts of violations of the type system. In order to maintain some type safety, there are therefore some restrictions; You can only cast to types that are related. Eg. up or down a hierarchy. In other words, you wouldn't be able to cast to a completely unrelated class Charlie.

It's important to note that all this happens in the compiler - That is, it happens before the code even runs. Java can still get in to run time type errors. For example, if you did this:

class Alpha {}

class Beta extends Alpha {
public void sayHello() {
System.out.println("Hello");
}
}

class Charlie extends Alpha {}

Alpha a = new Charlie();
((Beta) a).sayHello();

The above code is valid for the compiler, but at run time, you'll get an exception, since the cast from Beta to Charlie is incompatible.

Meanwhile, back at the PHP-farm.

The following is valid to the PHP-compiler - It'll happily turn this into executable byte code, but you'll get a run time error:

class Alpha {}

class Beta extends Alpha {
function sayHello() {
print "Hello";
}
}
$a = new Alpha();
$a->sayHello();

This is because PHP variables don't have type. The compiler has no idea about what run time types are valid for a variable, so it doesn't try to enforce it. You don't specify the type explicitly as in Java either. There are type hints, yes, but these are simply run time contracts. The following is still valid:

// reuse the classes from above
function tellToSayHello(Alpha $a) {
$a->sayHello();
}
tellToSayHello(new Beta());

Even though PHP variables don't have types, the values still do. A particular interesting aspect of PHP, is that it is possible to change the type of a value. For example:

// The variable $foo holds a value with the type of string
$foo = "42";
echo gettype($foo); // Yields "string"
// Here we change the type from string -> integer
settype($foo, "integer");
echo gettype($foo); // Yields "integer"

This feature some times confused with type casting, but that is a misnomer. The type is still a property of the value, and the type-change happens in runtime - not at compile time.

The ability to change type is also quite limited in PHP. It is only possible to change type between simple types - not objects. Thus, it isn't possible to change the type from one class to another. You can create a new object and copy the state, but changing the type isn't possible. PHP is a bit of an outsider in this respect; Other similar languages treat classes as a much more dynamic concept than PHP does.

Another similar feature of PHP is that you can clone a value as a new type, like this:

// The variable $foo holds a value with the type of string
$foo = "42";
echo gettype($foo); // Yields "string"
// Here we change the type from string -> integer
$bar = (integer) $foo;
echo gettype($bar); // Yields "integer"

Syntactically this looks a lot like how a typecast is written in statically typed languages. It's therefore also often confused with type casting, even though it is still a runtime type-conversion.

To summarise: Type casting is an operation that changes the type of a variable (not the value). Since variables are without type in PHP, it is not only impossible to do, but a nonsensical thing to ask in the first place.

Php string cast vs strval function which should I use?

http://www.php.net/manual/en/language.types.string.php#language.types.string.casting

A value can be converted to a string using the (string) cast or the strval() function.

Looks the same to me.

type conversion with strict_types in PHP

It is possible to enable strict mode on a per-file basis. In strict mode, only a variable of exact type of the type declaration will be accepted, or a TypeError will be thrown. The only exception to this rule is that an integer may be given to a function expecting a float.

http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration.strict

It's allowed as a widening primitive conversion:

A widening primitive conversion does not lose information about the overall magnitude of a numeric value.

PHP Cast to my class

As I know, in PHP you can only cast to some types:

(int), (integer) - cast to integer
(bool), (boolean) - cast to boolean
(float), (double), (real) - cast to float (real deprecated in PHP 8.0)
(string) - cast to string
(binary) - cast to binary string (PHP 6)
(array) - cast to array
(object) - cast to object
(unset) - cast to NULL (PHP 5) (depracted in PHP 7.2) (removed in 8.0)

(see Type Casting)

Instead you could use instanceof to check of specific type:

if($yourvar instanceof YourClass) {
//DO something
} else {
throw new Exception('Var is not of type YourClass');
}

EDIT

As mentioned by Szabolcs Páll in his answer, it is also possible to declare a return type or parameter type, but in that cases an exception (TypeError) will be throwen, if the type does not match.

function test(): string
{
return 'test';
}

function test(string $test){
return "test" . $test;
}

Since PHP 7.2 it is also possible to make the types nullable by adding ? in front of them:

function test(): ?string
{
return null;
}

Can you Force Type Casting in PHP?

PHP is loosely typed and does not require you to declare a variable type when declaring a variable. You can’t change that behavior with a magic php.ini directive.

The benefit of having “loose typing” is that it allows for flexibility. It allows you to create dynamic applications without having to worry about the type of the variable – PHP makes this possible by not enforcing variable types.

However, if you must convert a variable into a particular format, just cast it:

$int   = (int) $foo;
$str = (string) $foo;
$bool = (bool) $foo;
$float = (float) $foo;
...

There are functions to do the same, e.g. intval(), strval(), boolval() – all of them do the same task, but a function is very useful when you want to use it as a callback to another function.



Related Topics



Leave a reply



Submit