For a Cast to a User Defined Object you can define a cast method:
class MyObject {
/**
* @param MyObject $object
* @return MyObject
*/
static public function cast(MyObject $object) {
return $object;
}
}
In your php page code you can:
$myObject = MyObject::cast($_SESSION["myObject"]);
Then, PHP will validate the value and your IDE will help you.
Type Juggling
Η PHP δεν απαιτεί (ή υποστηρίζει) σαφή δήλωση τύπων κατά τη δήλωση μεταβλητών. Ένας τύπος μεταβλητής καθορίζεται από το περιεχόμενο με το οποίο αυτή η μεταβλητή θα χρησιμοποιηθεί. Δηλαδή, αν ορίσετε μια τιμή string σε μια μεταβλητή $var , η $var γίνεται string. Αν στη συνέχεια αναθέσετε μια integer τιμή στη $var , τότε γίνεται integer.
Ένα παράδειγμα της αυτόματης μετατροπής τύπου στην PHP είναι ο τελεστής πρόσθεσης '+'. Αν οποιοσδήποτε από τα τελούμενα είναι float, τότε όλα υπολογίζονται ως floats, και το αποτέλεσμα θα είναι float. Διαφορετικά, τα τελούμενα θα ερμηνεύονται ως integers, και το αποτέλεσμα θα είναι επίσης integer. Σημειώστε ότι αυτό ΔΕΝ αλλάζει τους τύπους των ίδιων των τελούμενων. Η μόνη αλλαγή είναι στο πώς υπολογίζονται τα τελούμενα.
<?php
$foo = "0"; // $foo is string (ASCII 48)
$foo += 2; // $foo is now an integer (2)
$foo = $foo + 1.3; // $foo is now a float (3.3)
$foo = 5 + "10 Little Piggies"; // $foo is integer (15)
$foo = 5 + "10 Small Pigs"; // $foo is integer (15)
?>
Αν τα τελευταία δυο παραδείγματα σας φάνηκαν περίεργα, δείτε το Μετατροπή του String σε number.
Αν επιθυμείτε να αναγκάσετε μια μεταβλητή να υπολογιστεί σαν να ήταν ενός συγκεκριμένου τύπου, δείτε το τμήμα σχετικά με Type casting. Αν επιθυμείτε να αλλάξετε τον τύπο μιας μεταβλητής, δείτε το settype().
Αν θέλετε να ελέγξετε οποιοδήποτε από αυτά τα παραδείγματα σ'αυτό το τμήμα, μπορείτε να χρησιμοποιήσετε τη συνάρτηση var_dump().
Note: Η συμπεριφορά μιας αυτόματης μετατροπής σε array είναι προς το παρόν απροσδιόριστη.
<?php
$a = "1"; // $a is a string
$a[0] = "f"; // What about string offsets? What happens?
?>
Αφού η PHP (για ιστορικούς λόγους) υποστηρίζει indexing σε strings μέσω offsets χρησιμοποιώντας την ίδια σύνταξη όπως και στο indexing των arrays, το παράδειγμα παραπάνω οδηγεί σε ένα πρόβλημα: θα πρέπει το $a να γίνει array με το πρώτο στοιχείο του να είναι το "f", ή θα πρέπει το "f" να γίνει ο πρώτος χαρακτήρας του string $a?
Οι τρέχουσες εκδόσεις της PHP μεταγλωττίζουν τη δεύτερη ανάθεση ως string offset πιστοποίηση, συνεπώς η $a γίνεται "f", το αποτέλεσμα όμως αυτής της αυτόματης μετατροπής θα πρέπει να θεωρηθεί απροσδιόριστο. Η PHP 4 εισήγαγε τη νέα σύνταξη χρηιμοποιώντας curly bracket για να αποκτήσει πρόσβαση σε χαρακτήρες ενός string, συνεπώς χρησιμοποιήστε αυτή τη σύνταξη αντί αυτής που παρουσιάστηκε παραπάνω:Δείτε το τμήμα με τίτλο Πρόσβαση των String με χαρακτήρες για περισσότερες πληροφορίες.<?php
$a = "abc"; // $a is a string
$a{1} = "f"; // $a is now "afc"
?>
Type Casting
Η μετατροπή τύπων (ή Type casting) στην PHP δουλεύει σχεδόν όπωε και στη C: το όνομα του επιθυμητού τύπου γράφετε σε παρενθέσεις πριν από τη μεταβλητή στην οποία θα γίνει το cast.
<?php
$foo = 10; // $foo is an integer
$bar = (boolean) $foo; // $bar is a boolean
?>
Τα επιτρεπόμενα casts είναι τα:
- (int), (integer) - cast σε integer
- (bool), (boolean) - cast σε boolean
- (float), (double), (real) - cast σε float
- (string) - cast σε string
- (array) - cast σε array
- (object) - cast σε object
Σημειώστε ότι τα tabs και τα spaces επιτρέπονται μέσα στις παρενθέσεις, συνεπώς τα ακόλουθα είναι εξίσου λειτουργικά:
<?php
$foo = (int) $bar;
$foo = ( int ) $bar;
?>
Note: Αντί να κάνουμε cast μιας μεταβλητής σε string, μπορείτε επίσης να κλείσετε τη μεταβλητή σε διπλά εισαγωγικά.
<?php
$foo = 10; // $foo is an integer
$str = "$foo"; // $str is a string
$fst = (string) $foo; // $fst is also a string
// This prints out that "they are the same"
if ($fst === $str) {
echo "they are the same";
}
?>
Ίσως δεν είναι ακριβώς προφανές τι θα συμβεί όταν γίνεται casting μεταξύ συγκεκριμένων τύπων. Για περισσότερες πληροφορίες, δείτε αυτά τα τμήματα:
Type Juggling
20-Jun-2008 03:43
20-Feb-2006 05:26
If you want to convert a string automatically to float or integer (e.g. "0.234" to float and "123" to int), simply add 0 to the string - PHP will do the rest.
e.g.
$val = 0 + "1.234";
(type of $val is float now)
$val = 0 + "123";
(type of $val is integer now)
If you have a boolean, performing increments on it won't do anything despite it being 1. This is a case where you have to use a cast.
<html>
<body> <!-- don't want w3.org to get mad... -->
<?php
$bar = TRUE;
?>
I have <?=$bar?> bar.
<?php
$bar++;
?>
I now have <?=$bar?> bar.
<?php
$bar = (int) $bar;
$bar++;
?>
I finally have <?=$bar?> bar.
</body>
</html>
That will print
I have 1 bar.
I now have 1 bar.
I finally have 2 bar.
09-Mar-2005 06:24
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:
function ClassTypeCast(&$obj,$class_type){
if(class_exists($class_type,true)){
$obj = unserialize(preg_replace"/^O:[0-9]+:\"[^\"]+\":/i",
"O:".strlen($class_type).":\"".$class_type."\":", serialize($obj)));
}
}
10-Feb-2005 03:05
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):
$dividend = 2;
$divisor = 3;
$quotient = $dividend/$divisor;
print $quotient; // 0.66666666666667
24-Aug-2004 01:27
function strhex($string)
{
$hex="";
for ($i=0;$i<strlen($string);$i++)
$hex.=dechex(ord($string[$i]));
return $hex;
}
function hexstr($hex)
{
$string="";
for ($i=0;$i<strlen($hex)-1;$i+=2)
$string.=chr(hexdec($hex[$i].$hex[$i+1]));
return $string;
}
to convert hex to str and vice versa
10-Mar-2004 07:02
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:
<?php
function typecast($old_object, $new_classname) {
if(class_exists($new_classname)) {
$old_serialized_object = serialize($old_object);
$old_object_name_length = strlen(get_class($old_object));
$subtring_offset = $old_object_name_length + strlen($old_object_name_length) + 6;
$new_serialized_object = 'O:' . strlen($new_classname) . ':"' . $new_classname . '":';
$new_serialized_object .= substr($old_serialized_object, $subtring_offset);
return unserialize($new_serialized_object);
} else {
return false;
}
}
?>
27-Feb-2004 07:08
Re: the typecasting between classes post below... fantastic, but slightly flawed. Any class name longer than 9 characters becomes a problem... SO here's a simple fix:
function typecast($old_object, $new_classname) {
if(class_exists($new_classname)) {
// Example serialized object segment
// O:5:"field":9:{s:5:... <--- Class: Field
$old_serialized_prefix = "O:".strlen(get_class($old_object));
$old_serialized_prefix .= ":\"".get_class($old_object)."\":";
$old_serialized_object = serialize($old_object);
$new_serialized_object = 'O:'.strlen($new_classname).':"'.$new_classname . '":';
$new_serialized_object .= substr($old_serialized_object,strlen($old_serialized_prefix));
return unserialize($new_serialized_object);
}
else
return false;
}
Thanks for the previous code. Set me in the right direction to solving my typecasting problem. ;)
03-May-2003 09:37
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.
function typecast($old_object, $new_classname) {
if(class_exists($new_classname)) {
$old_serialized_object = serialize($old_object);
$new_serialized_object = 'O:' . strlen($new_classname) . ':"' . $new_classname . '":' .
substr($old_serialized_object, $old_serialized_object[2] + 7);
return unserialize($new_serialized_object);
}
else
return false;
}
Example:
class A {
var $secret;
function A($secret) {$this->secret = $secret;}
function output() {echo("Secret class A: " . $this->secret);}
}
class B extends A {
var $secret;
function output() {echo("Secret class B: " . strrev($this->secret));}
}
$a = new A("Paranoia");
$b = typecast($a, "B");
$a->output();
$b->output();
echo("Classname \$a: " . get_class($a) . "Classname \$b: " . get_class($b));
Output of the example code above:
Secret class A: Paranoia
Secret class B: aionaraP
Classname $a: a
Classname $b: b
27-Nov-2002 01:24
incremental operator ("++") doesn't make type conversion from boolean to int, and if an variable is boolean and equals TRUE than after ++ operation it remains as TRUE, so:
$a = TRUE;
echo ($a++).$a; // prints "11"
Printing or echoing a FALSE boolean value or a NULL value results in an empty string:
(string)TRUE //returns "1"
(string)FALSE //returns ""
echo TRUE; //prints "1"
echo FALSE; //prints nothing!
