php基础知识入门

PHP基础知识点整理

• 缩写:Personal Home Page ==>>PHP:HypeText Preprocessor

php基本语法形式

php的标记符
有以下形式:

形式1(推荐):


形式2:


形式3(不推荐):

它依赖于php.ini中的一个设置项:
short_open_tag = On

php的结束标记(比如 ?>  ),在如下情况可以省略:
php的语句之后,再没有了html代码部分



php的区分大小写特性
1,变量区分大小写;
2,常量通常默认也区分,但可以人为设定为不区分(但这种做法不推荐)
3,其他场合的关键字都不区分,比如函数名,系统关键字(for,if,return....)

一条语句使用一个分号结束
1, 在一个php的语句标记中的最后一个分号可省略
2,  php结束标记省略则不能省略最后一个分号

单行注释:
形式1: //注释内容
形式2: #注释内容

多行注释:
/*  注释内容,可以多行 */

2个多行注释的技巧:
有时候,我们因为测试或别的原因,需要将一大段代码多次进行“注释”或“反注释”;,则此时,可以使用如下2个技巧来方便实现:
技巧1:
反注释


  • 变量
基本理解
变量可以理解为只是一个代表一定存储空间及其中的数据的一个“标识符”——也就是一个名字。
$v1  =  1;


这表明,使用该变量,就是在使用该数据空间的数据值!比如:
echo  $v1;      ///输出的是数据1
$v2 = $v1 + 3;      //此时,其实进行的是1+3的计算!

使用形式:每个变量名前面必须以$开头。
定义形式:php中,不支持“单纯定义”一个变量,而是,在第一次一个变量赋值的时候,就算是定义变量!

变量的基本操作
只有4个操作:
赋值:
等号(=)的左边放变量名,右边放“数据”,就是赋值;
$v1 = 1;

取值:
任何需要一个数据的语句中使用一个变量,此时就是指从该变量取得该变量的值——取值;
概括来说,大约有如下情形:
echo  $v1;      //取出v1的值并输出
$v2  =  $v1;        //取出v1的值并给其他变量赋值;
$v2  =  $v1 + 3;    //取出v1的值并与3进行运算!
$v2  =   round( $v1 );      //取出v1的值并并使用函数round()对其进行四舍五入运算

判断isset(变量名):
作用:判断该变量是否存在,或该变量是否有数据值!存在或有数据值,就是true,否则就是false



删除unset(变量名):
含义:删除一个变量,并不是指将该变量从程序中删掉,而是,“断开”该变量名跟该变量原有的数据值之间的“引用关系”(联系)!,此时,会有这样的结果:
1,该变量名已经不指向(引用)任何数据了,则此时其isset()判断的结果就是false
2,该数据(可能)没有任何变量指向它了,就成为“无法使用的数据”——通常就被自动回收了



$v1 = 1;
unset($v1);
$s1 = isset($v1);       //false


变量命名规则
基本规则——保证程序的正确性
•   以字母或下划线开头
•   后跟任意数量(含0个)的字母,数字和下划线

行业规则——保证程序的可读性
有3种常见的命名法:
1,骆驼命名法:首单词小写,其后每个单词首字母大写
举例:$name   $myName   $myFatherName

2,帕斯卡命名法:每个单词首字母大写
举例:$Name   $MyName   $MyFatherName

3,下划线分割法:每个单词小写,并且之间用下划线分开
举例:$name   $my_name   $my_father_name

变量的传值方式
1,变量的传值方式,是指“一个变量,传给另一个变量”的内部细节形式——单对单;
2,变量的传值方式,只有2中:值传递,引用传递;
值传递
$v1 = 1;
$v2 = $v1;  //这就是值传递
简单理解:将$v1的值取出来(注意:$v1中的值还在),然后再用该值给$v2赋值。

可见,值传递,就是变量v1的值进行了复制,然后在给另一个变量v2赋值。
注意:
1这两个变量此时是值相等的;
2这两个变量又是互相独立的——互不影响;
即$v1 = 10;  则echo  $v2 ;//输出1


引用传递
php中,只有一种语法形式可以实现变量的引用传值方式:&符号。
举例如下:
$m1  =  1;
$m2  =  & $m1;      //引用传值方式
简单理解:   将变量$m1跟其数据值之间的“引用关系”,复制一份,再给予变量$m2,即,此时,变量$m2也同样具有跟原来数据的一个“引用关系”(指向关系);

结果是:
1,此时仍然有了2个变量,但只有一个数据值(数据空间),2个变量都共同指向该数据空间。
2,对其中任何一个变量的操作,其实都是在操作数据值(空间);

可变变量:
$s1 = “abc”;        //这是一个变量,里面存储的是字符串”abc”
$abc  =  10;        //
echo   $$s1;        //???,输出10
理解:
1,在php中,一个”$”后面,总是跟着一个变量名!
2,这里,echo输出的这个变量(以第一个$为标识)的名字是:$s1, 即”abc”
3,所以,这里输出的是 $abc,  即 10
4,这种连续出现“$”的变量形式,就是所谓的“可变变量”;

预定义变量
所谓预定义变量,其实指,php这个语言工具中,预先就定义好的变量;
我们只是“拿来使用”。
综述
•   主要有:$_GET, $_POST, $_REQUEST, $_SERVER, $GLOBALS,
•   均是数组
•   系统定义与维护——即我们不应该其给其赋值或销毁其值,只应该去“用其值”。
•   具有超全局作用域——哪里都可以使用。
•   不同情形下可能具有不同的值

$_POST变量
含义:
它代表用户通过表单以post方式( method=”post” )提交的时候所提交的所有数据——这个称为post数据。

isset(变量):判断变量是否存在,或变量是否为空(null);如果存在,就是true,否则就是false
empty(变量): 判断变量的“内容”是否为空的(不是null的空,而是没有内容),基本上,是一些硬性规定,如下数据都是“空的”: 0, “”,  “0”,  false,  null,   array()空数组也是空  
如果一个变量内容是空的,empty()返回的结果是true,否则是false


$_GET变量
含义:
它代表用户通过get方式( 有5种get形式 )提交的时候所提交的所有数据——这个称为get数据。
小提示:get,post没有翻译!

提交get数据有5种形式:

形式1:
这种形式的get数据,跟post数据类似,数据内容由用户填写或选择而得到! 形式2: 链接文字 说明: 1,它只是一个链接而已,只是在链接文件名的后面加上“?”,然后一个一个“串接数据”; 2,数据形式为:数据项名称=数据值, 相互之间用“&”符号隔开 3,这种形式的数据也同样是“点击链接”就提交的get数据,但用户只能选择点还是不点,而不能修改数据。 形式3: 说明: 1,该语句可以看做是通过js技术实现的页面跳转功能,跟a标签的连接功能完全一样! 2,其中该语句,通常都是放在一个函数中,然后因为某个事件发生而去调用该函数! 形式4: 说明: 该语句其实跟形式3完全一样功能,只是location这个对象实现页面跳转的另一个语法形式而已! 形式5:php的跳转语法 小结: 上述多种get形式提交数据,都要理解为: 跳转到某个页面,并“同时”携带(提交)一定的get数据过去! 不管哪种形式的get数据提交,接收get数据,都只有一种形式,跟post类似: $v1 = $_GET[‘数据项名称’]; //取得一个get数据项的值;比如$_GET[‘data1’], $_GET[“age”]; 也可以“输出”所有get数据: print_r($_GET); 或 var_dump($_GET); $_REQUEST变量 含义: 一句话,它是$_GET变量和$_POST变量数据的“合集”:即,它里面同时存储了这两种数据。 怎么能同时具有get和post数据呢? 只有一个方式:
request数据取值时,跟get数据和post也完全一样! $_REQUEST[‘数据项名称’]; 当post数据和get数据的数据项名称相同时(其实我们反对这么做),默认是post数据覆盖了get数据。 不过这个状况同样可以在php.ini中设置: request_order = "PG" $_SERVER变量 含义: 它代表在一次浏览网页的过程中的浏览器端的一些信息或服务器端的一些信息。 我们只是在程序中可以拿到这些信息,并用于编程所需!比如:取得用户的访问IP地址。 注意: 这种信息,随着不同的页面,和不同的服务器,以及不同的时刻,都可能不同! 要求: 大约有30个左右的信息,我们只要知道其中5个左右!主要有: $_SERVER[‘REMOTE_ADDR’]:获取访问者的ip地址 $_SERVER[‘SERVER_ADDR’]:获取服务器所在的ip地址 $_SERVER[‘SERVER_NAME’]:获取服务器的名字,其实就是站点设置中的servername $_SERVER[‘DOCUMENT_ROOT’]:获取站点的真实物理地址,其实就是站点设置中的documentroot $_SERVER[‘PHP_SELF’]:获取当前网页地址(不含域名部分) $_SERVER[‘SCRIPT_FILENAME’]:获取当前网页地址物理路径 $_SERVER[‘QUERY_STRING’]获取当前网页地址中的所有get数据(就是?号后面部分),但只是一个整体的字符串而已。 $GLOBALS变量 含义: 它也是一个“重复性数据”,它里面存储了我们自己定义的所有“全局变量”。 举例: $v1 = 1; //定义了一个全局变量, 此时,就有了这样一个数据:$GLOBALS[‘v1’],其值就是1 echo $v1 ; //输出1 echo $GLOBALS[‘v1’]; //输出1 这个变量,主要是用于在局部范围不可以使用全局变量的时候,又需要该全局变量的值,此时就可以用它来取得该全局变量的值
  • 常量
定义:
define("PI",3.1415);
define("DDD","dog");

const CONST1 = 1321;
const Const2 = "ddff";

取值:

直接使用名字,或通过constant()函数取得其值;

Pi  //3.1415;
constant("CONST1");  //1321


常量变量的区别
•   定义形式不同:
•   使用形式不同:常量无需$符号
•   可变程度不同:常量的值不可以改变,常量也不可以销毁
•   作用范围不同:常量具有超全局作用域 (函数内外都可以直接使用)
•   可用类型不同:常量只能存储标量类型(整数,浮点数,字符串,布尔)
判断常量是否存在
使用defined()函数:
如果存在:返回结果是true,
如果不存在:返回结果是false

先看2个对比代码:
echo  “v1的值为”  .  $v1;      //注意,该变量v1未定义过
echo  “C1的值为”  .  C1;           //注意,该常量C1未定义过

注意:在php中,当使用一个未定义的常量的时候,系统会直接将该常量当做“有值”的常量去使用,并且其值就是该常量名——虽然也会报错!


预定义常量
就是系统中预先定义好的一些常量,大约有几百个,我们只要知道几个就行:
M_PI:       就是圆周率的常量值;
PHP_OS:     就是php运行所在的操作系统
PHP_VERSION:就是php的版本号
PHP_INT_MAX: php中的最大的整数值
......更多可参考:php手册>附录>保留字列表>预定义常量


魔术常量
其实只是常量的形式,但没有常量的“恒常”的含义:其值其实会变化的,只有很少的几个:
__FILE__        :代表当前网页文件的完整物理路径
__DIR__         :代表当前网页文件所在的文件夹
__LINE__        :代表当前这个常量名所在的”行号”

  • 数据类型
总体划分
有8种数据类型:
基本类型(标量类型):
整数类型:       int, integer
浮点数类型:  float,double, real
字符串类型:  string
布尔类型:       bool,  boolean  这种类型,只有2个数据:true,false
复合类型:
数组: array
对象: object
特殊类型
空类型:    null            这种类型中,只有一个数据,那就是null
资源类型:   resource

整数类型
整数类型的4种写法:
$n1 = 123;      //10进制数字写法
$n2 = 0123;     //8进制数字写法,实际n2中存储的数字比123小
$n3 = 0x123;        //16进制数字写法,实际n3中存储的数字比123大
$n4 = 0b1010;       //2进制数字写法(目前不学)
 
进制转换问题
首先记住这几个单词:
bin:2进制
oct:8进制
dec:10进制
hex:16进制
进制转换主要分2种情况:
1,10进制转换为其他3种进制:decbin(), decoct(), dechex();
2,其他3种进制,转换为10进制:

进制转换的系统函数——必须会用
进制转换主要分2种情况:
1,10进制转换为其他3中进制:
decbin(一个10进制数字):   结果返回的是该数字的2进制数字形式的字符串
decoct(一个10进制数字):   结果返回的是该数字的8进制数字形式的字符串
dechex(一个10进制数字):   结果返回的是该数字的16进制数字形式的字符串

2,其他3种进制,转换为10进制:
bindec(一个2进制数字字符串): 结果返回的是该2进制数字字符串对应的10进制数字!!!
octdec(一个8进制数字字符串): 结果返回的是该8进制数字字符串对应的10进制数字!!!
hexdec(一个16进制数字字符串):    结果返回的是该16进制数字字符串对应的10进制数字!!!
对于输入的字符串中的字符,如果不是对应进制的数字,会被忽略。


$v1 = 0x123;        //它的实际大小其实是:291
$result = octdec( $v1 );    //结果为:17,怎么理解?推理如下:
1,octdec( $v1 ) 
2,octdec(291)   //因为$v1的实际值就是291
3,octdec(“291”);    //因为octdec()函数要求输入一个字符串,这属于自动转换
4,octdec(“21”); //因为octdec()函数要求输入一个8进制数字字符串,而9不是合法的数字,忽略掉
5,结果,8进制数字”21”转换为10进制就是就是17;

进制转换的人工计算——了解其原理
10进制转换为2进制:
做法:除2取余倒着写出所有余数,就是对应的2进制数字形式;
详细解释:将一个10进制数字除以2,得到商和余数,如果商还大于等于2,则继续除以2,继续得到商和余数,以此类推,直到商为0为止,然后将前面的所有余数按倒序写出来就是对应的2进制数字。


10进制转换为8进制:
做法:除8取余倒着写出所有余数,就是对应的8进制数字形式;
详细解释:将一个10进制数字除以8,得到商和余数,如果商还大于等于8,则继续除以8,继续得到商和余数,以此类推,直到商为0为止,然后将前面的所有余数按倒序写出来就是对应的8进制数字。


10进制转换为16进制:
做法:除16取余倒着写出所有余数,就是对应的16进制数字形式;
详细解释:将一个10进制数字除以16,得到商和余数,如果商还大于等于16,则继续除以16,继续得到商和余数,以此类推,直到商为0为止,然后将前面的所有余数按倒序写出来就是对应的16进制数字


其他进制转换为10进制的做法:

先看一种对数字大小和“数字权值”的理解:
对一个10进制数字: 1234,可以这样去理解它的大小:
1234 = 1*103 + 2*102 + 3*101 + 4*100  = 1000 + 200 + 30 + 4;        (任何数的0次方都是1)
这里,我们对103 ,  102,   101,  100  等等,称为“权值”;每个位的权值是不同的。
对于10进制,每个位上的权值,就是10 的 n次方;
对于8进制,每个位上的权值,就是8的 n次方;
对于16进制,每个位上的权值,就是16 的 n次方;
对于2进制,每个位上的权值,就是2 的 n次方;

8进制转换10进制:
将8进制数字的每个位上的数字乘以其对应位上的权值,然后相加之后的结果。
举例:有一个8进制数字123,则其实际大小为:
1 * 82  +  2 * 81 +  3 * 80  =  64 + 16 + 3 = 83;

16进制转换10进制:
将16进制数字的每个位上的数字乘以其对应位上的权值,然后相加之后的结果。
举例:有一个16进制数字123,则其实际大小为:
1 * 162  +  2 * 161 +  3 * 160  =  256 + 32 + 3 = 291;

2进制转换10进制:
将2进制数字的每个位上的数字乘以其对应位上的权值,然后相加之后的结果。
举例:有一个2进制数字101011,则其实际大小为:
1 * 25  +  0 * 24  +  1 * 23  +  0 * 22  +  1 * 21  +  1 * 20=  32 + 0 + 8 + 0 + 2 + 1 = 43;

浮点类型
浮点数的2种表示形式

1, 常规写法:带小数点。
$v1 = 123.456;

2, 科学计数法:带一个特殊符号“E”
$v1 = 123.456E2;        //含义为:123.456乘以10的2次方;
$v2 = 123.456E3;        //含义为:123.456乘以10的3次方,虽然结果是123456,但仍然是“浮点型”
$v3 = 123E4;            //含义为:123乘以10的4次方,还是浮点数。

浮点数使用的细节知识
•   浮点数不应进行大小相等比较

因为:
1,所有数字,最终的表示形式,都是2进制!!!
2,大多数浮点数的2进制形式,不能完全表达准确,最终只能“以很高的精度接近理论值”
3,因此,浮点数比较是不可靠。

再从另一个角度证明浮点数的不准确性:
 
说明: php中输出其实是做了一定的处理之后的显示结果,而js的输出是该计算结果的“真实反映”。

那应该怎么办?
考虑实际应用所需的精度的情况下,去将要比较的浮点数,转换为整数之后再比较。
比如:
要求精度为3为小数,则都乘以1000,然后取整后比较;
要求精度为4为小数,则都乘以10000,然后取整后比较;


•   小数转二进制的做法:乘2并顺序取整数部分(了解):
•   当整数运算的结果超出整数的范围后,会自动转换为浮点数(了解)。
获取一个数据(变量)的类型的函数有:
getType($变量);       返回的是该类型的名字(字符串);
var_dump($变量):      会输出该变量的类型,数据内容,(以及长度);

字符串
有如下4形式:
形式1:双引号字符串:
$str1 = “字符串内容.....”;

形式2:单引号字符串:
$str2 = ‘字符串内容.....’;

形式3:双引号定界符字符串:
$str3 = <<<”标识符A”
字符串内容....
标识符A;

形式4:单引号定界符字符串:
$str4 = <<<’标识符B’
字符串内容...
标识符B;


双引号字符串
单引号字符串
双引号定界符字符串(heredoc)
单引号定界符字符串(nowdoc)

布尔类型
单词是bool,boolean。
其只有2个数据:true,false;
布尔类型的一个常见应用情形是:对一个变量直接进行判断,比如if判断,示例如下:

这里的判断,永远是指:判断该变量(数据)“是否为真”。
对于这种情况,只有如下数据是被当做“假”(false):
0,   0.0,   “”,   “0”,   null,   array(),   false,   还有一个是“未定义的变量”
其余都是真。


类型转换
自动转换:
在任何运算中,如果需要某种类型的数据,而给出的数据不是该类型,通常都会发生自动转换:将该类型转换为目标需要的类型。

比如: octdec($x), bindec($x),  hexdec($x);    //这里就要求$x必须是字符串,如果不是,就会转换;
$v1 = 1 + “2”;      //此时也发生了自动转换。



强制转换:
自动类型转换是由“运算符”或类似运算符的语句来决定的。
而:
强制类型转换,仅仅是一个简单的语法:
形式:(目标类型)数据;
含义: 将该数据转换为设定的目标类型;



通常的转换目标类型有:
(int),  (float),  (string),  (bool),  (array),  (object)

上述强制类型转换,并不改变该变量的本身数据或类型。
对应,有一个语法是直接改变改变本的数据(及类型):
settype( $变量名,  “目标类型”);



类型相关的函数
•   var_dump():用于输出变量的“完整信息”,几乎只用于调试代码。
•   getType($变量名):获取该变量的类型名字,返回的是一个表示该类型名字的字符串,比如:“string”,“bool”,“double”,“int”
•   setType($变量名,“目标类型”):将该变量强制改变为目标类型;
•   isset(), empty(), unset();。。。。省略!
•   is_XX类型() 系列函数:判断某个数据是否为某种类型,有如下一些:
o   is_int($x);     判断$x是否是一个整数类型;
o   is_float($x);
o   is_string($x);
o   is_bool($x);
o   is_array($x);
o   is_object($x);
o   is_null($x);
o   is_numeric($x);     判断$x是否是一个数字!
o   is_scalar($x);      判断$x是否是一个“标量类型”

  • 算术运算符
符号有:+   -   *   /   %
说明:
1,他们都是针对数字进行的运算;
2,如果他们的两边有不是数字的数据,就会(自动)转换为数字;
3,其中取余运算(取模运算)%,它只针对“整数”进行运算,如果不是,会自动截取为整数。
11. 3  %  3 相当于 11  % 3;
11.8  %  3. 8  相当于 11 % 3;



自增自减运算符:
•   常规:对数字进行自加1或自减1。
•   字符串: 只能自增,且自增的效果就是“下一个字符”,其只能针对字母或数字进行自加:
•   布尔值递增递减无效
    null递减无效,递增结果为1
字符串自增的例子:

"a"++   //b
"A"++   //A
"abc"++ //abd
"xyz"++     //xza
"xyzz"++        //xzaa
"zzz"++     //aaaa
"abc9"++        //abd0
"9z"++          //10a



通常,我们在循环中,推荐使用前加加,比如:
for($i = 1;  $i < 10000;  ++$i){ ....... }

演示前加加后加加进行1千万次的“效率比较”:前加的效率会高很多

  • 比较运算符
•   符号:>  >=  <   <=  ==  !=   ===  !==
•   一般比较:是针对数字进行的大小比较
•   ==和===比较:前者通常叫做模糊相等的比较,后者叫做精确相等的比较(只有数据的类型和数据的值/内容,都相等,才是全等的)。必须能够找到手册的“类型比较表”

常见不同类型(标量类型)数据之间的比较规律:
•   如果比较的数据中,有布尔值,转为布尔值比较,布尔值比较只有一个规则:true>false
•   否则,如果有数字值,就转为数字值比较:这就是常规比较。
•   否则,如果两边都是“纯数字字符串”,转为数字比较

•   否则,就按字符串比较。字符串比较的规则是:
    对两边的字符串,一个一个从前往后取出字符并进行比较,谁“先大”,结果就是它大。




“abc” > true  //? false
“abc” > false  //true
“0”  > false  //false
3  >  “12”; //false
3  >  “12abc”; //false
“3”  > “12”   //false
“abc”  > “c”;  //false,后者大
“abc”  > “ab123cde”; //true  因为这里”c”大于”1”
“3abc” > “12abc”;      //true, 因为”3”大于“1”
1 > “a”;            //? true
“1” > “a”           //? false

逻辑运算符
逻辑运算符都是针对“布尔值”进行的运算。
如果不是布尔值,就会转换为布尔值进行;
布尔值只有2个:true,false
基本运算规则(真值表):
逻辑与规则:
true  &&  true  ==>> true
true  &&  false  ==>>false
false  &&  true  ==>>false
false  &&  false  ==>>false
总结:只有2个都是true,结果才是true
只要有一个是false,结果就是false
逻辑或规则:
true  ||  true  ==>> true
true  ||  false  ==>>true
false  ||  true  ==>>true
false  ||  false  ==>>false
总结:只有2个都是false,结果才是false
只要有一个是true,结果就是true
逻辑非规则:
!true  ==>> false
!false  ==>> true

逻辑运算符的“短路现象”:

逻辑与短路:
如果一个语句中,通过与运算需要进行多项判断,而且不同的判断具有明显不同的“复杂程度”,则我们应该将简单的判断放在前面,这时候我们就可以利用短路现象以达到提高效率的目的。

逻辑或短路:
如果一个语句中,通过或运算需要进行多项判断,而且不同的判断具有明显不同的“复杂程度”,则我们应该将简单的判断放在前面,这时候我们就可以利用短路现象以达到提高效率的目的



字符串运算符
1,符号只有一个:.      也衍生出另一个:  .=
2,含义:就是将这个符号两边的字符串连接起来;
3,如果两边不是字符串,就会自动转换为字符串,然后连接起来。

“ab”  .   3     ==>> “ab3”;
“12”  .   3         ==>>”123”
12  .  3         ==>> “123”

赋值运算符:
一个基本赋值运算符:  =
形式:  $变量名  =  值;
理解:  将右边的值(不管做了多少运算),赋值给左边的变量。
若干个衍生的赋值运算符:
+= 加等:   形式:  $变量名  +=  值;
理解:  相当于: $变量名  =  $变量名 + 值;
-= 加等:   形式:  $变量名  -=  值;
理解:  相当于: $变量名  =  $变量名 - 值;
*=   /=    %=    .=   其都可以认为是上述形式的一种简化版。

条件(三目,三元)运算符
只有一个,形式如下:
数据值1 ? 数据值2 : 数据值3
含义:
对数据值1进行判断,如果为“真”,则该运算符的运算结果就是数据值2,否则就是数据值3;
它是这样一个流程控制(逻辑判断)语句的简写形式:
if( 数据值1 ){
$变量名 = 数据值2;
}
else{
$变量名 = 数据值3;
}
注意:如果数据值1不是布尔值,也会转换为布尔值;
$score = 66;        //分数
$valuation = $score >= 60 ?  “及格”  :  “不及格”;    //结果为“及格”

$score = 56;        //分数
$valuation = $score >= 60 ?  “及格”  :  “不及格”;    //结果为“不及格”

$score = 56;        //分数
$valuation =  $score  ?  “及格”  :  “不及格”;    //结果为“及格”,这里可能就偏离的本意!!

位运算符
基础规定
1,位是什么?就是2进制数字的每一个“位”,一个整数数字,有(由)32个位构成!
2,位运算符是仅仅针对整数进行的运算符;
3,位运算符有如下几个
&:  按位与;
|:  按位或;
~:  按位非;按位取反;
^:  按位异或;
4,位运算符的基本语法规则:
按位与基本规则:
1  &  1  ==>>  1
1  &  0  ==>>  0
0  &  1  ==>>  0
0  &  0  ==>>  0

按位或基本规则:
1  |  1  ==>>  1
1  |  0  ==>>  1
0  |  1  ==>>  1
0  |  0  ==>>  0
按位非基本规则:
~1  ==>>  0
~0  ==>> 1

按位异或基本规则:
1  ^  1  ==>>  0
1  ^  0  ==>>  1
0  ^  1  ==>>  1
0  ^  0  ==>>  0
可见,按位异或的规则是:相同为0,不同为1

整数的按位与运算(&)
形式:
$n1  &  $n2;    //n1,n2是2个任意整数;
含义:
将该2个整数的二进制数字形式(注意,都是32位)的每一个对应位上的数字进行基本按位与运算之后的结果!
注意:他们运算的结果,其实仍然是一个普通的数字(10进制)。

$r1 = 10 & 20;      //0


整数的按位或运算:
形式:
$n1  |  $n2;    //n1,n2是2个任意整数;
含义:
将该2个整数的二进制数字形式(注意,都是32位)的每一个对应位上的数字进行基本按位或运算之后的结果!
注意:他们运算的结果,其实仍然是一个普通的数字(10进制)。
$r1 = 10 | 20;      //30
则结果该数据值大小为: 1*24  +  1 * 23  +  1*22  + 1* 21  + 0  =  16 + 8 + 4 + 2 = 30



整数的按位左移运算
形式:
$n1  <<  $m
含义:
将十进制数字n1的二进制数字形式(也是32位的)的每一个位上的数字都一次性往左边移动m位,
并将右边空出来的位置补0,左边冒出去的不管,这样操作之后得到的结果。

$r1 = 10 <<  2;     //40



补充知识:原码,反码,补码
原码:
就是一个二进制数字,从“数学观念”上来表达出的形式。其中,我们规定:
一个数字的最左边一位是“符号位”,0表示正数,1表示负数;

反码:
正数的反码就是其本身(即不变);
负数的反码是:符号位不变,其他位取反;

补码:
正数的补码就是其本身(即不变);
负数的补码是:符号位不变,其他位取反后+1——即反码+1

计算机内部的运算,实际全都是使用补码进行的,而且运算的时候,符号位不再区分,直接也当做“数据”参与运算

实际上,cpu内部,会将“减法”运算,转换为“加法运算”,即:5 + (-3)


位运算符的应用:管理一组事物的开关状态
什么是开关状态?
现实中,有很多数据都是只有2种结果(值)的,对应的其实就是我们的布尔类型的值。

这里,所谓管理一组事物的开关状态,应该理解为其实就是管理若干个只有2个状态的“数据符号”。
比如:有5个灯泡,对应5个状态数据。
这5个灯泡,就有 25  种状态呢?

这里的管理目标是:使用一个变量,就可以表达若干个数据的“当前状态”。具体有3个任务:
1,通过该变量,可以获知任何一个数据(灯泡)的当前状态。
2,通过该变量,可以将一个一个数据的状态“关闭”;
3,通过该变量,可以将一个一个数据的状态“开启”;



数组运算符
有这些:
+:  数组联合,也可以理解为“数组串联”。
将右边的数组项合并到左边数组的后面,得到一个新数组。如有重复键,则结果以左边的为准
$arr1 = array(5=>10,  8=>20,  10=>30);
$arr2 = array(3=>33,  2=>22);
$r1 = $arr1 + $arr2;    //结果为:array(5=>10,  8=>20,  10=>30, 3=>33,  2=>22)
另一个有重复键的例子:
$arr1 = array(5=>10,  8=>20,  10=>30);
$arr2 = array(8=>33,  2=>22);
$r1 = $arr1 + $arr2;    //结果为:array(5=>10,  8=>20,  10=>30, 2=>22)
= =:如果两个数组具有相同的键名和键值(可以顺序不同,或类型不同),则返回true
$arr1 = array(3=>33,  2=>22);
$arr2 = array(2=>”22”, 3=>”33” );
此时,$arr1,和 $arr2是相等的( = = )
!=
= = =: 如果两个数组具有相同的键名和键值且顺序和类型都一样,则返回true
!= =

错误控制运算符@:
通常就用在一个地方:
$link  =  @mysql_connect(“数据库服务器地址”, “用户名”,  “密码”);
作用是:
如果该连接数据的语句失败(比如连接不上),则屏蔽该失败的错误提示!

运算符的优先级
运算符,都有优先级问题!
记住以下几条就可以了:
•   要意识到运算符有优先级问题
•   括号最优先,赋值最落后(通常)
•   先乘除后加减
•   大致:单目运算符〉算术运算符〉比较运算符〉逻辑运算符(除了“非”运算)



  • 文件加载
综述和基本语法:
1,有4个文件加载语句:include, require, include_once, require_once
2,他们的使用形式完全一样,比如: include  “要加载的文件路径”; 或: include (“要加载的文件路径”);
3,他们的含义也几乎完全一样:只是在加载失败时或是否重复加载这种情况,有所不同。
4,他们可以载入php或html文件;

文件加载的路径问题:
前提说明:以下的说明举例,以include为例,也适用于其他3个加载语句;

有3中路径形式可以使用:

相对路径:
是相对于当前网页文件所在的位置来定位某个被加载的文件位置,主要依赖以下2个特殊的路径符号:
./  :表示当前位置,即当前网页文件所在的位置(目录);
../ :表示上一级位置,即当前网页文件所在的位置的上一级位置(目录);
我们需要用这2个符号来表达位置信息,比如:
include  ‘./page1.php’;     //表示当前网页文件所在位置的page1.php文件;
include  ‘../page2.php’;
include  ‘../ab/page3.html’;

绝对路径:
绝对路径又分2种:
本地绝对路径:
比如:
include  “c:/d1/d2/p1.php”;   
include  “f:/f1/abc/p2.html”;
特别注意:我们其实几乎都不应该在代码中直接写这种本地绝对路径!
但,其实我们这种本地绝对路径的写法是很常用的!



网络绝对路径:
比如:
include  “http://www.abc.com/p1.php”;   
include  “http://www.baidu.com/index.php”;

“无路径”(不推荐):
形式就是没有给出路径信息,而只给出文件名,我们不推荐。
比如:include  ‘page1.php’;        //此时通常其实php语言引擎会在当前网页目录下找该文件。



文件载入和执行过程详解
•   第1步:从include语句处退出php脚本模式(进入html代码模式)
•   第2步:载入include语句所设定的文件中的代码,并执行之(如同在当前文件中一样)
•   第3步:退出html模式重新进入php脚本模式,继续执行之后的代码



4个载入语句的区别
include和require的区别:
include载入文件失败时(即没有找到该文件),报一个“提示错误”,然后继续执行后续代码;
requre载入文件失败时,报错并立即终止执行。
通常,require用于在程序中,后续的代码依赖于载入的文件的时候。

include_once和require_once的区别:
同include和require的区别:


include和include_once的区别:
include载入的文件不判断是否重复,只要有include语句,就会载入一次——即此时可能导致重复载入。

include_once载入的文件会有内部判断机制是否“前面代码”已经载入过,如果载入过,就不再载入。

require和require_once的区别:
同include和include_once的区别。


在被载入文件中return语句的作用
1,一个载入语句,如果载入成功,其实是有返回值的,为1,如果载入失败,则返回的是false。
(虽然我们通常不去使用该返回值)。

但,如果被载入文件中有return语句,此时就有另外的机制和作用:
2,return语句此时的作用是终止载入过程——该return语句的后续被载入文件的代码不再载入。
3,return语句也可以用于该被载入文件载入时返回一个数据,形式为:return  XX数据;

  • 错误处理
错误的分类
通常分3种:

语法错误:
程序运行之前,都要先检查语法。如果语法有错误,就会立即报错,并且不会去执行程序。

运行时错误:
就是在程序语法检查通过后,,开始运行程序并在此过程中遇到的错误。常见的有3中:
提示性错误:
警告性错误:
致命错误:

逻辑错误:
指的是,程序本身可以正常执行,没有报错——但“计算结果”却错了。

错误的分级
php语言中,将各种错误进行了不同级别的分类归纳,并形成大约有10几个级别的错误,这就是技术层面的错误分级。
每一级别的错误,都有一个“代号”,这个代号其实也就是一个系统内部的“常量而已”。比如:

系统常见错误:
E_ERROR:        致命错误
E_WARNING:  警告性错误
E_NOTICE:       提示性错误
用户可自定义的错误:
E_USER_ERROR:       自定义致命错误
E_USER_WARNING:     自定义警告性错误
E_USER_NOTICE:      自定义提示性错误
其他:
E_STRICT:       严谨性语法检查错误
E_ALL           代表“所有错误”。



错误的触发
错误的触发,就是让错误“发生”。

有两种方式会触发错误:

系统触发
程序运行到某行代码,确实出现了某种错误,此时系统就会报错——这就是触发了系统错误。
系统触发的典型错误有这3种:
E_NOTICE:       提示性错误:会输出错误提示,并继续执行后续代码;
比如使用不存在的变量或常量:

E_WARNING:  警告性错误:会输出错误提示,并继续执行后续代码(也可能看具体情况,比如require)
比如include载入一个不存在的文件

E_ERROR:致命错误:导致程序无法执行后续语句;
比如调用一个不存在的函数!

自定义触发:
当我们处理某些数据的时候,本来数据本身是没有错误的,但根据具体应用(业务)的需要,会要求数据满足某种条件,而该数据并不满足的时候,我们就可以在程序中“主动”去触发(创建)一个错误,以表明该数据的“非法性”。
语法形式:
trigger_error(“错误提示信息内容”,  3中用户错误代号之一);
其中触发了用户的致命错误(E_USER_ERROR),也会终止程序的后续执行。


错误报告的显示问题
所谓错误报告,就是显示在网页上的错误提示内容!

有关错误报告,有2个问题需要处理:

是否显示错误报告(display_errors):
有2种做法可以来设定是否显示:
做法1:
在php.ini文件中,设定display_erros的值,为on(显示),或为off(不显示)


当然,作为开发阶段,我们都应该显示错误信息。

注意:前提条件都是我们apache已经装载了php.ini文件——这一点,需要在apache的配置文件httpd.config中加入如下一行:
PHPIniDir  “php.ini文件的了位置(路径)”

方法2:
直接在php的脚本文件中设使用函数ini_set()来对其进行设置:
ini_set("display_errors",0);//不显示错误报告

当然,如果设置为1,就是显示!

注意:
1,不管哪种形式,该单词是一样的:display:errors
2,使用php.ini配置,影响的是全局(即所有php网页);
3,在某个脚本代码中使用ini_set()设置,就只影响该脚本代码本身——这是常用的方式。
4,脚本中的设置优先于php.ini中的设置。

显示哪些级别的错误报告(error_reporting):
显然,前提是“display_errors”设置为On(或1),表示可以显示。

显示哪些级别的错误报告,也有2个做法:
做法1:在php.ini文件中
error_reporting = E_NOTICE,这时候只显示E_NOTICE级别的错误

error_reporting = E_NOTICE | E_WARING | E_ERROR     //显示该3种;
error_reporting = E_ERROR | E_USER_ERROR                //显示该2种严重错误
要想代表真正的“所有错误”,应该写为:E_ERROR | E_STRICT


做法2:在当前的脚本代码中:
跟php.ini中设置其实是一样,举一些例子如下:
ini_set(“error_reporting”,  E_NOTICE);  //就显示该一个级别的错误
ini_set(“error_reporting”,  E_NOTICE | E_WARNING),  //显示2个级别
ini_set(“error_reporting”,  E_NOTICE | E_WARNING | E_ERROR),    //显示3个级别
ini_set(“error_reporting”,  E_ALL | E_STRICT),  //这才代表显示所有错误!

错误日志的记录问题
错误日志其实就是错误报告,只是它会“写入文件中”,此时就称为错误日志!

也有2个问题,每个问题也有2种做法:

是否记录log_errors:
php.ini中:
log_errors = On    或 Off

脚本中:
ini_set(“log_erros”,  1);   或 0

补充一句:
1:ini_set(“php配置项”, 值); //用于脚本中设置php.ini中是某项的值。
2,:$v1 = ini_get(“php配置项”); //用于获取php.ini中是某项的值

记录到哪里error_log:
一般就只有2个写法:
写法1:直接使用一个文件名,此时系统会自动在每个文件夹下都建立该文件名,并用其记录该文件夹下的所有网页文件发生的错误信息。

写法2:使用一个特殊的名字“syslog”,则此时所有错误信息都会记录到系统的“日志文件”中。
//window
系统日志文件在这里:控制面板》管理工具》事件查看器》window日志》应用程序:


自定义错误处理器
什么叫错误处理器?
就是一旦发生错误,用来处理该错误的一种“机器”——其实就是一个函数。

自定义错误处理,就是指:
让系统不要去处理错误了,而完全由我们(开发者)来对错误进行处理:显示和记录。

做法,其实非常简单,就2步:

第一步:
设定要用于处理错误的函数名!
set_error_handler(“f1”);
第二步:
去定义该函数!
function f1(){
//这里可以任意写代码:自然正常是去显示错误报告,和记录错误日志。
}

  • 函数
函数的定义:
形式:
function  函数名 ( 【$形参1】 【,$形参2】 【,.... 】  ){
//函数体。。。。。。
}
说明:
1,定义时使用的形参,其实就是一个变量——只能在该函数内部使用的变量
2,形参作为变量,其名字是“自己定义”——自然应该遵循命名规范;
函数的调用:
函数名($实参1, $实参2, ..... );
说明:
1,实参应该跟要调用的函数的形参“一一对应”;
2,实参就是“数据值”,可能是直接值(比如5,”abc”),也可能是变量值(比如$v1)



函数调用详细过程
1,首先,将函数调用时的实参数据,传递(赋值)给函数的形参(变量);
2,程序的执行流程,进入到函数内部——此时可以认为是一个跟外界“隔离” 的“独立运行空间”。
3,在函数内部,按正常的流程顺序,执行其中的代码;
4,直到函数结束,则退出该运行空,而返回到原来调用函数的位置,继续执行后续代码!
5,如果在函数内部执行的过程中,有return语句,则也会立即终止函数,并回到函数调用位置。



函数的参数问题
函数形参的默认值问题
我们可以给一个函数定义时的形参,赋值一个“默认值”,则这个函数调用的时候,该形参对应的实参,可以不给值
.

函数形参的默认值,可以只给部分形参设置默认值,但设置默认值性的形参,都要放在“右边”(后边):

function func2($a,$b,$v="ddf"){

}


形参的传值问题
一句话:形参的传值问题,其实就是“变量之间的传值问题”:
其实无非就是实参变量,传值给形参变量的问题。
即:
此时,也同样有两种传值方式:
值传递:
这是默认值。如果没有特别设定,参数传值都是值传递。
引用传递:
需要在形参的前面加 &符号



函数参数的数量问题
1,通常,函数调用时的实参数量,应该跟函数定义时的形参数量保持一致。
2,如果函数定义时,形参有默认值,则对应的实参就可以进行一定程度的省略:
注意:省略只能从右往左进行。
3,有一种定义和使用函数的特别形式(并不常见):它不定义形参,而实参任意给出。
其实,系统中也有类似的函数:,比如:
var_dump($v1);
var_dump($v1, $v2, $v3);    //ok!
可见,该函数就可以接受任意个数的实参;
我们自己也可以定义这种函数。其实,这种函数,依赖的是以下3个系统函数来获取相应的信息,以得到实参数据的处理:
1: func_get_args(); //获取实参数据列表,成为一个数组
2: func_get_arg($i);    //获取第$i个实参数据,$i从0开始算起;
3:func_num_args();  //获取实参的数量(个数)



函数的返回值问题
一个观念问题:
函数的返回值,不是语法规定,而是应用所需:需要就返回,不需要就无需返回。
返回值,一定是通过return语句!
形式:
function 函数名(....)
{
//。。。。。。
return  XX数据;
}

注意:
return语句的作用,不管后面跟不跟数据值,都会立即终止函数的执行,返回到函数调用的位置并继续后续工作。


函数的其他形式:
可变函数
先想想可变变量:
$v1 =”abc”;
$abc = 123;
echo  $$v1; //输出123,这就是所谓的可变变量。
可变变量:一个变量的名字还是一个变量!
可变函数:一个函数的名字是一个变量!



匿名函数
匿名函数就是没有名字的函数。

有2种形式的匿名函数:

形式1:将一个匿名函数“赋值”给一个变量——此时该变量就代表该匿名函数了!

形式2:
是直接将一个匿名函数,当做“实参”来使用!——即调用“别的函数A”的时候,使用一个匿名函数来当做实参。自然,在该函数A中,也就应该对该匿名函数当做一个函数来用!



变量的作用域问题
变量的作用域,就是指:一个变量,在什么范围中可以使用的情况。
php中,有3中变量作用域:
局部作用域:
就是指一个函数的内部范围。
对应这样的变量,就称为“局部变量”;
超全局作用域:
就是指所有的代码范围。
对应这样的变量,就称为“超全局变量”;
其实只有系统预定义的几个:$_GET, $_POST, $_SERVER, $_REQUEST, $GLOBALS, $_SESSION, $_COOKIE, $_FILES
全局作用域:
就是不在函数内部的范围——函数外部。
对应这样的变量,就称为“全局变量”;



通常,
1,全局范围不能访问局部变量;
2,局部范围不能访问全局变量;

3,函数内部的变量(局部变量),通常在函数调用执行结束后,就被“销毁”了。
4,但有一种局部变量,在函数调用结束后不被销毁:它叫做“静态变量”;
使用形式:
function 函数名 (....){
static  $变量名  =  初始值;   //这就是静态变量!
...
}

如果在局部作用域使用(访问)全局变量?(常见需求)
有2种做法:

做法1:
使用global关键字来实现:
global $var;

做法2:
使用$GLOBALS超全局变量来实现:
$GLOABAL["var"];

但,如果我们对$GLOBALS变量的某个单元(也即下标)进行unset,则其就会完全对应销毁该变量。
这是因为,$GLOBALS对全局变量的使用可以看做是全局变量的另一种语法形式而已,而不是“引用关系”


有关函数的系统函数:
•   function_exists():判断一个函数是否被定义过。其中使用的参数为“函数名
function_exists("funcName") == false ? 1 : 0;



•   func_get_arg($i):   获取第i个实参值
•   func_get_args():    获取所有实参(结果是一个数组)
•   func_num_args():    获取所有实参的个数。
其他系统函数:
自己会查,并需要去查:
•   字符串函数:
o   输出与格式化:echo , print, printf, print_r, var_dump.
o   字符串去除与填充:trim, ltrim, rtrim, str_pad
o   字符串连接与分割:implode, join, explode, str_split
o   字符串截取:substr, strchr, strrchr,
o   字符串替换:str_replace, substr_replace
o   字符串长度与位置: strlen, strpos, strrpos,
o   字符转换:strtolower, strtoupper, lcfirst, ucfirst, ucwords
o   特殊字符处理:nl2br, addslashes, htmlspecialchars, htmlspecialchars_decode,
•   时间函数:
o   time, microtime, mktime, date, idate, strtotime, date_add, date_diff, date_default_timezone_set, date_default_timezone_get
•   数学函数:
o   max, min, round, ceil, floor, abs, sqrt, pow, round, rand

有关函数的编程思想
递归思想——递归函数
递归函数,就是:在一个函数内部调用它自己的函数!

先考察一个最简单的函数:
function  f1( $n ){
echo $n;
$n++;
f1( $n );
}

f1(1);
从这个简单的函数可以看出,该函数调用是“永无止境”的(没完没了),最终会将内存消耗完毕。
显然,这不是一个正常的做法!
实用的递归函数是:能够控制这个调用的过程中,会在某个时刻(条件下)停下来!

实例演示:
求5的阶乘。
数学上,有这样两个有关阶乘的基本规则:
1,n的阶乘,是n-1的阶乘,乘以n的结果。
2,  1的阶乘是1;
现在,假设,有一个函数,该函数“能够”计算n的阶乘。
function  feibonaci( $n ){
//.....
}
$v1 = feibonaci(8); //结果应该是8的阶乘
$v2= feibonaci(5);  //结果应该是5的阶乘


递归思想总结:
当面对一个“大问题”,该大问题可以经由该问题的同类问题的“小一级问题”而经过简单计算获得,而且,可以获知(已知)这类问题的“最小一级问题”的答案。则,此时就可以使用递归方法来解决该问题。
则此时该函数的基本模式是:
function  recursion( $n ){
if(是最小一级){
return 已知的答案;
}
$result = 对 recursion($n-1) 进行简单运算;
return $result;
}

  • 数组
含义:
数组就是一系列数据的集合体,他们按设定的顺序排列为一个“链的形状”。
注意:php中的数组单元的顺序,跟下标无关!
数组定义(赋值):
$arr1 = array(3,  11,  5,  18,  2  );//这是最常见的数组,下标为“默认下标”,就是从0开始的整数;
$arr2 = array(“a”=>3,  “bb”=>11,  “cc123”=>5,  ‘d1’=>18,  ‘xyz’=>2  );关联数组,下标为字符串,常见
$arr3 = array(1=>3,  10=>11,  3=>5,  0=>18,  88=>2  );下标可以人为给定;
$arr4 = array(1=>3,  ‘a1’=>11,  3=>5,  ‘mn’=>18,  88=>2  );下标可以数字和字符串混合使用;
$arr5 = array(5=>3,  11,  3=>5,  ‘mn’=>18,  2  ); //有指定下标,也有“自动下标”,
//此时下标为:5,6,3,”mn”, 7
//可见,自动下标为“前面最大数字下标+1”
$arr6 = array(5=>3,  7.7=>11,  3=>5,  ‘mn’=>18,  2  ); //此时下标为:5,7,3,”mn”, 8
$arr7 = array(5=>3,  true=>11,  false=>5,  ‘mn’=>18,  2  ); //此时下标为:5,1,0,”mn”, 6
$arr8 = array(1=>3,  3=>33,  true=>11,  ); //此时下标为:1,3,其对应值为:11, 33
//下标如果有重复,后面的值覆盖前面的值;
$arr9 = array(1=>3,  -3=>33,  11,  );   //此时下标为:1, -3, 2,注意:最后一个逗号“可以有”。
其他一些形式:
$arr10[] = 3;
$arr10[] = 11;
$arr10[] = 5;   //该数组下标为0,1,2,常规情况
$arr11[‘a’] = 3;
$arr11[‘bb’] = 11;
$arr11[‘cc123’] = 5;    //该数组下标为’a’,’bb’,’cc123’,常规情况
$arr12[1] = 3;
$arr12[] = 11;  //此时下标为2
$arr13[‘cc123’] = 5;    //该数组下标为1,2,’cc123’

特别注意:php中,数组单元的顺序,是由其“放入”顺序决定,而不是下标。
数组取值:
$v1 = $arr1[0];
$i = 3;
$v2 = $arr1[$i];    //取得数组下标为3的单元的值;
总体上,可以将取得一个数组的单元的值,看组取得一个变量的值完全一样!!!


数组的分类
按键值关系来分:
索引数组:通常认为,如果一个数组的下标是严格按照从0开始的连续的整数作为下标,则称其为索引数组——就是类似js数组的下标。例如:
$arr1 = array(3,  11,  5,  18,  2  );//这是最常见的数组,下标为“默认下标”,就是从0开始的整数;

关联数组:通常认为,如果一个数组的下标都是一个“字符串”并一定程度上表名了该单元的“含义”,则称为关联数组,例如:
$conf = array(
‘host’=>”localhost”  ,
‘port’=>3306  ,
‘username’=>’root’  ,
‘password’ => ‘123’  ,
);

混合数组:既有数字下标,也有字符下标的情况:
$arr4 = array(1=>3,  ‘a1’=>11,  3=>5,  ‘mn’=>18,  88=>2  );下标可以数字和字符串混合使用;


按数组的维数(复杂程度)分:
一维数组:
$a = array(1, 11, 111);
$b = array(2, 22, 222);
$c = array(3, 33, 333);

二维数组:
$dd = array(
array(1, 11, 111),
array(2, 22, 222),
array(3, 33, 333)
);
多维数组:无非就是继续里面再用数组代替。



数组的遍历
foreach基本语法
foreach( $数组变量名  as   【$key =>】 $value ){
//循环体;这里可以去“使用”$key 和 value;
//$key 和 $value 就是该遍历语句一次次取得的数组的每一个单元(项)的下标和对应值。
//而且,它总是从数组的开头往后按顺序取数据。
}

数组的指针操作及遍历原理:
首先,看看数组的一个“形象图”:
$arr4 = array(1=>3,  ‘a1’=>11,  3=>5,  ‘mn’=>18,  88=>2  );



foreache遍历流程原理:
foreach( $数组变量名  as   $key => $value ){
//循环体;这里可以去“使用”$key 和 value;
//$key 和 $value 就是该遍历语句一次次取得的数组的每一个单元(项)的下标和对应值。
//而且,它总是从数组的开头往后按顺序取数据。
}

对php数组,往往不能单纯使用for循环进行遍历。
或者说:php中,使用for循环只能循环“下标为连续的纯整数数组”;

each()函数的使用
each()函数的作用:先取得一个数组的“当前单元”的下标和值(并放入一个数组),然后将指针移到下一个单元。
使用形式:
$a  =  each($数组名);  //此时$a就是一个数组了

list()“函数”的使用:
list()函数用于一次性取得一个数组中从0开始的数字下标的多个单元的值!
形式:
list($变量1,$变量2,$变量3, .. ) = $数组;
作用:
上述一行代码相当于如下代码:
$变量1 = $数组[0];
$变量2 = $数组[1];
$变量3 = $数组[2];
........
注意:这里变量的个数,要跟该数组的数字下标的单元对应,如果某个变量对应的该数字下标不存在,就会报错!

数组变量的一些细节
•   foreach也是正常的循环语法结构,可以有break和continue等操作。
•   遍历过程中值变量默认的传值方式是值传递。
•   遍历过程中值变量可以人为设定为引用传递:foreach($arr as $key => &$value){ ... }

•   foreach默认是原数组上进行遍历。但如果在遍历过程中对数组进行了某种修改或某种指针性操作,则会复制数组后在复制的数组上继续遍历循环(原数组保持不变)。

•   foreach中如果值变量是引用传递,则无论如何都是在原数组上进行。


你可能感兴趣的:(php基础知识入门)