PHP手册之类型转换的判别

前言

PHP手册系列文章,会挑选一些手册中有意思的评论进行翻译
手册目录: 语言参考---类型---类型转换的判别
参考详情

评论

  1. 两个整数想除得到的可能是通过自动转换后的float类型结果,所以你不需要通过整数加浮点数来避免结果截断取整
$dividend = 2;
$divisor = 3;
$quotient = $dividend/$divisor;
print $quotient; // 0.66666666666667
  1. 将对象类型转换为数组类型永远是心里的痛
class MyClass {
    private $priv = 'priv_value';
    protected $prot = 'prot_value';
    public $pub = 'pub_value';
    public $MyClasspriv ='second_pub_value';
}

$test = new MyClass();
echo '<pre>';
print_r((array) $test);

/* 输出
Array
(
    [MyClasspriv] => priv_value
    [*prot] => prot_value
    [pub] => pub_value
    [MyClasspriv] => second_pub_value
)
*/

结果看上去很正常,对象属性转换为关联数组,key是属性,value是值,并且通过在key前面添加*来标示其在对象中是protected的访问等级,但是事实远非如此

foreach ((array) $test as $key =>$value) {
    $len = strlen($key);
    echo "{$key} ({$len}) => {$value}<br />";
    for ($i = 0;$i< $len; ++$i) {
        echo ord($key[$i]) .' ';
    }
    echo '<hr />';
}

/*输出
MyClasspriv (13) => priv_value
0 77 121 67 108 97 115 115 0 112 114 105 118
*prot (7) => prot_value
0 42 0 112 114 111 116
pub (3) => pub_value
112 117 98
MyClasspriv (11) => second_pub_value
77 121 67 108 97 115 115 112 114 105 118
*/

输出的字符码显示 protected属性转变成key的时候会添加'\0*\0',同时private属性转变成key的时候会添加'\0'._CLASS.'\0'

  1. ++操作符不会将boolean类型转换程int类型,并且如果一个变量是boolean,值为true,那么对其++之后它还是true
$a = true; 
var_dump(++$a);  // 输出 bool(true)

4.object 转换到 object是可以的,通过serialize/unserialize操作,详情见序列化

class my{
    public $m = 1;
    public function test(){
        echo 'he';
    }
}


class yo{
    public $mi = 2;
    public function testi(){
        echo 'hehe';
    }
}

$b = new my();
$a = serialize($b);
echo $a;  //输出O:2:"my":1:{s:1:"m";i:1;},其中O表示object,O后面的2表示类名的长度,"my"表示类名,1表示变量个数(包括public,protected,private),s:1:"m"依次表示变量,变量名长度,变量名.所以我们要转换成别的类,不仅要替换掉类名,同时也需要替换掉类名长度
$c = unserialize($a); 

if($c == $b) echo 'succ'; //输出succ,说明$c和$b是同一个类的实例,并且属性值都相等,注意$b!==$c

$a = str_replace('my','yo',$a); //新类名长度与旧类名长度一致,所以只需要替换类名部分
echo $a;  //输出O:2:"yo":1:{s:1:"m";i:1;}
$d = unserialize($a); //新类产生

if($d instanceof yo)echo 'succ' //输出succ,是yo类的实例

echo $d->m; //1

echo $d->mi; //2

echo $d->test(); //error:undefined method

echo $d->testi(); //hehe   //如此可以知道转换后的类居然保存有旧类的变量属性,但是不具备旧类的方法属性,很神奇有木有,其实可以手动修改串O:2:"yo":1:{s:1:"m";i:1;},想添加什么变量都可以,但是注意protected的变量转变成字符串之后会添加'\0*\0',具体见上面的class转换成array

思考:那么旧类中的private和protected变量会不会也传递给新类呢,访问限制等级是否会发生变化呢,如果旧类中的变量的初始值是另外一个类的实例又会怎样,如果旧类extends其他类或者implements其他接口又会是怎样,这个可以自己去实验,不再一一赘述

  1. 一些更短更快的方法进行类型转换
$string='12345.678';
$float=+$string;
$integer=0|$string;
$boolean=!!$string;
  1. 你应该意识到不要在对某个目标连续进行太多次类型转换,因为这样很可能意外的将false变成true
if(TRUE === (boolean) (array) (int) FALSE) {
    echo 'ca';
}  // (boolean)array(0) 变成 true了
  1. 从string转换到int或者从int转换到string是最常见的,php可以通过+.和.=来转换
$x = 1;
var_dump($x);// int(1)
$x .= 1;
var_dump($x);// string(2) "11"; also an empty string ("") would cast to string without changing $x

$x = "1";
var_dump($x); // string(1) "1"
$x += 1;
var_dump($x);// int(2); also a zero value (0) would cast to int without changing $x
  1. 提出一段很有意思的代码
$obj = new stdClass();
$obj->{'4'} = 'id';
$arr = (array) $obj;
var_dump($arr);
foreach ($arr as $key => $value) {
   var_dump($key);
    var_dump($arr[$key]);
}
?>

/*
输出:
array(1) {
  ["4"]=>
  string(2) "id"
}
string(1) "4"
string(2) "id"
NULL
*/

发现怎么都读取不到$arr[$key],应该输出$value的值,并且通过array()构造$arr怎么都构造不出下面这个数组

array(1) {
  ["4"]=>
  string(2) "id"
}

希望高手能解释下这个问题

  1. unset看起来好像用处比较单一,但是如果你想把代码变得紧凑,你可以在同一行使用变量并且unset它
$hello = 'Hello world';
$hello = (unset) print $hello;
// 等同于
$hello = 'Hello world';
print $hello;
unset($hello);
  1. 仅仅是一些关于unset的经验之谈
$var = 1;
$var_unset = (unset) $var;
$var_ref_unset &= (unset)$var;   //把与&换成或|结果也一样
var_dump($var);
var_dump($var_unset);
var_dump($var_ref_unset);

output:
int(1)
NULL
int(0)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容