php学习记录

本文详细介绍了PHP中array_multisort函数的使用误区,浮点数运算精度问题,资源类型特性,以及变量类型动态转换。通过实例和技巧探讨了如何正确处理数组排序和数值比较。

1:array_multisort排序多个一维数组,直接上案例:

$ar1 = array(10, 100, 100, 0);

$ar2 = array(1, 3, 2, 4);

array_multisort($ar1, $ar2);



var_dump($ar1);

var_dump($ar2);

这个例子里,排序后,第一个数组会包含 0、 10、 100、 100。 第二个数组会包含 4、1、 2、 3。 第二个数组里的项目对应第一个数组后也进行了排序(100 和 100)。

array(4) { [0]=> int(0) [1]=> int(10) [2]=> int(100) [3]=> int(100) } array(4) { [0]=> int(4) [1]=> int(1) [2]=> int(2) [3]=> int(3) }

按道理说$ar2经过排序后应该是1、2、3、4的顺序,但结果完全不一样。

我理解的原因:第一个数组会正常排序,后面的数组就以key和前一个数组关联,然后排序,

如$ar2的4的key是3,对应的$ar1的key为3的值是0,因为$ar1的0经过排序后在第一位,所以$ar2的4也排在了第一位,

以此类推。

2: php浮点数运算比较

$a = 0.1;

$b = 0.9;

$c = 1;

var_dump(($a+$b) == $c);//true

var_dump(($c-$b) == $a);//false

出现这个问题是因为浮点数计算涉及精度,当浮点数转为二进制时有可能会造成精度丢失。

所以永远不要相信浮点数已精确到最后一位,也永远不要比较两个浮点数是否相等。

正确比较浮点数的方法:

a:使用round方法处理后在比较

var_dump(round(($c-$b),1)==round($a,1));//true

b: 使用高精度函数比较

var_dump(bccomp(($c-$b),$a));//true

3:resource(资源)类型:resource是一种特殊变量,保存了到外部资源的一种引用,资源是通过专门的函数建立的。由于资源类型变量保存有为打开文件、数据库连接、图形画布区域等的特殊句柄,因此将其它类型的值转换为资源没有意义。

4:变量的类型通常不是由程序员设定的,是由php根据该变量使用的上下文在运行时决定的。整型数 int 的字长和平台有关。如果给定的一个数超出了 int 的范围,将会被解释为 float。同样如果执行的运算结果超出了 int 范围,也会返回 float。

一个字符串可以用4种方式表达:

a:单引号

b:双引号

c:heredoc语法结构

d:nowdoc语法结构

不像双引号和 heredoc 语法结构,在单引号字符串中的变量和特殊字符的转义序列将不会被替换。

用双引号定义的字符串最重要的特征是变量会被解析。

第三种表达字符串的方法是用 heredoc 句法结构(类似于双引号字符串):<<<。在该运算符之后要提供一个标识符,然后换行。接下来是字符串 string 本身,最后要用前面定义的标识符作为结束标志。

$str = <<<EOD

Example of string

spanning multiple lines

using heredoc syntax.

EOD;

就象 heredoc 结构类似于双引号字符串,Nowdoc 结构是类似于单引号字符串的。Nowdoc 结构很象 heredoc 结构,但是 nowdoc 中不进行解析操作。

变量解析:

当字符串用双引号或 heredoc 结构定义时,其中的变量将会被解析。

这里共有两种语法规则:一种简单规则,一种复杂规则。简单的语法规则是最常用和最方便的,它可以用最少的代码在一个 string 中嵌入一个变量,一个 array 的值,或一个 object 的属性。

复杂规则语法的显著标记是用花括号包围的表达式。

简单语法:

当 PHP 解析器遇到一个美元符号($)时,它会和其它很多解析器一样,去组合尽量多的标识以形成一个合法的变量名。可以用花括号来明确变量名的界线。

复杂(花括号)语法

复杂语法不是因为其语法复杂而得名,而是因为它可以使用复杂的表达式。

任何具有 string 表达的标量变量,数组单元或对象属性都可使用此语法。 表达式的书写方式与在 string 以外的方式相同, 然后用花括号 { 和 } 把它括起来即可。由于 { 无法被转义,只有 $ 紧挨着 { 时才会被识别。可以用 {\$ 来表达 {$。

函数、方法、静态类变量和类常量可使用 {$} ,在该字符串被定义的命名空间中将其值作为变量名来访问。只单一使用花括号 ({}) 无法处理从函数或方法的返回值或者类常量以及类静态变量的值。

class beers {

    const softdrink = 'rootbeer';

    public static $ale = 'ipa';

}



$rootbeer = 'A & W';

$ipa = 'Alexander Keith\'s';



// 有效,输出: I'd like an A & W

echo "I'd like an {${beers::softdrink}}\n";



// 也有效,输出: I'd like an Alexander Keith's

echo "I'd like an {${beers::$ale}}\n";

字符串运算符:

有两个字符串(string)运算符。第一个是连接运算符(“.”),它返回其左右参数连接后的字符串。第二个是连接赋值运算符(“.=”),它将右边参数附加到左边的参数之后。

$a = "Hello ";

$b = $a . "World!"; // 现在 $b 包含 "Hello World!"



$a = "Hello ";

$a .= "World!";     // 现在 $a 包含 "Hello World!"

数字字符串:

如果一个 PHP string 可以被解释为 int 或 float 类型,则它被视为数字字符串。

数组的key 可以是 integer 或者 string。value 可以是任意类型。

此外key会有如下的强制类型转换:

  • String 中包含有效的十进制 int,除非数字前面有一个 + 号,否则将被转换为 int 类型。例如键名 "8" 实际会被储存为 8。另外, "08" 不会被强制转换,因为它不是一个有效的十进制整数。
  • Float 也会被转换为 int ,意味着其小数部分会被舍去。例如键名 8.7 实际会被储存为 8。
  • Bool 也会被转换成 int。即键名 true 实际会被储存为 1 而键名 false 会被储存为 0。
  • Null 会被转换为空字符串,即键名 null 实际会被储存为 ""。
  • Array 和 object 不能 被用为键名。坚持这么做会导致警告:Illegal offset type。

key 为可选项。如果未指定,PHP 将自动使用之前用过的最大 int 键名加上 1 作为新的键名。

unset() 函数允许删除 array 中的某个键。但要注意数组将不会重建索引。如果需要删除后重建索引,可以用 array_values() 函数重建 array 索引。

为什么 $foo[bar] 错了? ¶

应该始终在用字符串表示的数组索引上加上引号。例如用 $foo['bar'] 而不是 $foo[bar]。但是为什么呢?可能在老的脚本中见过如下语法:

<?php

$foo[bar] = 'enemy';

echo $foo[bar];

// 及其它

?>

这样是错的,但可以正常运行。那么为什么错了呢?原因是此代码中有一个未定义的常量( bar )而不是 string('bar'-注意引号)。而 PHP 可能会在以后定义此常量,不幸的是你的代码中有同样的名字。它能运行,是因为 PHP 自动将裸字符串(没有引号的 string 且不对应于任何已知符号)转换成一个其值为该裸 string 的 string。例如,如果没有常量定义为 bar,那么PHP 将在 string 中替代为 'bar' 并使用之。

var_dump(fruit);//fruit

$arr = array('fruit' => 'apple', 'veggie' => 'carrot');

var_dump($arr['fruit']); // apple

var_dump($arr['veggie']); // carrot

var_dump($arr[fruit]);//apple



define('fruit', 'veggie');



var_dump($arr['fruit']);//apple

var_dump($arr[fruit]);//carrot

对于任意 int,float, string,bool 和 resource 类型,如果将一个值转换为 array,将得到一个仅有一个元素的数组,其下标为 0,该元素即为此标量的值。换句话说,(array)$scalarValue 与 array($scalarValue) 完全一样。

如果将 object 类型转换为 array,则结果为一个数组,其单元为该对象的属性。键名将为成员变量名,不过有几点例外:整数属性不可访问; 私有变量前会加上类名作前缀;保护变量前会加上一个 '*' 做前缀。这些前缀的前后都各有一个 NUL 字节。

class Goods {

public $name = 'john';

protected $height = 180;

private $age = 18;

public function getName()

{

return $this->name;

}

private function getAge()

{

return $this->age;

}

}

$goods = new Goods();

$arr = (Array)$goods;

print_r($arr);

Array

(

[name] => john

[*height] => 180

[Goodsage] => 18

)



$age = 18;

$name = 'john';

print_r((Array)$age);

Array

(

[0] => 18

)

print_r((Array)$name);

Array

(

[0] => john

)

在下列情况下一个变量被认为是 null:

a:被赋值为null

b:尚未被赋值

c:被unset

null 类型只有一个值,就是不区分大小写的常量 null。

callback/callable类型:

回调可以通过 callable 类型声明来表示。

一些函数如 call_user_func() 或 usort() 可以接受用户自定义的回调函数作为参数。回调函数不止可以是简单函数,还可以是对象的方法,包括静态类方法。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值