PHP变量类型

类函数但不是函数的PHP内嵌机制:array(), echo, empty(), eval(), exit(), isset(), list(), print, unset()

传递给echo多个参数,参数一定不能用括号包围。但是结尾的分号和参数之间的逗号是必须的。echo不会输出false和null等一些特殊值,因为它们转化为字符串时都是空字符串。

标量类型:boolean、integer、float、string,复杂类型array、object、callable,特殊类型resource、NULL。在PHP中,int和long统一为整型,float和double统一为浮点型。

boolean类型值为True和False。当操作符、函数、控制结构需要boolean类型时,会自动将其它类型转化为boolean类型。使用(bool)val,(boolean)val强转。当转化为bool类型时,下列被认定为False: 数字0,空字符串或者数字字符串”0”,没有元素的数组,NULL值,未初始化的变量。不要将布尔值转化为任何其它类型。

integer类型值可以指定为十进制、八进制、十六进制、二进制。8进制需要前导0,16进制需要前导0x,2进制需要前导0b。

可以通过PHP_INT_SIZE和PHP_INT_MAX,PHP_INT_MIN了解,int类型在运行系统中的大小。当一个数字超出了integer的范围,会自动转为float类型。在PHP中没有整数除法,只有浮点数除法。转化为整数类型可以使用(int)、(integer)、intval()函数转化。当数字超出了整型的范围,而试图将一个float型数字转为int型,返回值是未定义的。根本原因在于PHP的变量是动态类型的。

浮点数存在精度不准确的情况。最好不要直接对浮点数进行等性比较,最好使用bccmp进行比较。准确精度的浮点数计算可用bc数学函数。使用(float), (double), (real)进行强转。使用is_nan比较一个数字是不是NAN。

单引号字符串不会展开变量也不会转义字符序列,除了\和\’。在双引号中,会展开变量和转义字符序列,转义序列包括\$并且字符内部表示形式\ddd是八进制的,\xdd是16进制的。如果trim()的参数是不存在的变量或者是NULL将返回空字符串。

展开变量时可以使用$var和{$var}。{$var}用于复杂表达式,括号内的表达式需要与在字符串外一致,如{$arr[4][3]},{$arr[‘foo’][3]}以及{$obj->values[3]->name}等。$var只用于简单的关联数组、对象属性。

双引号字符串中不能使用{$arr[foo][3]},foo没有单引号。{}外部必须$juices[koolaid1]而不能表示成$juices[‘koolaid1’]。

在双引号字符串中,括弧还有另外一种形式${var},${var}只能用于单独变量和单独数组元素,其它情况不能使用,如$great/{$great}/${great}的含义是一样的,${juices[1]}/$juices[1]/{$juices[1]}是一样的。{$juices[‘orange’][1]}不能表示成${juices[‘orange’][1]}。

在双引号字符串中,还存在一种{${}}的形式,用于获取函数{${get_name()}}、类方法{${$object->getName()}}、类常量值{${beers::softdrink}}、类静态字段{${beers::$ale}}。{${$var}}首先解析$var的值,然后以$var的值为变量名,取得最后的值。双引号字符串中无法直接获取函数、类方法返回值或者类的常量值和类静态字段值。过于复杂的变量展开不应该使用。

PHP中多行字符串不要使用,语法格式过于复杂。PHP的字符串是可以改变的,可以像数组一样访问和修改字符串中的字符,下标从0开始。PHP使用点号(.)来实现字符串拼接。字符串有非常多函数:字符串函数表POSIX正则表达式URL函数等。

将其它类型转化为string类型,可以使用 (string)强转、strval()函数或者settype()函数。只应该在数字和字符串之间进行有效转换。

要获取字符串的ASCII码,可以使用ord()函数,用ASCII码获取字符使用chr()。

字符串的编码跟代码文件的编码是一致的,但必须是ASCII的兼容超集。字符串的比较是值比较的,也就是说内容相同的字符串是等价的,而不需要是引用同一个变量。字符串实现为字节数组,因而可以包含任何数据,包括NUL字节。

关联数组是有序映射。key必须是整数或者字符串,而值可以是任何类型。没有指定键的值,在最大的整数索引的递增1继续使用整数键。PHP的数组索引从0开始。可以使用array(key=>value,…)和[key=>value,…]来构建关联数组。索引数组:$array = array("foo", "bar", "hallo", "world”);

数字字符串作为键会转换为整数存储。不要将索引数组和关联数组混合使用。以字符串为键时一定要加上引号,如:$foo[“arr”]; array(“foo”=>”bar”); 不加引号是错误的做法。

从关联数组中删除一个元素(element)使用unset()方法。即便删除了元素,最大值递增1的起点也不会变,得用array_values()可以重新索引数组。使用array_diff()比较两个数组。

引用形式直接修改数组中的值

1
2
3
4
5
6
7
8
foreach ($colors as &$color) {
    $color = strtoupper($color);
}
unset($color);  // 一定要unset此变量,不然后面有可能改变数组的最后一个元素

foreach ($colors as $key => $color) {
    $colors[$key] = strtoupper($color);
}

以上两种形式是一样的。数组的赋值是值拷贝(value-copying),使用引用操作符(&)可以按引用赋值数组。如下代码:

1
2
3
4
5
6
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 is changed,
             // $arr1 is still array(2, 3)
$arr3 = &$arr1;
$arr3[] = 4; // now $arr1 and $arr3 are the same

以下被视为null值 - 被赋值为NULL的变量,没有初始化的变量,被unset的变量。NULL值本身不区分大小写的。

callback或称为callable就是Lua中的function对象,函数可以作为值来传递,因此PHP能够支持函数式编程。PHP函数通过名字进行传递,不论是PHP定义好的标准函数还是用户自定义的函数,除了PHP类似函数但不是函数的内嵌机制不能作为callback。object的实例方法是需要使用数组传递,数组的索引0位置是对象本身,索引1位置是函数名。静态方法可以将类名而不是对象本身放在数组的索引为0的位置进行传递。也可以使用ClassName::methodName进行传递。如下代码演示了callback的基本用法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
function my_callback_function() {
     echo 'hello world!';
}
class MyClass {
     static function myCallbackMethod() {
          echo 'Hello World!';
     }
}
call_user_func( 'my_callback_function' );
call_user_func( array('MyClass', 'myCallbackMethod') );
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));
call_user_func('MyClass::myCallbackMethod');

PHP还提供了闭包形式的回调,将函数定义赋值给一个变量就是闭包,或者一个匿名函数也是闭包。

1
2
3
4
5
6
7
8
$callback = function () {
    echo "callback achieved";
};
call_user_func($callback);

usort($array, function($a, $b) {
    return strlen($a) - strlen($b);
});