问题
why this is not possible:
$user = (User) $u[0];
but this is possible
$bool = (boolean) $res['success'];
I use PHP 7.0.
回答1:
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
(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) (marked for remove 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');
}
回答2:
If you just want to ensure a variable is instance of YourClass and let exception handling to the typesystem you can use the following function:
function implicitFakeCast($myClass): YourClass
{
return $myClass;
}
Note: this will not actually do any casting, rather it throws exceptions in case of class mismatch and lets intellisense treat it as an instance of the target class.
回答3:
For people that do want to be able to cast to a class type. I've found a gist by @borzilleri that uses serialize and unserialize to achieve this: https://gist.github.com/borzilleri/960035.
TL;DR:
// make sure to include the namespace when casting
$className = "Some\\NameSpace\\SomeClassName";
$classNameLength = strlen( $className );
$castedItem = unserialize(
preg_replace(
'/^O:\d+:"[^"]++"/',
"O:$classNameLength:\"$className\"",
serialize( $item )
)
)
回答4:
In addition to the answer on why this is not possible, I would suggest that you write a builder function that creates an object, based on your input. so it would look something like
$user = User::buildFromSomeArrayInput($u[0]);
And then have a builder create a new User
object, assign the right properties, etc. You could just do all this in-place of course, but having a builder function makes sure you won't be doing this on several locations, AND you can set private properties as it is a class-member function. It is a bit more work then having it magically work, but not that much.
The only issue you might have is when you do have a different object that does not expose all the internals you might need. But this is for a reason, as internals might change -> you don't want to rely on that.
There are hacks out there that suggest doing this with serialization. I would suggest to steer away from them, as they are hackish and as far as i'm concerned, not very clear.
回答5:
Objects and primitive types are different. Since it's called as primitive types, they are really simple, maybe only 1 byte, 2 bytes, or 4 bytes, and at most 8 bytes.
When we are talking about object, this object can have different attributes with the others. Then the question from PHP will be is, "is this object really from my Class?" "How to convert this object to my Class?". Thus, you can't parse right away the object using
$myObject = (ClassName) $variable
Then how to cast it? Dunno, but usually the approach is like this:
- Create constructor for the class
- In the class, make a method that specifically accept certain parameters, maybe array
here is sample:
public class MyAwesomeClass{
function __construct($thisIsArray){
$this->attributeA = $thisIsArray["A"];
$this->attributeB = $thisIsArray["B"];
......
}
static function fromArray($thisIsArray){
return MyAwesomeClass($thisIsArray);
}
}
$obj = MyAwesomeClass::fromArray($attributes);
回答6:
The reason is that "false" is a string and its true. But false is a boolean.
$res['success'] = "false"|;
if ($res['success']) { // returns true
// this cose will be executed
}
Another example here: echo "false" == true ? 111 : 222;
that prints 111.
And again, ... "42" is a string while 42 is a number.
You can always check boolean value of a variable content.
"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."
Another example from documentation:
<?php
$foo = 10; // $foo is an integer
$bar = (boolean) $foo; // $bar is a boolean
?>
Take a look the type comparison tables.
回答7:
PHP supports two types of casting.
- Implicit Casting
- Explicit Casting
Implicit Casting is done by PHP. For instance, when dividing two integers (5/2), the result will be float (2.5). This conversion is done by PHP.
Explicit Casting can be by us (programmer). As in your question, you can use () to cast to a new data type. But, everything does not work in this way. Sometimes this can lead to data loss (casting a float (2.52) to an integer will drop the decimal value which can be useful). Casting to objects can be risky, as different objects behave in different ways.
Learn More about Type Casting
So, if you are thinking of casting to an object, use an object constructor.
$user = new User($u[0]);
The user class should be something like this.
class User {
public function __construct($user) {
$this -> user = $user;
}
}
In this way, you can create your own object to manipulate user-related data and more.
来源:https://stackoverflow.com/questions/42623498/php-cast-to-my-class