《细说PHP》第二版--读书笔记

第五章 PHP 的基本语法

5.2.4 在程序中使用空白的处理

php空行处理

5.3 变量

5.3.1 变量的声明

在 php 中变量的声明必须是使用一个$符号,后面跟变量名来表示
unset()函数释放指定变量
isset()函数检测变量是否设置
empty()函数检查一个变量是否为空

5.3.2 变量的命名

变量命名严格区分大小写,但内置结构和关键字以及用户自定义的类名和函数名都是不区分大小写
变量名由字母或者下划线开头,后面跟上任意数量的字母,数字,或者下划线。

5.3.4 变量的引用赋值

变量的引用赋值,意味着新的变量只是简单的引用了原始变量(并没有执行赋值操作),因而改动新的变量会影响到原始变量。
使用引用赋值,简单的将&符号添加到将要赋值的变量前
$bar = &$foo;只有有名字的变量才可以引用赋值

变量的类型

5.4.1 类型的介绍

PHP 支持 8 中原始数据类型:

  • 4 种标量类型 boolean integer float string
  • 两种复合类型 array object
  • 两种特殊类型 resource null

如果想查看某个表达式的值和类型,可以使用函数var_dump()

5.4.3 布尔型

以下值被认为是 false:

  • 布尔值 false
  • 整型值 0
  • 浮点型值 0.0
  • 空白字符串和字符串“0”
  • 没有成员变量的数组
  • 特殊类型 null
5.4.4 整型

八进制和十六进制的整型表达式的计算结果均以十进制数字输出

5.4.5 字符串

字符串有单引号 双引号 定界符三种方法定义
单引号中不能再包含单引号,可添加反斜线转义
单引号中的变量不会被变量的值替代,而是将变量名原样输出
双引号最重要的一点是其中的变量名会被变量值替代,即 PHP 可以解析双引号中包含的变量
定界符

<<<EOT
string
EOT;
5.4.6 数组

使用 print_r()函数查看数组中的全部内容

5.4.7 对象

要初始化一个对象,用 new 语句将对象实例化到一个变量中

5.4.8 资源类型

资源是一种特殊类型的变量,保存到外部资源的一个引用

$file_handle = fopen("info.txt","w");
var_dump($file_handle);
5.4.9 null

null 值表示一个变量没有值,不区分大小写
在下列情况变量将被认为是 null:

  • 将变量直接赋值位 null
  • 声明的变量尚未被赋值
  • 被 unset()函数销毁的变量
5.4.11 数据类型转换

只有相同类型的数据才能彼此操作,自动转换要遵循按数据长度增加的方向进行
强制类型转换需要在转换的变量之前加上用括号括起来的目标类型,也可以使用转换函数
intval()获取变量的整数值
floatval() 获取变量的浮点值
strval() 获取变量的字符串值
以上强制类型转换都没有改变被转换变量本身的类型,而是通过转换将得到新类型数据赋值给新变量。如果需要将变量本身的类型改变成其他类型可使用 setType()函数

$foo = "5bar";
settype($foo,"integer");  //$foo 现在是5

想得到一个易读懂的类型的表达方式用于调试可以使用 gettype()函数
查看某个类型用 is_type()函数

5.5 常量

5.5.1 常量的定义和使用

在 PHP 中是通过使用 define()函数来定义的,其命名规则与变量相似,按照惯例常量标识符总是大写,不要$符号

define(string name,mixed value[,bool case_insensitive]);
define("CON_INT",100);
echo CON_INT;
5.5.2 常量和变量

常量和变量的不同点:

  • 1.常量前没有$
  • 2.常量只能用 define()函数定义,而不能通过赋值语句
  • 3.常量可以再任意地方定义和使用,一旦定义就不能被重新定义或者取消定义
  • 4.常量只能是标量

5.6 PHP 中运算符

5.6.1 算数运算符

在做求模运算时首先会将 % 运算符两边操作数转化为整型,然后返回第一个操作数除以第二个操作数后所得到的余数。在程序开发中一般用于计算闰年和一个范围之内的随机数

5.6.6 位运算符

位运算

5.6.7 其他运算符

三元运算符(expr1)?(expr2):(expr3)
在 expr1 求值为 true 时执行 expr2 并获取其值,为 false 时执行 expr3 并获取其值
执行运算符
反引号(``)PHP 尝试将反引号中的内容作为操作系统命令来执行,并将其输出信息返回。使用反引号的效果与函数 shell_exec()相同
PHP 中运算符优先级
PHP中运算符优先级

第六章 PHP 语言结构

6.1 流程控制

顺序结构 语句按照出现的先后次序自上而下依次执行
分支结构 先做判断再做选择

6.3.4 特殊的流程控制语句

break 语句结束当前 for、foreach、while、do-while、switch 结构循环的执行
continue 语句作用是跳过该次循环,继续执行下一次循环结构
exit 语句作用是直接退出当前脚本

6.4 PHP 中的函数

函数的调用 在需要使用函数的位置,使用函数名称和参数列表进行调用,执行完毕后返回调用位置继续向下执行
函数的返回值是函数执行后的结果返回给调用者
return 语句可以向函数调用者返回函数体中任意确定的值,将程序控制权反回到调用者的作用域,即退出函数
如果要返回多个值,可以将多个值添加到一个数组中,然后返回这个数组

6.4.4 PHP 变量的范围

局部变量 其作用域仅限于函数内部。不仅在函数中声明的变量是局部的,函数参数在函数名后面的括号内声明也是局部变量,当函数执行完毕后,函数内部的变量都被释放。如果在函数外部需要使用该变量值时,必须通过 return 语句
全局变量 作用域从变量定义开始,到本程序文件末尾
注意:在 PHP 函数中无法直接调用全局变量,若要使用全局变量,必须通过 global 关键字定义目标变量,以告诉函数此变量为全局变量。
还可以在 PHP 中使用预定义的全局变量数组$GLOBALS
局部变量可分为动态存储类型(默认)和静态存储类型(函数执行完毕后,内部变量依旧保存在内存中)

6.4.5 参数的传递

PHP 中参数默认是按值传递,即使在函数内部改变参数的值,他并不会改变函数外部的值
按引用传递是把该数值或变量的内存储存区块相对地址导入函数之中,因此当该数值在函数中有任何变动时,会连带对父程序造成影响。可以在函数定义中在参数前预先加上&

6.4.6 变量函数

将函数名赋给变量,在程序中使用变量名并在后面加上圆括号时就调用那个函数执行

第七章 PHP 中的数组及数组结构

7.2 数组的定义

7.2.1 直接赋值方式声明数组
$arr[0] = 1;
$arr["ID"] = 1;
$arr[3] = "jesse";
$arr["company"] = "xxx";
$arr[] = "aa";
print_r($arr);
/*Array
(
    [0] => 1
    [ID] => 1
    [3] => jesse
    [company] => xxx
    [4] => aa
)*/

如果没有指定索引值的元素与指定索引值的元素混在一起赋值时,没有指定索引值的元素的默认索引将紧跟索引元素中最高的索引值递增

7.2.2 使用 array()构建新数组

语法格式如下:
$数组变量名 = array(key1=>value1,key2=>value2,key3=>value3……keyN=>valueN);
如果不使用=>符号指定下标,默认为索引数组,索引值从 0 开始依次增加
如果使用 array()声明关联数组,就必须使用=>运算符指定字符串下标

7.2.3 多维数组的声明
$contact = array(
    array(1,"jesse","a"),
    array(2,"jack","b"),
    array(3,"lucy","c"),
);
echo $contact[0][1];  //jesse

7.3 数组的遍历

由于 for 语句的局限性,在 php 中很少使用

7.3.2 使用 foreach 语句遍历数组
//第一种语法格式:
foreach(array_expression as $value){
    //循环体
}
//第二种语法格式:
foreach(array_expression as $key => $value){
    //循环体
}
7.3.3 联合使用 list() each()和 while 循环遍历数组

each()
each()函数需要传递一个数组作为参数,返回当前元素的键值对,并向后移动数组指针到下一个元素的位置。键值对被返回带有四个元素的关联和索引混合数组,键名分别为 0,1,key,value。如果内部指针越过了数组的末端,则 each()返回 false

$arr = array("id"=>1,"name"=>"jesse");
$id = each($arr);
print_r($id);
/*Array
(
    [1] => 1
    [value] => 1
    [0] => id
    [key] => id
)*/
$name = each($arr);
print_r($name);
/*Array
(
    [1] => jesse
    [value] => jesse
    [0] => name
    [key] => name
)*/
$no = each($arr);
var_dump($no); //bool(false)

list()
list()不是真正的函数,是 php 语言结构,list()用一步操作给一组变量进行赋值,即把数组中的值赋值给变量

$info = array('coffee','brown','caffeine');
list($drink,$color,$power) = $info;
echo "$drink is $color and $power makes it special";
//coffee is brown and caffeine makes it special
list(,,$power) = $info;
echo "i need $power!";  //i need caffeine!
$arr = array("id"=> 1,"name" => "jesse","email" => "xxx@163.com");
list($key,$value) = each($arr);
echo "$key => $value.\n";  //id => 1

while()

$arr = array("id"=> 1,"name" => "jesse","email" => "xxx@163.com");
while(list($key,$value)=each($arr)){
    echo "$key => $value.\n";
}
/*id => 1
name => jesse
email => xxx@163.com*/
7.3.4 使用数组内部指针控制函数遍历数组
  • current():取得目前指针位置的内容资料
  • key():读取目前指针所指向的资料的索引值
  • next():将数组中内部指针移动到下一个单元
  • prev():将数组中的内部指针回到一位
  • end():将数组中的内部指针直到最后一位
  • reset();将数组中的内部指针重置到第一位
$arr = array("id"=> 1,"name" => "jesse","email" => "xxx@163.com");
echo key($arr)."=>".current($arr)."\n"; //id=>1
next($arr);
next($arr);
echo key($arr)."=>".current($arr)."\n"; //email=>xxx@163.com
prev($arr);
echo key($arr)."=>".current($arr); //name=>jesse

7.4 预定义数组

预定义数组

7.5 数组的相关处理函数

7.5.1 数组的键值操作函数

array_values()
array_values()的作用是返回数组中所有元素的值,只有一个参数,传入给定的数组

$arr = array("id"=> 1,"name" => "jesse","email" => "xxx@163.com");
print_r(array_values($arr));
/*Array( [0] => 1 [1] => jesse [2] => xxx@163.com)*/

array_keys()
array_keys()的作用是返回数组中所有的键名
array_keys ( array $input [, mixed $search_value = NULL [, bool $strict = false ]] )

  • input 一个数组,包含了要返回的键。
  • search_value 如果指定了这个参数,只有包含这些值的键才会返回。
  • strict 判断在搜索的时候是否该使用严格的比较(===)。
$arr = array(10,20,30,"10");
print_r(array_keys($arr));
/*Array([0] => 0 [1] => 1 [2] => 2 [3] => 3)*/
print_r(array_keys($arr,10));
/*Array([0] => 0 [3] => 3)*/
print_r(array_keys($arr,"10",true));
/*Array([3] => 3)*/

in_array()
in_array()的作用是检查数组中是否存在某个值,即在数组中搜索给定的值
in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )

  • needle 待搜索的值。如果 needle 是字符串,则比较是区分大小写的。
  • haystack 这个数组。
  • strict 如果第三个参数 strict 的值为 TRUE 则 in_array() 函数还会检查 needle 的类型是否和 haystack 中的相同。
$os  = array( "Mac" ,  "NT" ,  "Irix" ,  "Linux" );
if ( in_array ( "Irix" ,  $os )) {
    echo  "Got Irix" ;  //Got Irix
}
if ( in_array ( "mac" ,  $os )) {  //区分大小写
    echo  "Got mac" ;
}
$a  = array( '1.10' ,  12.4 ,  1.13 );
if ( in_array ( '12.4' ,  $a ,  true )) {  //类型不同
    echo  "'12.4' found with strict check\n" ;
}
if ( in_array ( 1.13 ,  $a ,  true )) {
    echo  "1.13 found with strict check\n" ; //1.13 found with strict check
}
$a  = array(array( 'p' ,  'h' ), array( 'p' ,  'r' ),  'o' );
if ( in_array (array( 'p' ,  'h' ),  $a )) {
    echo  "'ph' was found\n"  ;  //'ph' was found
}

array_search()
在数组中搜索给定的值,如果成功则返回相应的键名
array_search ( mixed $needle , array $haystack [, bool $strict = false ] )
如果找到了 needle 则返回它的键,否则返回 FALSE 。
如果 needle 在 haystack 中出现不止一次,则返回第一个匹配的键

$array  = array( 0  =>  'blue' ,  1  =>  'red' ,  2  =>  'green' ,  3  =>  'red' );
 $key  =  array_search ( 'green' ,  $array );  // $key = 2;
 $key  =  array_search ( 'red' ,  $array );// $key = 1;
 $key = array_search('orange',$array);  //false

array_key_exists()
array_key_exists() 在给定的 key 存在于数组中时返回 TRUE 。key 可以是任何能作为数组索引的值。 array_key_exists() 也可用于对象。
array_key_exists ( mixed $key , array $search )

  • key 要检查的键。
  • search 一个数组,包含待检查的键。
$search_array  = array( 'first' => null , 'second' =>  4 );
array_key_exists ( 'first' , $search_array );  // returns true

array_filp()
array_flip ( array $trans )
array_flip() 返回一个反转后的 array ,例如 trans 中的键名变成了值,而 trans 中的值成了键名。
如果同一个值出现了多次,则最后一个键名将作为它的值,所有其它的都丢失了。

$trans  = array( "a"  =>  1 ,  "b"  =>  1 ,  "c"  =>  2 );
 $trans  =  array_flip ( $trans );
 print_r ( $trans ); //Array([1] => b [2] => c)

array_reverse()
array_reverse ( array $array [, bool $preserve_keys = false ] )
array_reverse() 接受数组 array 作为输入并返回一个单元为相反顺序的新数组。

$input   = array( 4.0 ,"php" ,array( "green" , "red" ));
$result_keyed  =  array_reverse ( $input);
print_r($result_keyed);
/*Array
(
    [0] => Array([0] => green [1] => red)
    [1] => php
    [2] => 4
)*/

7.5.2 统计数组元素的个数和唯一性

count()
统计一个数组里的所有元素,或者一个对象里的东西。
count ( mixed $var [, int $mode = COUNT_NORMAL ] )
array_count_values()
统计数组中所有的值出现的次数
array_count_values ( array $input )返回一个数组,该数组用 input 数组中的值作为键名,该值在 input 数组中出现的次数作为值。

$array  = array( 1 ,  "hello" ,  1 ,  "world" ,  "hello" );
 print_r ( array_count_values ( $array ));
/* Array([1] => 2 [hello] => 2 [world] => 1)*/

array_unique()
移除数组中重复的值
接受 array 作为输入并返回没有重复值的新数组。注意键名保留不变。先将值作为字符串排序,然后对每个值只保留第一个遇到的键名,接着忽略所有后面的键名。

$input  = array( "a"  =>  "green" ,  "red" ,  "b"  =>  "green" ,  "blue" ,  "red" );
 $result  =  array_unique ( $input );
 print_r ( $result );
 //Array( [a] => green [0] => red [1] => blue )
7.5.3 使用回调函数处理数组的函数

array_filter()
用回调函数过滤数组中的单元
array_filter ( array $input [, callable $callback = "" ] )
依次将 input 数组中的每个值传递到 callback 函数。如果 callback 函数返回 TRUE ,则 input 数组的当前值会被包含在返回的结果数组中。数组的键名保留不变。
如果没有提供 callback 函数, 将删除 input 中所有等值为 FALSE 的条目。

function  odd ( $var ){
     return( $var  &  1 );
}
function  even ( $var ){
     return(!( $var  &  1 ));
}
 $array1  = array( "a" => 1 ,  "b" => 2 ,  "c" => 3 ,  "d" => 4 ,  "e" => 5 );
 $array2  = array( 6 ,  7 ,  8 ,  9 ,  10 ,  11 ,  12 );
echo  "Odd :\n" ;
 print_r ( array_filter ( $array1 ,  "odd" ));
echo  "Even:\n" ;
 print_r ( array_filter ( $array2 ,  "even" ));
/*Odd :
Array( [a] => 1 [c] => 3 [e] => 5 )
Even:
Array( [0] => 6 [2] => 8 [4] => 10 [6] => 12 )*/

array_walk()
使用用户自定义函数对数组中的每个元素做回调处理
bool array_walk ( array &$array , callable $funcname [, mixed $userdata = NULL ] )
将用户自定义函数 funcname 应用到 array 数组中的每个单元。array_walk() 不会受到 array 内部数组指针的影响。 array_walk() 会遍历整个数组而不管指针的位置
成功时返回 TRUE , 或者在失败时返回 FALSE 。

$fruits  = array( "d"  =>  "lemon" ,  "a"  =>  "orange" ,  "b"  =>  "banana" ,  "c"  =>  "apple" );
function  test_alter (& $item1 ,  $key ,  $prefix ){
     $item1  =  " $prefix :  $item1 " ;
}
function  test_print ( $item2 ,  $key ){
    echo  " $key .  $item2 <br />\n" ;
}
echo  "Before ...:\n" ;
array_walk ( $fruits ,  'test_print' );
array_walk ( $fruits ,  'test_alter' ,  'fruit' );
echo  "... and after:\n" ;
array_walk ( $fruits ,  'test_print' );

array_map()
将回调函数作用到给定数组的单元上
array array_map ( callable $callback , array $arr1 [, array $... ] )
返回一个数组,该数组包含了 arr1 中的所有单元经过 callback 作用过之后的单元。callback 接受的参数数目应该和传递给 array_map() 函数的数组数目一致。

function  cube ( $n ){
    return( $n  *  $n  *  $n );
}
$a  = array( 1 ,  2 ,  3 ,  4 ,  5 );
$b  =  array_map ( "cube" ,  $a );
print_r ( $b );
//Array( [0] => 1  [1] => 8 [2] => 27 [3] => 64 [4] => 125 )
7.5.4 数组的排序函数

排序函数

usort()
使用用户自定义的比较函数对数组中的值进行排序
bool usort ( array &$array , callable $cmp_function )
本函数将用用户自定义的比较函数对一个数组中的值进行排序。如果要排序的数组需要用一种不寻常的标准进行排序,那么应该使用此函数。

function  cmp ( $a ,  $b ){
    if ( $a  ==  $b ) {
        return  0 ;
    }
    return ( $a  <  $b ) ? - 1  :  1 ;
}
 $a  = array( 3 ,  2 ,  5 ,  6 ,  1 );
 usort ( $a ,  "cmp" );
 print_r($a);
//Array( [0] => 1 [1] => 2 [2] => 3 [3] => 5 [4] => 6 )

array_multisort()
bool array_multisort ( array &$arr [, mixed $arg = SORT_ASC [, mixed $arg = SORT_REGULAR [, mixed $... ]]] )
可以用来一次对多个数组进行排序,或者根据某一维或多维对多维数组进行排序。
排序顺序标志:

  1. SORT_ASC - 按照上升顺序排序
  2. SORT_DESC - 按照下降顺序排序

排序类型标志:

  1. SORT_REGULAR - 将项目按照通常方法比较
  2. SORT_NUMERIC - 将项目按照数值比较
  3. SORT_STRING - 将项目按照字符串比较

每个数组之后不能指定两个同类的排序标志。每个数组后指定的排序标志仅对该数组有效 - 在此之前为默认值 SORT_ASC 和 SORT_REGULAR 。

$ar1  = array( 10 ,  100 ,  100 ,  0 );
 $ar2  = array( 1 ,  3 ,  2 ,  4 );
 array_multisort ( $ar1 ,  $ar2 );
 var_dump ( $ar1 );
 var_dump ( $ar2 );
 /*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)
 }*/
 $ar  = array(
        array( "10" ,  11 ,  100 ,  100 ,  "a" ),
        array(    1 ,   2 ,  "2" ,    3 ,    1 )
       );
  array_multisort ( $ar [ 0 ],  SORT_ASC ,  SORT_STRING ,$ar [ 1 ],  SORT_NUMERIC ,  SORT_DESC );
  var_dump ( $ar );
  /*
  array(2) {
    [0]=> array(5) {
      [0]=> string(2) "10"
      [1]=> int(100)
      [2]=> int(100)
      [3]=> int(11)
      [4]=> string(1) "a"
    }
    [1]=> array(5) {
      [0]=> int(1)
      [1]=> int(3)
      [2]=> string(1) "2"
      [3]=> int(2)
      [4]=> int(1)
    }
  }
   */
7.5.5 拆分 合并 分解 接合数组

array_slice()
array array_slice ( array $array , int $offset [, int $length = NULL [, bool $preserve_keys = false ]] )
返回根据 offset 和 length 参数所指定的 array 数组中的一段序列。

  • array 输入的数组。
  • offset 如果 offset 非负,则序列将从 array 中的此偏移量开始。如果 offset 为负,则序列将从 array 中距离末端这么远的地方开始。
  • length 如果给出了 length 并且为正,则序列中将具有这么多的单元。如果给出了 length 并且为负,则序列将终止在距离数组末端这么远的地方。如果省略,则序列将从 offset 开始一直到 array 的末端。
  • preserve_keys
    注意 array_slice() 默认会重新排序并重置数组的数字索引。你可以通过将 preserve_keys 设为 TRUE 来改变此行为。
$input  = array( "a" ,  "b" ,  "c" ,  "d" ,  "e" );

 $output  =  array_slice ( $input ,  2 );       // returns "c", "d", and "e"
 $output  =  array_slice ( $input , - 2 ,  1 );   // returns "d"
 $output  =  array_slice ( $input ,  0 ,  3 );    // returns "a", "b", and "c"
// note the differences in the array keys
 print_r ( array_slice ( $input ,  2 , - 1 ));
//Array( [0] => c [1] => d )
 print_r ( array_slice ( $input ,  2 , - 1 ,  true ));
//Array( [2] => c [3] => d )

array_splice()
array array_splice ( array &$input , int $offset [, int $length = 0 [, mixed $replacement ]] )
把 input 数组中由 offset 和 length 指定的单元去掉,如果提供了 replacement 参数,则用其中的单元取代。

$input  = array( "red" ,  "green" ,  "blue" ,  "yellow" );
array_splice ( $input , - 1 ,  1 , array( "black" ,  "maroon" ));
// $input is now array("red", "green","blue", "black", "maroon")

array_combine()
array array_combine ( array $keys , array $values )
返回一个 array ,用来自 keys 数组的值作为键名,来自 values 数组的值作为相应的值。

$a  = array( 'green' ,  'red' ,  'yellow' );
 $b  = array( 'avocado' ,  'apple' ,  'banana' );
 $c  =  array_combine ( $a ,  $b );
 print_r ( $c );
 //Array([green]  => avocado [red]    => apple [yellow] => banana )

array_merge()
array array_merge ( array $array1 [, array $... ] )
将一个或多个数组的单元合并起来,一个数组中的值附加在前一个数组的后面。返回作为结果的数组。
如果输入的数组中有相同的字符串键名,则该键名后面的值将覆盖前一个值。然而,如果数组包含数字键名,后面的值将不会覆盖原来的值,而是附加到后面。
如果只给了一个数组并且该数组是数字索引的,则键名会以连续方式重新索引。

$array1  = array( 0  =>  'zero_a' ,  2  =>  'two_a' ,  3  =>  'three_a' );
 $array2  = array( 1  =>  'one_b' ,  3  =>  'three_b' ,  4  =>  'four_b' );
 $result  =  $array1  +  $array2 ;
 print_r( $result );
 //Array( [0] => zero_a [2] => two_a [3] => three_a [1] => one_b [4] => four_b)

array_intersect()
array array_intersect ( array $array1 , array $array2 [, array $ ... ] ) 返回一个数组,该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。注意键名保留不变。

$array1  = array( "a"  =>  "green" ,  "red" ,  "blue" );
 $array2  = array( "b"  =>  "green" ,  "yellow" ,  "red" );
 $result  =  array_intersect ( $array1 ,  $array2 );
 print_r ( $result );
 //Array([a] => green [0] => red )

array_diff()
array array_diff ( array $array1 , array $array2 [, array $... ] )
对比返回在 array1 中但是不在 array2 及任何其它参数数组中的值。

$array1  = array( "a"  =>  "green" ,  "red" ,  "blue" ,  "red" );
 $array2  = array( "b"  =>  "green" ,  "yellow" ,  "red" );
 $result  =  array_diff ( $array1 ,  $array2 );
 print_r ( $result );
//Array( [1] => blue )
7.5.6 数组与数据结构

array_push()
array_push() 将 array 当成一个栈,并将传入的变量压入 array 的末尾。
array_pop()
array_pop() 弹出并返回 array 数组的最后一个单元,并将数组 array 的长度减一。如果 array 为空(或者不是数组)将返回 NULL
array_shift()
array_shift() 将 array 的第一个单元移出并作为结果返回,将 array 的长度减一并将所有其它单元向前移动一位。所有的数字键名将改为从零开始计数,文字键名将不变。
array_unshift()
将传入的单元插入到 array 数组的开头。注意单元是作为整体被插入的,因此传入单元将保持同样的顺序。所有的数值键名将修改为从零开始重新计数,所有的文字键名保持不变。

7.5.7 其他有用的数组处理函数

array_rand()
从数组中取出一个或多个随机的单元,并返回随机条目的一个或多个键。
如果你只取出一个, array_rand() 返回一个随机单元的键名,否则就返回一个包含随机键名的数组。这样你就可以随机从数组中取出键名和值。
shuffle()
本函数打乱(随机排列单元的顺序)一个数组。
array_sum()
array_sum() 将数组中的所有值的和以整数或浮点数的结果返回。
range()
建立一个包含指定范围单元的数组。

  • start 序列的第一个值。
  • limit 序列结束于 limit 的值。
  • step 如果给出了 step 的值,它将被作为单元之间的步进值。step 应该为正值。如果未指定,step 则默认为 1。
foreach ( range ( 0 ,  100 ,  10 ) as  $number ) {
    echo  $number ;
}
// array(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100)

第八章 PHP 面向对象的程序设计

8.2.1 类的声明
[修饰词]class 类名{
    对象的成员属性://对类的静态描述,可以是php中标量类型和复合类型
    对象的成员方法://对类的动态描述
}

类名和变量名、函数名命名规则相似
在类中声明成员属性时一定要使用关键字如 public private static var
成员方法的声明和函数完全一样,只不过可以加一些关键字控制成员方法的权限,如 public private static

8.3 通过类实例化对象

$变量名 = new 类名称([参数列表]) //对象实例化格式
在 php 中只要使用一次 new 关键字就会实例化出一个对象,并在堆内存中开辟一块自己的空间,每个对象之间都是相互独立的。

8.3.2 对象在内存中的分配

内存结构大体上分为 4 断:

  • 栈空间段
    空间小但被 CPU 访问的速度快。存放程序中临时创建的变量具有后进先出的特点,用于存储占用空间长度不变并且占用空间小的数据类型内存段。例如 int bool
  • 堆空间段
    存放程序运行中被动态分配的内存段,用于存储数据长度可变或占用内存较大的数据,例如 string array object
  • 初始化数据段
    存放程序静态分配的变量,例如已初始化的全局变量
  • 代码段
    用来存放可执行文件的操作指令 只准读取不准写入 function
8.3.3 对象中成员的访问
$引用名 =new 类名称([参数列表])
echo $引用名 -> 成员属性;     //获取属性值
$引用名 -> 成员属性 = 值;     //对属性赋值操作
$引用名 -> 成员方法;         //访问成员方法
8.3.4 特殊对象引用$this

对象一旦被创建,在对象的每个成员方法中都会存在一个特殊的对象引用$this,专门用来完成对象内部成员之间的访问

8.3.5 构造方法与析构方法

构造方法 对象创建完成后第一个被对象自动调用的方法,常用来执行一些初始化任务
构造方法名称必须是(php5) __construct()
同一个类只能声明一个构造方法
析构方法 对象被销毁前自动调用的方法,在垃圾回收程序回收对象之前调用,例如执行关闭文件,释放结果等操作
__destruct()不能带有任何参数

8.4 封装性

封装性就是把对象的成员属性和成员方法组合成一个独立的相同单位,并尽可能隐藏内部细节
在声明成员属性或成员方法时,使用 private 关键字修饰将成员属性和方法封装成私有,封装后的成员在外部不能被访问,但在对象内部成员的方法中可以访问到被封装的成员属性和方法。
在对象内部声明一些操作私有属性的公有方法,这样在对象外部就可以通过公有的方法作为访问接口,间接的访问对象内部私有成员

8.4.3 *set() _get() _isset() _unset()*方法

  • __set()
    在程序运行过程中为私有的成员属性设置值,自动调用。使得看上去像没被封装一样
  • __get()
    在程序运行时通过他可以在对象的外部获取私有成员的属性的值
  • __isset()
    当在类外部使用 isset()来测定对象里面的私有成员属性是否存在时,会自动调用_isset()来完成操作
  • _unset()
    删除私有成员属性,用法与_isset 类似

8.5 继承性

8.5.2 访问类型控制

访问控制修饰符号的区别与联系

同类访问 子类访问 外部访问
private true
protected true true
public true true true
8.5.3 子类重载父类的方法

在 PHP 中提供了在子类重载的方法中调用父类被覆盖方法的功能
parent::方法名
在子类中重写父类的方法时,一定要高于或等于父类被覆盖的方法的访问权限

8.6 常见的关键字和魔术方法

final 关键字作用:

  1. 使用 final 标识的类不能被继承
  2. 使用 final 标识的成员方法,在子类中不能被覆盖

static 关键字
static 可以将类中成员标识为静态,这个 static 成员属于类的,总是唯一的,与对象实例和其他的类无关
如果在类的外部访问类中的静态成员,通常使用类名来访问
如果在类的内部成员方法中访问其他的静态成员,通常使用 self 的形式 self::$count++;
const关键字
将类中的成员属性使用const关键字标识为常量,const声明的常量名称前不要使用$符号,而且常量名称通常都是大写的,其访问方式与静态成员一样

8.6.3 克隆对象

PHP5 中使用 clone 关键字克隆对象,原本和副本两个对象完全独立互不干扰

8.6.4 __tostring()

__tostring()是快速获取对象的字符串表示的最便捷方式,该方法中一定要有一个字符串作为返回值

8.6.5 __call()

如果在类中添加一个魔术方法__call(),则调用对象中不存在的方法时就会自动调用该方法,

function _call($functionName,$args){
    //code
}
8.6.6 自动加载类

PHP 提供了类的自动加载功能autoload(),当需要加载一个类时,PHP 会自动执行autoload()

function __autoload($className){
    include($className.".php");
}
$obj = new User();  //User类不存在则自动调用__autoload()函数,将类名user作为参数传入
8.6.7 对象串行化

串行化就是把整个对象转化为二进制字符串,有两种情况我们必须把对象串行化:

  1. 对象需要在网络中传输时,将对象串行化成二进制串后再网络中传输
  2. 对象需要长久保存时,将对象串行化后写入文件或是数据库中

serialize()函数用来串行化一个对象
unserialize()函数用来反串行化一个对象
在 php5 中还有两个魔术方法__sleep()__wakeup()
在调用 serialize()函数将对象串行化时会自动调用对象中的__sleep()方法
在调用 unserialize()函数将对象反串行化时会自动调用对象中的__wakeup()方法

8.7 抽象类与接口

8.7.1 抽象类

抽象方法就是没有方法体的方法,在声明抽象方法时,还要使用 abstract 来修饰
abstract function fun1() //没有花括号和方法体
抽象类也要使用 abstract 关键字来修饰,在抽象类中可以有不是抽象的成员方法和属性,但访问权限不能使用 private 关键字修饰为私有
抽象类的作用:
使用抽象类就包含了继承关系,它是为它的子类定义公共接口,将它的操作交给子类去实现。就是将抽象类作为子类的重载的模板使用。子类必须把父类中的抽象方法全部实现,否则子类还是抽象类不能实例化

8.7.2 接口技术

接口的声明使用 interface 关键字标识,不能再接口中声明变量,只能使用 const 关键字声明的常量
接口和抽象类一样不能实例化对象,也需要通过子类来实现
通过类继承接口时需要使用 implements 关键字来实现
通过抽象类去实现接口的部分方法时也需要使用 implements 关键字

PHP 是单继承的,一个类只能有一个父类,但是可以有多个接口

class className extends fatherClassName implements 接口1,接口2……{
    //实现所有接口中的抽象方法
}

8.8 多态性的应用

在 PHP 中多态性指的是方法的重载,重载要求子类的方法和父类的方法名称相同,可通过成名抽象类和接口来实现

第九章 字符串的处理与正则表达式

9.2 常用的字符串输出函数

printf()
int printf ( string $format [, mixed $args [, mixed $... ]] )
依据 format 格式参数产生输出格式化字符串 。
第一个参数中使用的转换格式是以%开始到转换字符结束

printf('There is a difference between %s and %s', 'good', 'evil');
//There is a difference between good and evil

sprintf()
sprintf()用法和 printf()相同,但它并不输出字符串

$num = 12345;
$txt = sprintf("%0.2f",$num);
echo $txt;

9.3 常见的字符串格式化函数

字符串格式化函数

9.4 字符串比较函数

strcmp(str1,str2) //区分字母大小写的比较
strcasecmp(str1,str2) //忽略字母大小写的比较
strnatcmp(str1,str2) //按自然排序法比较,区分大小写
strcasenatcmp(str1,str2) //按自然排序法比较,不区分大小写

9.5 正则表达式在字符串处理中的应用

9.5.2 正则表达式的语法规则

正则表达式中的元字符
正则表达式中的元字符

9.6 正则表达式函数

#####9.6.1 字符串的匹配与查找
preg_match()
int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )

  • pattern 要搜索的模式,字符串类型。
  • subject 输入字符串。
  • matches 如果提供了参数 matches,它将被填充为搜索结果。 $matches[0] 将包含完整模式匹配到的文本, $matches[1] 将包含第一个捕获子组匹配到的文本,以此类推。

preg_match() 返回 pattern 的匹配次数。 它的值将是 0 次(不匹配)或 1 次,因为 preg_match() 在第一次匹配后 将会停止搜索。preg_match_all() 不同于此,它会一直搜索 subject 直到到达结尾。 如果发生错误 preg_match() 返回 FALSE 。
preg_match_all()
int preg_match_all ( string $pattern , string $subject [, array &$matches [, int $flags = PREG_PATTERN_ORDER [, int $offset = 0 ]]] )
搜索 subject 中所有匹配 pattern 给定正则表达式的匹配结果并且将它们以 flag 指定顺序输出到 matches 中.

  • PREG_PATTERN_ORDER 结果排序为 $matches[0] 保存完整模式的所有匹配, $matches[1] 保存第一个子组的所有匹配,以此类推。
  • PREG_SET_ORDER 结果排序为 $matches[0] 包含第一次匹配得到的所有匹配(包含子组), $matches[1] 是包含第二次匹配到的所有匹配(包含子组)的数组,以此类推。

preg_grep()
array preg_grep ( string $pattern , array $input [, int $flags = 0 ] )
返回给定数组 input 中与模式 pattern 匹配的元素组成的数组.

如果只是查找一个字符串中是否包含某个子字符串,建议使用 strstr()或 strpos()
string strstr ( string $haystack , mixed $needle [, bool $before_needle = false ] )
返回 haystack 字符串从 needle 第一次出现的位置开始到 haystack 结尾的字符串。如果想要不区分大小写,请使用 stristr() 。
mixed strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )
返回 needle 在 haystack 中首次出现的数字位置。
如果只是简单的从一个字符串中取出一段子字符串,建议使用 substr()

preg_replace()
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
搜索 subject 中匹配 pattern 的部分, 以 replacement 进行替换。
limit 每个模式在每个 subject 上进行替换的最大次数。默认是 -1(无限)。

str_replace()
mixed str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] )
该函数返回一个字符串或者数组。该字符串或数组是将 subject 中全部的 search 都被 replace 替换之后的结果。
preg_split()
array preg_split( string $pattern, string $subject [, int $limit = -1 [, int $flags = 0 ]] )
通过一个正则表达式分隔给定字符串.返回一个使用 pattern 边界分隔 subject 后得到的子串组成的数组。
explode()
array explode ( string $delimiter , string $string [, int $limit ] )
此函数返回由字符串组成的数组,每个元素都是 string 的一个子串,它们被字符串 delimiter 作为边界点分割出来。
implode()
string implode ( string $glue , array $pieces )
用 glue 将一维数组的值连接为一个字符串。

第十章 PHP 常用功能模块

10.1 错误和异常处理

不显示 Notice 消息的方法:

  • 在配置文件中修改 error_reporting = E_ALL & ~E_NOTICE
  • 在当前脚本中设置 error_reporting(E_ALL & ~E_NOTICE);

10.2 日期和时间

10.2.1 UNIX 时间戳

time()
返回自从 Unix 纪元(格林威治时间 1970 年 1 月 1 日 00:00:00)到当前时间的秒数。
**mktime()**将日期和时间转化为 UNIX 时间戳
int mktime ([ int $hour = date("H") [, int $minute = date("i") [, int $second = date("s") [, int $month = date("n") [, int $day = date("j") [, int $year = date("Y") [, int $is_dst = -1 ]]]]]]] )
根据给出的参数返回 Unix 时间戳。时间戳是一个长整数,包含了从 Unix 纪元(January 1 1970 00:00:00 GMT)到给定时间的秒数。
参数可以从右向左省略,任何省略的参数会被设置成本地日期和时间的当前值。

echo  date ( "M-d-Y" ,  mktime ( 0 ,  0 ,  0 ,  12 ,  32 ,  1997 ));//Jan-01-1998
10.2.2 在 PHP 中获取日期和时间

getdate()
array getdate ([ int $timestamp = time() ] )
返回一个根据 timestamp 得出的包含有日期信息的关联数组 array 。如果没有给出时间戳则认为是当前本地时间。

print_r(getdate());
/*Array
(
    [seconds] => 20
    [minutes] => 51
    [hours] => 23
    [mday] => 11
    [wday] => 4
    [mon] => 8
    [year] => 2016
    [yday] => 223
    [weekday] => Thursday
    [month] => August
    [0] => 1470959480
)*/
10.2.3 日期和时间格式化输出

date()
string date ( string $format [, int $timestamp ] )
返回将整数 timestamp 按照给定的格式字串而产生的字符串。如果没有给出时间戳则使用本地当前时间。换句话说,timestamp 是可选的,默认值为 time() 。

print_r(date ( "Y-m-d H:i:s" ));//2016-08-12 07:58:15
10.2.4 修改默认时区
  1. 修改 php.ini 中的 date.timezone = PRC
  2. 在当前 php 文件中设置 date_default_timezone_set(‘PRC’)
10.2.5 使用微妙计算 PHP 时间

microtime()
mixed microtime ([ bool $get_as_float ] )
如果调用时不带可选参数,本函数以 “msec sec” 的格式返回一个字符串,其中 sec 是自 Unix 纪元(0:00:00 January 1, 1970 GMT)起到现在的秒数,msec 是微秒部分。字符串的两部分都是以秒为单位返回的。
如果给出了 get_as_float 参数并且其值等价于 TRUE , microtime() 将返回一个浮点数。

print_r(microtime()); //0.17703600 1470960354

10.3 动态图像处理

10.3.2 画布管理

创建画布
imagecreate(int $x_size,int $y_size)
imagecreatetruecolor(int $x_size,int $y_size)
获取图像的大小 imagesx(),imagesy();
画布的引用句柄不用时,一定要将其销毁 imagedestory()

10.3.3 设置颜色

int imagecolorallocate ( resource $image , int $red , int $green , int $blue )
$black = imagecolorallocate ( $im , 0 , 0 , 0 );

10.3.4 生成图像
  1. imagepng() - 以 PNG 格式将图像输出到浏览器或文件
  2. imagewbmp() - 以 WBMP 格式将图像输出到浏览器或文件
  3. imagejpeg() - 输出图象到浏览器或文件。
  4. imagegif() - 以 gif 格式将图像输出到浏览器或文件
  5. imagetypes() - 返回当前 PHP 版本所支持的图像类型
10.3.5 绘制图像

图像区域填充
bool imagefill ( resource $image , int $x , int $y , int $color )
绘制点和线
bool imagesetpixel ( resource $image , int $x , int $y , int $color )
bool imageline ( resource $image , int $x1 , int $y1 , int $x2 , int $y2 , int $color )
绘制矩形
bool imagerectangle ( resource $image , int $x1 , int $y1 , int $x2 , int $y2 , int $col )
bool imagefilledrectangle ( resource $image , int $x1 , int $y1 , int $x2 , int $y2 , int $color )画一矩形并填充

第十一章 文件系统处理

11.1.1 文件类型

string filetype ( string $filename )
返回文件的类型。 可能的值有 fifo,char,dir,block,link,file 和 unknown。

echo  filetype ( '/etc/passwd' );   // file
echo  filetype ( '/etc/' );         // dir

11.2 目录的基本操作

basename()返回路径中的文件名部分
dirname()返回去掉文件名后的目录
pathinfo()返回一个关联数组,包含指定路径中的目录名基本名和扩展名,分别通过数组键 dirname,basename,extension 来引用

11.3 文件的基本操作

**fopen()**打开文件或者 URL

resource fopen ( string $filename , string $mode [,bool $use_include_path =false  [, resource $context  ]] )

mode 参数指定了所要求到该流的访问类型。
fclose() 关闭一个已打开的文件指针
bool fclose ( resource $handle )
**fwrite()**写入文件(可安全用于二进制文件)

int fwrite  ( resource $handle  , string $string  [, int $length  ] )int fwrite  ( resource $handle  , string $string  [, int $length  ] )

第十二章 MySQl 数据库设计

12.1 数据库的连接与关闭

cmd mysql -h 服务器主机地址 -u 用户名 -p
Enter passward:
输入好后即可连接

12.1.4 创建、选择、查看数据库
CREATE DATABASE [IF NOT EXISTS] bookstore; //创建bookstore数据库
DROP DATABASE [IF EXISTS] bookstore; //删除bookstore数据库
SHOW DATABASES; //显示所有已建立的数据库名称列表
USE bookstore; //打开bookstore数据库作为当前数据库使用
21.2.3 数据字段属性

UNSIGNED 只能用于设置数值类型,不允许出现负数
ZEROFILL 只能用于设置数值类型,在数值之前自动用 0 补齐不足的位数
AUTO_INCREMENT 设置字段的自动增量属性,每增加一条记录,该字段的值就加 1
NULL NOT NULL
DEFAULT 指定默认值

12.2.4 创建、修改及删除表

创建数据表:

CREATETABLE [IF NOT EXISTS] 表名称(
    字段名1 列类型 [属性] [索引],
    字段名2 列类型 [属性] [索引],
    字段名3 列类型 [属性] [索引],
    字段名n 列类型 [属性] [索引]
)[表类型] [表字符集];

CREATE TABLE if not exists user(
    userId INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    userName VARCHAR(50) NOT NULL,
    userPass VARCHAR(50) NOT NULL,
    telNo VARCHAR(20) NOT NULL UNIQUE,
    sex ENUM('男','女') NOT NULL DEFAULT '男',
    brithday DATE NOT NULL DEFAULT '000-00-00',
    PRIMARY KEY(userId),
    INDEX username(userName,userPass)
)ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

ALTER TABLE //修改表
添加新字段
ALTER TABLE 表名 ADD 字段名 <建表语句>[FIRST|AFTER 列名]
若没指定可选的 first|after,则在列尾添加一列,否则在指定列添加新列

ALTER TABLE user ADD email VARCHAR(30) NOT NULL;
ALTER TABLE user ADD name VARCHAR(30) NOT NULL FIRST;
ALTER TABLE user ADD height DOUBLE NOT NULL DEFAULT '0.00' AFTER userPass;

修改原有字段
ALTER TABLE 表名 CHANGE(MODIFY) 列表 <建表语句>

ALTER TABLE users MODIFY telNo INT UNSIGNED DEFAULT '0'
ALTER TABLE users CHANGE telNo phone INT UNSIGNED DEFAULT '0'

CHANGE 除了更改类型外还能更改列名
desc 表名 //查看表结构
DROP TABLE [IF EXISTS] 表名 //删除不再使用的数据表

12.2.7 创建索引

在 MYSQL 中主要有四类索引:

  • PRIMARY KEY 主键索引
  • UNIQUE 唯一索引
  • INDEX 常规索引
  • FULLTEXT 全文索引

12.4 SQL 语言设计

12.4.2 使用 DML 命令操作数据表中的数据

使用 INSERT 语句向数据表中添加数据
INSERT INTO 表名(字段名 1,字段名 2……)VALUES(值 1,值 2……)(……);
INSERT INTO categories(pid,categoryName,categoryDesn)VALUES(0,'english','about english');
使用 UPDATE 语句更新数据表中存在的数据
UPDATE 表名 SET 字段名=值[,字段名=值] WHERE 条件;
UPDATE books SET price=24.00 WHERE bookId=2;
使用 DELETE 语句删除数据表中不需要的数据记录
DELETE FROM 表名 [WHERE 条件];
DELETE FROM books WHERE bookId=2;

12.4.3 使用 DQL 语句查询数据表中的数据

SELECT 字段名 FROM 表名;

12.5 使用 PHP 脚本向 mysql 服务器发送 SQL

resource mysql_connect  ([ string $server  [, string $username  [, string $password  [, bool $new_link  [, int $client_flags  ]]]]] )

选择已创建的数据库
mysql_select_db()

$lnk  =  mysql_connect ( 'localhost' ,  'mysql_user' ,  'mysql_password' )
       or die ( 'Not connected : '  .  mysql_error ());
mysql_select_db ( 'foo' , $lnk ) or die ( 'Can\'t use foo :'.mysql_error ());

执行 SQL 语句
mysql_query()
$result = mysql_query ( 'SELECT * WHERE 1=1' );
mysql_query() 在执行成功时返回 TRUE ,出错时返回 FALSE 。

第十三章 PHP 的 mysqli 扩展

13.2 使用 mysqli 类

连接 MySQL 服务器
$mysqli=new mysqli("localhost","mysql_user","mysql_pwd","mylib");
处理连接错误
mysqli_connect_errno()
关闭与 mysql 服务器连接
close();
执行 SQL 语句
query();
$mysqli->query("insert into 表名(列名1,列名2)values(值1,值2)")
成功时返回 true,错误时返回 false;
一次执行多条 SQL 语句用 multi_query()

13.3 使用 mysql_result 类

使用mysql_result类
使用mysql_result类

13.4 使用 mysql_stmt 类

使用mysql_stmt类
使用mysql_stmt类

第十五章 会话控制

15.2 会话跟踪的方式

  1. 使用超链接或者 header()重定向,通过 URL 附加参数的形式
  2. 使用 cookie 将用户信息保存于客户端电脑之中
  3. 使用 Session 将用户信息保存于服务器之中
bool setcookie  ( string $name  [, string $value  [, int $expire  = 0  [, string $path  [, string $domain  [, bool $secure  = false  [, bool $httponly  = false  ]]]]]] )

setcookie()必须在其他信息被输出到浏览器之前调用
setcookie("userName","jesse",time()+60*60*24*7);
任何从客户端发送过来的 cookie 信息,都会被保存在$_cookie全局数组中
print_r($\_cookie)
删除 cookie:

  1. 仅导入第一个参数来删除指定名称的 cookie 资料setcookie("account")
  2. 利用 setcookie()把 cookie 设定为已过期状态setcookie("account",time()-1)

15.4 session 的应用

bool session_start ( void )
session_start()会创建新会话或者重用现有会话。
使用该函数开启 session 之前不能有任何内容的输出,调用该函数会生成一个唯一的 Session ID 保存在客户端 cookie 中
注册和读取 session 变量都需要通过访问$_SESSION 超全局数组来完成
session_destory()结束当前会话,并清空所有会话资源

//第一步:开启Session并初使化
session_start();
//第二步:删除所有Session的变量,也可用unset($_SESSION[xxx])逐个删除
$_SESSION = array();
//第三步:如果使用基于Cookie的Session,使用setCooike()删除包含Session Id的Cookie
if (isset($_COOKIE[session_name()])) {
    setcookie(session_name(), '', time()-42000, '/');
}
//第四步:最后彻底销毁Session
session_destroy();

session 会因为下面两种状况自动消失

  1. 关闭浏览器
  2. 有效期限到期

通过 cookie 形式传递 session ID
如果客户端没有禁用 cookie 则在 PHP 脚本中通过 session_start()函数进行初始化后,服务器会自动发送 HTTP 表头将 session ID 保存到客户端 cookie 中
通过 url 形式传递 session ID
如果客户端不支持 cookie,可以手动在每个超链接中添加 session ID

session_start();
echo '<a href="demo.php?'.session_name().'='.session_id()'".>演示连接</a>';

第十六章 PHP 的模板技术 smarty

16.4.1 安装 smarty

在自己的项目中包含 smarty 类库,这样在移动项目时会带着 smarty,不需要改变 web 服务器配置
直接将 libs 文件夹复制到项目的主文件夹下
在执行的 PHP 脚本中通过 require()将 libs 目录中的 Smarty.class.php 类文件加载进来就可以了

16.5 Smarty 在应用程序逻辑层的使用步骤

  1. 加载 Smarty 模板引擎 require(“Smarty.class.php”);
  2. 建立 Smarty 对象 $smarty=new Smarty();
  3. 修改 Smarty 默认行为 开启缓存机制,修改模板默认存放目录;
  4. 将程序中动态获取的变量用 assign()方法置入模板
  5. 用 display()方法将模板输出

前三步是 Smarty 的核心,可放置在 main.inc.php 中

**assign()**方法
在 PHP 脚本中调用该方法可以为 Smarty 模板文件中的变量赋值

  1. 指定“名称/数值”的赋值方式$smarty->assign("name","jesse");
  2. 指定包含“名称/数组”的联合数组的使用方式$smarty->assign(array("city"=>"lincoln","state"=>"nabraska"));

**display()**方法
smarty 脚本中必须用到的方法,而且一个脚本中只能使用一次,他负责获取和显示 smarty 引擎引用的模板
Void display(string template[,string cache_id[,string compile_id]])
template 必选 需要指定一个合法的模板资源类型和路径
cache_id 可选 指定一个缓存标识符的名称
compile_id 可选 在维护一个页面的多个缓存时使用
获取和显示$template_dir属性所指定目录下的的模板文件
$smarty->display(“index.tpl”);
在 win 平台下绝对路径必须用 file:前缀,用来使用不在$template_dir模板目录下的文件
$smarty->display(“C:/www/pub/templates/header/tpl”);

16.6 Smarty 模板中的程序逻辑

smarty 引擎不仅在 php 逻辑层使用,在表现层也会偶尔使用(很简单)

16.6.1 模板中的注释

包围在定界符{**}之间的内容都是注释内容,是模板的内在注释

16.6.2 模板中变量的声明

smarty 有几种不同类型的变量,变量的类型取决于他的前缀是什么符号。
以下几个变量可以再 smarty 模板中直接输出

{$Name}                    {*常规类型变量*}
{$Contacts[row].Phone}     {*数组类型变量*}
<body bgcolor="{#bgcolor#}"> {*从配置文件中读取并输出的变量*}
16.6.3 在模板中输出从 PHP 中分配的变量

模板中只能输出从 PHP 中分配的变量,不能在模板中为这些变量重新赋值
在 Smarty 模板中变量的预设是全域的。只要分配一次就可以,分配两次以上以最后以此为主
通常在模板中通过遍历输出数组中的每个元素,通过 foreach 或 section 语句
在模板中单独输出数组中的某个元素
索引数组 和在 PHP 脚本的引用方式一样 {$contact2[1][2]}
关联数组 使用"."访问{$contact.email}
索引关联混合数组 {$contact2[1].name}
在 PHP 脚本中创建的对象类型变量也可以分配给模板,并访问对象中的每个成员,都是通过“->”运算符完成
{$person->name}
{$person->work()}

16.6.4 模板中变量的数学运算

在模板中的变量不能重新赋值,但是可以参与数学运算

{$foo+1}
{$foo*$bar}
{$foo->bar-$bar[1]*$baz->foo->bar()-3*7}     {*复合类型变量也可参与运算*}
{if($foo+$bar.test%$baz*134232+10+$b+10)}    {*可以将数学运算在程序逻辑中运用*}

在 Smarty 模板中可以识别嵌入在""中的变量,只要此变量名称只包含字母数字下划线或[]。若有其他符号,此变量必须用两个反引号``包住

16.6.5 在模板中使用{$smarty}保留变量

{$smarty}保留变量是可以在模板中直接访问的数组类型变量,通常用于访问一些特殊模板变量 1.在模板中访问页面请求变量

{$smarty.get.page}          {* 类似在PHP脚本中访问$_GET["page"] *}
{$smarty.post.page}         {* 类似在PHP脚本中访问$_POST['page'] *}
{$smarty.cookies.username}  {* 类似在PHP脚本中访问$_COOKIE['username']*}
{$smarty.server.SERVER_NAME}{* 类似在PHP脚本中访问$_SERVER['SERVER_NAME']*}
{$smarty.env.PATH}          {* 类似在PHP脚本中访问$_EVN["PATH"] *}
{$smarty.request.username}  {* 类似在PHP脚本中访问$_REQUEST["username"]*}

2.在模板中访问 PHP 中的常量

{$smarty.const._MY_CONST_VAL}  {*在模板中输出php脚本中用户自定义的常量*}
{$smarty.const._FILE_}         {*在模板中通过保留变量数组直接输出系统常量*}
16.6.6 变量调节器

变量在模板中输出以前如果需要调解,可以在该变量后面跟一个“|”,在后面使用调解命令。可以使用多个修改器按设定好的顺序依次组合使用
{$articleTitle|lower|spacify|truncate}
truncate()在截取中文时需要修改

16.6.7 模板的控制结构
  1. 条件选择结构 if-elseif-else
    {if}{/if}必须成对出现,中间的修饰词 eq 等等必须和变量或常量用空格隔开

  2. 重复的区块 foreach
    {foreach}{/foreach}必须成对出现

    属性 类型 是否必须 缺省值 描述
    from array Yes n/a 待循环数组的名称
    item string Yes n/a 当前处理元素的变量名称
    key string No n/a 当前处理元素的键名
    name string No n/a 该循环的名称,用于访问该循环

    foreachelse 标记一定要与 foreach 一起使用,与 ifelse 相似
    关联数组和索引数组都可以用 foreach 遍历

  3. 重复的区块 section 改进版的 foreach

    属性 类型 是否必须 缺省值 描述
    name string Yes n/a 该循环的名称
    loop [$variable_name] Yes n/a 决定循环次数的数组变量名称
    start integer No 0 循环执行的初始位置

    如果 start 值为负数,开始位置从数组的尾部算起. 例如:如果数组中有 7 个元素,指定 start 为-2,那么指向当前数组的索引为 5. 非法值(超过了循环数组的下限)将被自动调整为最接近的合法值.
    step integer No 1 该值决定循环的步长. 例如指定 step=2 将只遍历下标为 0、2、4 等的元素. 如果 step 为负值,那么遍历数组的时候从后向前遍历.
    max integer No 1 设定循环最大执行次数.
    show boolean No true 决定是否显示该循环.
    section 遍历的数组必须是下表从 0 开始的顺序索引数组
    section 标记也可以使用可选的 sectionelse 子标记,当 loop 属性指定的数组为空时,输出 sectionelse 区域中的内容,必须与 section 一起使用

  4. 重复区块中可供调用的变量
    在 section 和 foreach 循环中都有可供调用的变量,都必须通过$smarty进行访问
    {$smarty.foreach.foreachname.varname}
    $smarty.foreach 是 Smarty 保留变量
    foreachname 在 foreach 标记指定的 name 属性值
    varname 在循环中被调用的特定变量名称
    foreach 循环区域中可调用的变量

    变量名 描述
    iteration 用于显示当前循环的执行次数,总是从 1 开始,每执行一次增加 1
    first 当前 foreach 循环第一次执行时 first 被设置成 true.
    last 当前 foreach 循环执行到最后一遍时 last 被设置成 true.
    show 是 foreach 的一个参数. 取值为布尔值 true 或 false. 如果指定为 false 该循环不显示,如果循环指定了 foreachelse 子句,该子句显示与否也取决于 show 的取值.
    total 用于显示循环执行的次数,可以在循环中或循环执行后调用.

    section 循环中调用可供变量的方式与 foreach 相似

16.6.8 在模板中包含子模板

如果在多个模板中有相同的输出内容,这些相同的部分可在独立的模板中定义,在需要的模板中将其用 include 标记导入,但必须指定模板资源的位置。
一般头部文件和尾部文件都可作为独立的模板导入

{include file="header.tpl"}
{include file="footer.tpl"}

在 include 标记中还有两个比较实用的特性

  1. assign 属性
    将导入的子模板内容不在当前模板中输出,而是赋给由 assign 指定的变量
    {include file="header.tpl" assign="header"}{*模板header.tpl中的全部内容以字符串的形式赋值给变量header,再通过{$header}将子模板输出*}
  2. 可以在导入子模板的同时向其传递各种属性
    {include file="header.tpl" title="menu" table_bgcolor="#ccc"}
    以此方式传递的各种属性只能在被导入的文件中使用,不能用于模板的其他位置。如果模板中有同名变量,则会被传递的属性替代
16.7.2 加载配置文件

{config_load file="foo.conf" section="customer"}{*加载foo.conf中第一节customer中的变量*}

16.7.3 引用配置文件中的变量

配置文件中的变量需要通过两个##或者是$smarty.config 来调用

{#pageTitle#}
{$smarty.config.pageTitle}
16.8.3 緩存

is_cached() 判断指定模板的缓存是否存在
clear_all_cache()清除所有缓存
clear_cache()清除单个缓存

16.8.5 关闭局部缓存

1、使用{insert}使模板的一部分不被缓存
2、使用$smarty->register_function($params.&$smarty)阻止插件从缓存中输出
3、使用$smarty->register_block($params,&$samrty)是整篇页面的某一块不被缓存

文章目录

  1. 第五章 PHP 的基本语法
    1. 5.2.4 在程序中使用空白的处理
    2. 5.3 变量
      1. 5.3.1 变量的声明
      2. 5.3.2 变量的命名
      3. 5.3.4 变量的引用赋值
    3. 变量的类型
      1. 5.4.1 类型的介绍
      2. 5.4.3 布尔型
      3. 5.4.4 整型
      4. 5.4.5 字符串
      5. 5.4.6 数组
      6. 5.4.7 对象
      7. 5.4.8 资源类型
      8. 5.4.9 null
      9. 5.4.11 数据类型转换
    4. 5.5 常量
    5. 5.5.1 常量的定义和使用
      1. 5.5.2 常量和变量
    6. 5.6 PHP 中运算符
      1. 5.6.1 算数运算符
      2. 5.6.6 位运算符
      3. 5.6.7 其他运算符
  2. 第六章 PHP 语言结构
    1. 6.1 流程控制
    2. 6.3.4 特殊的流程控制语句
    3. 6.4 PHP 中的函数
      1. 6.4.4 PHP 变量的范围
      2. 6.4.5 参数的传递
      3. 6.4.6 变量函数
  3. 第七章 PHP 中的数组及数组结构
    1. 7.2 数组的定义
      1. 7.2.1 直接赋值方式声明数组
      2. 7.2.2 使用 array()构建新数组
      3. 7.2.3 多维数组的声明
    2. 7.3 数组的遍历
      1. 7.3.2 使用 foreach 语句遍历数组
      2. 7.3.3 联合使用 list() each()和 while 循环遍历数组
      3. 7.3.4 使用数组内部指针控制函数遍历数组
    3. 7.4 预定义数组
    4. 7.5 数组的相关处理函数
      1. 7.5.1 数组的键值操作函数
    5. 7.5.2 统计数组元素的个数和唯一性
      1. 7.5.3 使用回调函数处理数组的函数
      2. 7.5.4 数组的排序函数
      3. 7.5.5 拆分 合并 分解 接合数组
      4. 7.5.6 数组与数据结构
      5. 7.5.7 其他有用的数组处理函数
  4. 第八章 PHP 面向对象的程序设计
    1. 8.2.1 类的声明
  5. 8.3 通过类实例化对象
    1. 8.3.2 对象在内存中的分配
    2. 8.3.3 对象中成员的访问
    3. 8.3.4 特殊对象引用$this
    4. 8.3.5 构造方法与析构方法
  6. 8.4 封装性
  7. 8.4.3 *set() _get() _isset() _unset()*方法
  8. 8.5 继承性
    1. 8.5.2 访问类型控制
    2. 8.5.3 子类重载父类的方法
  9. 8.6 常见的关键字和魔术方法
    1. 8.6.3 克隆对象
    2. 8.6.4 __tostring()
    3. 8.6.5 __call()
    4. 8.6.6 自动加载类
    5. 8.6.7 对象串行化
  10. 8.7 抽象类与接口
    1. 8.7.1 抽象类
    2. 8.7.2 接口技术
  11. 8.8 多态性的应用
  • 第九章 字符串的处理与正则表达式
    1. 9.2 常用的字符串输出函数
    2. 9.3 常见的字符串格式化函数
    3. 9.4 字符串比较函数
    4. 9.5 正则表达式在字符串处理中的应用
      1. 9.5.2 正则表达式的语法规则
    5. 9.6 正则表达式函数
  • 第十章 PHP 常用功能模块
    1. 10.1 错误和异常处理
    2. 10.2 日期和时间
      1. 10.2.1 UNIX 时间戳
      2. 10.2.2 在 PHP 中获取日期和时间
      3. 10.2.3 日期和时间格式化输出
      4. 10.2.4 修改默认时区
      5. 10.2.5 使用微妙计算 PHP 时间
    3. 10.3 动态图像处理
      1. 10.3.2 画布管理
      2. 10.3.3 设置颜色
      3. 10.3.4 生成图像
      4. 10.3.5 绘制图像
  • 第十一章 文件系统处理
    1. 11.1.1 文件类型
  • 11.2 目录的基本操作
  • 11.3 文件的基本操作
  • 第十二章 MySQl 数据库设计
    1. 12.1 数据库的连接与关闭
      1. 12.1.4 创建、选择、查看数据库
      2. 21.2.3 数据字段属性
      3. 12.2.4 创建、修改及删除表
      4. 12.2.7 创建索引
    2. 12.4 SQL 语言设计
      1. 12.4.2 使用 DML 命令操作数据表中的数据
      2. 12.4.3 使用 DQL 语句查询数据表中的数据
    3. 12.5 使用 PHP 脚本向 mysql 服务器发送 SQL
  • 第十三章 PHP 的 mysqli 扩展
    1. 13.2 使用 mysqli 类
    2. 13.3 使用 mysql_result 类
    3. 13.4 使用 mysql_stmt 类
  • 第十五章 会话控制
    1. 15.2 会话跟踪的方式
    2. 15.3 cookie 的应用
    3. 15.4 session 的应用
  • 第十六章 PHP 的模板技术 smarty
    1. 16.4.1 安装 smarty
  • 16.5 Smarty 在应用程序逻辑层的使用步骤
  • 16.6 Smarty 模板中的程序逻辑
    1. 16.6.1 模板中的注释
    2. 16.6.2 模板中变量的声明
    3. 16.6.3 在模板中输出从 PHP 中分配的变量
    4. 16.6.4 模板中变量的数学运算
    5. 16.6.5 在模板中使用{$smarty}保留变量
    6. 16.6.6 变量调节器
    7. 16.6.7 模板的控制结构
    8. 16.6.8 在模板中包含子模板
    9. 16.7.2 加载配置文件
    10. 16.7.3 引用配置文件中的变量
    11. 16.8.3 緩存
    12. 16.8.5 关闭局部缓存