PHP知识点总结(二)

数组


PHP数组之索引数组初始化

PHP有两种数组:索引数组、关联数组。

索引和关联两个词都是针对数组的键而言的。

先介绍下索引数组,索引数组是指数组的键是整数的数组,并且键的整数顺序是从0开始,依次类推。

下面使用图来说明一下:

可以使用下面代码实现:

$fruit = array("苹果","香蕉","菠萝"); 注意数组的键是从0开始的。可以使用print_r($fruit);语句输出数组键及对应的值。

[php] view plain copy
  1. <?php  
  2. //创建一个索引数组,索引数组的键是“0”,值是“苹果”  
  3. $fruit = array("苹果",'香蕉','菠萝');  
  4. echo '<pre>';  
  5. print_r( $fruit );  
  6. echo '</pre>';  
  7. ?>  
  8.   
  9. 输出  
  10. <pre>Array  
  11. (  
  12.     [0] => 苹果  
  13.     [1] => 香蕉  
  14.     [2] => 菠萝  
  15. )  

PHP数组之索引数组赋值

索引数组赋值有三种方式:

第一种:用数组变量的名字后面跟一个中括号的方式赋值,当然,索引数组中,中括号内的键一定是整数。比如,$arr[0]='苹果';

第二种:用array()创建一个空数组,使用=>符号来分隔键和值,左侧表示键,右侧表示值。当然,索引数组中,键一定是整数。比如,array('0'=>'苹果');

第三种:用array()创建一个空数组,直接在数组里用英文的单引号'或者英文的双引号"赋值,数组会默认建立从0开始的整数的键。比如array('苹果');这个数组相当于array('0'=>'苹果');

[php] view plain copy
  1. <?php  
  2. $arr=array('0'=>'苹果','1'=>'西瓜');  
  3. $arr1 = array("苹果",'香蕉','菠萝');  
  4. $arr2=array();  
  5. $arr2[0]="苹果";  
  6. $arr2[1]="香蕉";  
  7. $arr2[2]="菠萝";  
  8. print_r($arr);  
  9. echo '<pre>';  
  10. print_r( $arr1 );  
  11. echo '</pre>';  
  12. echo '<pre>';  
  13. print_r( $arr2 );  
  14. echo '</pre>';  
  15. ?>  
  16. //////  
  17.   
  18. (  
  19.     [0] => 苹果  
  20.     [1] => 香蕉  
  21.     [2] => 菠萝  
  22. )  
Array
(
    [0] => 苹果
    [1] => 香蕉
    [2] => 菠萝
)

PHP数组之访问索引数组内容

有的时候我们需要把数组中的内容也就是值取出来该怎么办呢?用数组变量的名字后跟的中括号中的键,来访问数组中的值。
[php] view plain copy
  1. <?php  
  2. //从数组变量$arr中,读取键为0的值  
  3. $arr = array('苹果','香蕉');  
  4. $arr0 = $arr['0'];  
  5. if( isset($arr0) ) {print_r($arr0);}  
  6. ?>  
  7. //////  
  8. <pre>苹果  
  9. isset()在php中用来检测变量是否设置,该函数返回的是否布尔值,即true/false。  

PHP数组之for循环访问索引数组里的值

for循环可以将数组里的所有值都访问到,用for循环访问索引数组里的值。
[php] view plain copy
  1. <?php  
  2. $fruit=array('苹果','香蕉','菠萝');  
  3. for($index=0; $index<3; $index++){  
  4.     echo '数组第'.$index.'值是:'.$fruit[$index]."<br/>";  
  5. }  
  6. ?>  
  7. //////  
  8. 数组第0值是:苹果  
  9. 数组第1值是:香蕉  
  10. 数组第2值是:菠萝  

PHP数组之foreach循环访问索引数组里的值

foreach循环可以将数组里的所有值都访问到,用foreach循环访问索引数组里的值。
[php] view plain copy
  1. <?php  
  2.     $fruit=array('苹果','香蕉','菠萝');  
  3.     foreach($fruit as $key=>$value){  
  4.         echo '第'.$key.'值是:'.$value.'<br/>';  
  5.     }  
  6.     foreach($fruit as $value){  
  7.         echo $value.'<br/>';  
  8.     }  
  9. ?>  
  10. //////  
  11. 第0值是:苹果  
  12. 第1值是:香蕉  
  13. 第2值是:菠萝  
  14. 苹果  
  15. 香蕉  
  16. 菠萝  

PHP数组之关联数组初始化

PHP有两种数组:索引数组、关联数组。

索引和关联两个词都是针对数组的键而言的。

先介绍下,关联数组是指数组的键是字符串的数组。

[php] view plain copy
  1. <?php  
  2.     $fruit = array(  
  3.         'apple'=>"苹果",  
  4.         'banana'=>"香蕉",  
  5.         'pineapple'=>"菠萝"  
  6.     );   
  7.     print_r($fruit)  
  8. ?>  
  9. //////  
  10. Array ( [apple] => 苹果 [banana] => 香蕉 [pineapple] => 菠萝 )  

PHP数组之关联数组赋值

关联数组赋值有两种方式:

第一种:用数组变量的名字后面跟一个中括号的方式赋值,当然,关联数组中,中括号内的键一定是字符串。比如,$arr['apple']='苹果';

第二种:用array()创建一个空数组,使用=>符号来分隔键和值,左侧表示键,右侧表示值。当然,关联数组中,键一定是字符串。比如,array('apple'=>'苹果');

[php] view plain copy
  1. <?php  
  2.     $arr = array('apple'=>'苹果','pineapple'=>'菠萝');  
  3.     if( isset($arr)){  
  4.         print_r($arr);  
  5.     }  
  6. ?>  
  7. //////  
  8. Array ( [apple] => 苹果 [pineapple] => 菠萝 )  

PHP数组之访问关联数组内容

用数组变量的名字后跟中括号+键的方式来访问数组中的值,键使用单引号或者双引号括起来。

[php] view plain copy
  1. <?php  
  2.     $fruit = array('apple'=>"苹果",'banana'=>"香蕉",'pineapple'=>"菠萝");   
  3.     $fruit0 = $fruit['banana'];  
  4.     print_r($fruit0);  
  5. ?>  
  6. //////  
  7. 香蕉  

PHP数组之foreach循环访问关联数组里的值

foreach循环可以将数组里的所有值都访问到,用foreach循环访问关联数组里的值。
[php] view plain copy
  1. <?php  
  2.     $fruit=array('apple'=>"苹果",'banana'=>"香蕉",'pineapple'=>"菠萝");  
  3.     foreach($fruit as $k=>$v){  
  4.         echo '水果的英文键名:'.$k.',对应的值是:'.$v.'<br/>';  
  5.     }  
  6. ?>  
  7. //////  
  8. 水果的英文键名:apple,对应的值是:苹果  
  9. 水果的英文键名:banana,对应的值是:香蕉  
  10. 水果的英文键名:pineapple,对应的值是:菠萝  

函数

PHP自定义函数

PHP内置了超过1000个函数,因此函数使得PHP成为一门非常强大的语言。大多数时候我们使用系统的内置函数就可以满足需求,但是自定义函数通过将一组代码封装起来,使代码进行复用,程序结构与逻辑更加清晰。
PHP函数的定义方式:
    1.使用关键字“function”开始
    2.函数名可以是字母或下划线开头:function name()

    3.在大括号中编写函数体:

[php] view plain copy
  1. <?php  
  2.     function say()  
  3.     {  
  4.         echo 'hello world';  
  5.     }  
  6.     say();  
  7.     //在这里调用函数  
  8. ?>  
  9. //////  
  10. hello world  

PHP函数的参数

PHP的函数可以没有参数,也可以有若干个参数,多个参数称之为参数列表,采用逗号进行分割,参数类似于一个变量,调用时用来传递数据到函数体中。通过传递参数可以使函数实现对参数的运算,得到我们想要的结果。

参数的变量名可以自由指定,但最好能够表达相关的意思
[php] view plain copy
  1. <?php  
  2.     function sum($a$b) {  
  3.         echo $a + $b;  
  4.     }  
  5.     sum(2,5);  
  6.     //在这里调用函数计算1+2的值  
  7. ?>  
  8. //////  
  9. 7  

PHP函数之返回值

使用return关键字可以使函数返回值,可以返回包括数组和对象的任意类型,如果省略了 return,则默认返回值为 NULL。
[php] view plain copy
  1. <?php  
  2.     function add($a) {  
  3.         return $a+1;  
  4.     }  
  5.     $b = add(1);  
  6.     echo $b;  
  7. ?>  
  8. //////  
  9. 2  
返回语句会立即中止函数的运行,并且将控制权交回调用该函数的代码行
[php] view plain copy
  1. <?php  
  2.     function add($a) {  
  3.         return $a+1;  
  4.         $a = 10;  
  5.         return $a+20;  
  6.     }  
  7.     $b = add(1);  
  8.     echo $b;  
  9. ?>  
  10. //////  
  11. 2  

函数不能返回多个值,但可以通过返回一个数组来得到类似的效果

[php] view plain copy
  1. <?php  
  2.     function numbers() {  
  3.         return array(1, 2, 3);  
  4.     }  
  5.     list ($one$two$three) = numbers();  
  6.     echo $one;  
  7.     echo $two;  
  8.     echo $three;  
  9. ?>  
  10. //////  
  11. 123  
  12. 函数不能返回多个值,但可以通过返回一个数组来得到类似的效果  
[php] view plain copy
  1. array(3) {  
  2.   [0]=>  
  3.   int(1)  
  4.   [1]=>  
  5.   int(2)  
  6.   [2]=>  
  7.   int(3)  
  8. }  
  9. 这是numbers()返回的值  
list()只是举个例子而已,重点是函数函数不能返回多个值。
[php] view plain copy
  1. <?php  
  2.     function numbers() {  
  3.         return array(1, 2, 3);  
  4.     }  
  5.     $hh=numbers();  
  6.     print_r ($hh);  
  7. ?>  
  8. //////  
  9. Array ( [0] => 1 [1] => 2 [2] => 3 )  

PHP函数之可变函数

所谓可变函数,即通过变量的值来调用函数,因为变量的值是可变的,所以可以通过改变一个变量的值来实现调用不同的函数。经常会用在回调函数、函数列表,或者根据动态参数来调用不同的函数。可变函数的调用方法为变量名加括号。
[php] view plain copy
  1. <?php  
  2.     function name() {  
  3.         echo 'jobs';  
  4.     }  
  5.     $func = 'name';  
  6.     $func(); //调用可变函数  
  7. ?>  
  8. //////  
  9. jobs  
可变函数也可以用在对象的方法调用上。
[php] view plain copy
  1. <?php  
  2.     class book {  
  3.         function getName() {  
  4.             return 'bookname';  
  5.         }  
  6.     }  
  7.     $func = 'getName';  
  8.     $book = new book();  
  9.     echo $book->$func();  
  10. ?>  
  11. //////  
  12. bookname  

PHP函数之内置函数

内置函数指的是PHP默认支持的函数,PHP内置了很多标准的常用的处理函数,包括字符串处理、数组函数、文件处理、session与cookie处理等。

通过内置函数str_replace可以实现字符串的替换。下面的例子将“jobs”替换成“steven jobs”:

[php] view plain copy
  1. <?php  
  2.     $str = 'i am jobs.';  
  3.     $str = str_replace('jobs''steven jobs'$str);  
  4.     echo $str//结果为“i am steven jobs”  
  5. ?>  

PHP函数之判断函数是否存在

当我们创建了自定义函数,并且了解了可变函数的用法,为了确保程序调用的函数是存在的,经常会先使用function_exists判断一下函数是否存在。同样的method_exists可以用来检测类的方法是否存在。
[php] view plain copy
  1. <?php  
  2.     function func() {  
  3.     }  
  4.     if (function_exists('func')){  
  5.         echo 'exists';  
  6.     }  
  7. ?>  

类是否定义可以使用class_exists。
[php] view plain copy
  1. <?php  
  2.     class MyClass{  
  3.     }  
  4.     // 使用前检查类是否存在  
  5.     if (class_exists('MyClass')) {  
  6.         $myclass = new MyClass();  
  7.     }  
  8. ?>  

PHP中有很多这类的检查方法,例如文件是否存在file_exists等。
[php] view plain copy
  1. <?php  
  2.     $filename = 'test.txt';  
  3.     if (!file_exists($filename)) {  
  4.         echo $filename . ' not exists.';  
  5.     }  
  6. ?>  

判断函数func是否存在,如果存在的话就调用他。
[php] view plain copy
  1. <?php  
  2.     function func() {  
  3.         echo 'exists';  
  4.     }  
  5.     $name = 'func';  
  6.     if (function_exists($name)) { //判断函数是否存在  
  7.         $name();  
  8.     }  
  9. ?>  

类与面向对象

PHP类和对象

类是面向对象程序设计的基本概念,通俗的理解类就是对现实中某一个种类的东西的抽象, 比如汽车可以抽象为一个类,汽车拥有名字、轮胎、速度、重量等属性,可以有换挡、前进、后退等操作方法。

通常定义一个汽车类的方法为:

[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         $name = '汽车';  
  4.         function getName() {  
  5.             return $this->name;  
  6.         }  
  7.     }  
  8. ?>  

类是一类东西的结构描述,而对象则是一类东西的一个具体实例,例如汽车这个名词可以理解为汽车的总类,但这辆汽车则是一个具体的汽车对象。

对象通过new关键字进行实例化:

[php] view plain copy
  1. $car = new Car();  
  2. ar->getName();  
类与对象看起来比较相似,但实际上有本质的区别,类是抽象的概念,对象是具体的实例。类可以使程序具有可重用性。
[php] view plain copy
  1. <?php  
  2.     class car{  
  3.         public function rec(){  
  4.             echo "你好";  
  5.         }  
  6.         public function caa(){  
  7.             $this->rec();  
  8.         }  
  9.     }  
  10.     $cat=new car();  
  11.     $cat->caa();  
  12. ?>  
  13. //////  
  14. 你好  
定义类的属性为公共,
var跟public一个意思,var是php旧版的用法。
[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         var $name = '汽车';  
  4.         function getName() {  
  5.             return $this->name;  
  6.         }  
  7.     }  
  8.   
  9.     //实例化一个car对象  
  10.     $car = new Car();  
  11.     echo $car->getName();  //调用对象的方法 输出对象的名字  
  12.     echo $car->name;  
  13. ?>  
  14. //////  
  15. 汽车汽车  
[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         public $name = '汽车';  
  4.         function getName() {  
  5.             return $this->name;  
  6.         }  
  7.     }  
  8.   
  9.     //实例化一个car对象  
  10.     $car = new Car();  
  11.     echo $car->getName();  //调用对象的方法 输出对象的名字  
  12.     echo $car->name;  
  13. ?>  
  14. //////  
  15. 汽车汽车  
[php] view plain copy
  1. <?php  
  2.     //定义一个类  
  3.     class Car {  
  4.         var $name = '汽车';  
  5.         function getName() {  
  6.             return $this->name;  
  7.         }  
  8.     }  
  9.   
  10.     //实例化一个car对象  
  11.     $car = new Car();  
  12.     $car->name = '奥迪A6'//设置对象的属性值  
  13.     echo $car->getName();  //调用对象的方法 输出对象的名字  
  14. ?>  
  15. //////  
  16. 奥迪A6  

PHP类和对象之创建一个对象

类通过关键字class开头,然后是类名与花括号,在花括号中定义类的属性与方法。类名必须是字母或下划线开头,后面紧跟若干个字母、数字或下划线,类名最好能够表意,可以采用名词或者英文单词。

[php] view plain copy
  1. <?php  
  2.     //定义一个类  
  3.     class Car {  
  4.         //定义属性  
  5.         public $name = '汽车';  
  6.   
  7.         //定义方法  
  8.         public function getName() {  
  9.             //方法内部可以使用$this伪变量调用对象的属性或者方法  
  10.             return $this->name;  
  11.         }  
  12.     }  
  13.     $car = new Car();  
  14.     echo $car->getName();  //调用对象的方法 输出对象的名字  
  15. ?>  
  16. //////  
  17. 汽车  

也可以采用变量来创建
[php] view plain copy
  1. <?php  
  2.     //定义一个类  
  3.     class Car {  
  4.         //定义属性  
  5.         public $name = '汽车';  
  6.   
  7.         //定义方法  
  8.         public function getName() {  
  9.             //方法内部可以使用$this伪变量调用对象的属性或者方法  
  10.             return $this->name;  
  11.         }  
  12.     }  
  13.     $className = 'Car';  
  14.     $car = new $className();  
  15.     echo $car->getName();  
  16. ?>  
  17. <pre name="code" class="php">//////  
  18. 汽车  

PHP类和对象之类的属性

在类中定义的变量称之为属性,通常属性跟数据库中的字段有一定的关联,因此也可以称作“字段”。属性声明是由关键字 public,protected 或者 private 开头,后面跟一个普通的变量声明来组成。属性的变量可以设置初始化的默认值,默认值必须是常量。

访问控制的关键字代表的意义为:

public:公开的protected:受保护的private:私有的

[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         //定义公共属性  
  4.         public $name = '汽车';  
  5.   
  6.         //定义受保护的属性  
  7.         protected $corlor = '白色';  
  8.   
  9.         //定义私有属性  
  10.         private $price = '100000';  
  11.     }  
  12.     $car = new Car();  
  13.     echo $car->name;    //调用对象的属性  
  14.     echo $car->color;  //错误 受保护的属性不允许外部调用  
  15.     echo $car->price;  //错误 私有属性不允许外部调用    
  16. ?>  

默认都为public,外部可以访问。一般通过->对象操作符来访问对象的属性或者方法,对于静态属性则使用::双冒号进行访问。当在类成员方法内部调用的时候,可以使用$this伪变量调用当前对象的属性。

受保护的属性与私有属性不允许外部调用,在类的成员方法内部是可以调用的。

[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         private $name = '汽车';  
  4.         public function getName() {  
  5.             return $this->name;  
  6.         }  
  7.     }  
  8.   
  9.     $carnew Car();    //new一个新的类  
  10.     echo $car->getName();  
  11. ?>  
  12. //////  
  13. 汽车  

PHP类和对象之定义类的方法

方法就是在类中的function,很多时候我们分不清方法与函数有什么差别,在面向过程的程序设计中function叫做函数,在面向对象中function则被称之为方法。

同属性一样,类的方法也具有public,protected 以及 private 的访问控制。

访问控制的关键字代表的意义为:
public:公开的
protected:受保护的
private:私有的

[php] view plain copy
  1. <?php   
  2.     class hup {  
  3.         public function but() {  
  4.             return 100;  
  5.         }  
  6.     }  
  7.     $hu=new hup();  
  8.     echo $hu->but();  
  9. ?>  
  10. //////  
  11. 100  

使用关键字static修饰的,称之为静态方法,静态方法不需要实例化对象,可以通过类名直接调用,操作符为双冒号::。

[php] view plain copy
  1. <?php   
  2.     class hup {  
  3.         public function but() {  
  4.             return 100;  
  5.         }  
  6.     }  
  7.     echo hup::but(); //结果为“100”  
  8. ?>  

PHP类和对象之构造函数和析构函数

PHP5可以在类中使用__construct()定义一个构造函数,具有构造函数的类,会在每次对象创建的时候调用该函数,因此常用来在对象创建的时候进行一些初始化工作。
[php] view plain copy
  1. <?php   
  2.     class Car {  
  3.        function __construct() {  
  4.            print "构造函数被调用\n";  
  5.        }  
  6.     }  
  7.     $car = new Car(); //实例化的时候 会自动调用构造函数__construct,这里会输出一个字符串  
  8. ?>  


在子类中如果定义了__construct则不会调用父类的__construct,如果需要同时调用父类的构造函数,需要使用parent::__construct()显式的调用。

[php] view plain copy
  1. <?php   
  2.     class Car {  
  3.        function __construct() {  
  4.            print "父类构造函数被调用\n";  
  5.        }  
  6.     }  
  7.     class Truck extends Car {  
  8.        function __construct() {  
  9.            print "子类构造函数被调用\n";  
  10.            parent::__construct();  
  11.        }  
  12.     }  
  13.     $car = new Truck();  
  14. ?>  
  15. //////  
  16. 子类构造函数被调用 父类构造函数被调用  
PHP5支持析构函数,使用__destruct()进行定义,析构函数指的是当某个对象的所有引用被删除,或者对象被显式的销毁时会执行的函数。
[php] view plain copy
  1. <?php   
  2.     class Car {  
  3.        function __construct() {  
  4.            print "构造函数被调用 \n";  
  5.        }  
  6.        function __destruct() {  
  7.            print "析构函数被调用 \n";  
  8.        }  
  9.     }  
  10.     $car = new Car(); //实例化时会调用构造函数  
  11.     echo '使用后,准备销毁car对象 \n';  
  12.     unset($car); //销毁时会调用析构函数  
  13. ?>  

当PHP代码执行完毕以后,会自动回收与销毁对象,因此一般情况下不需要显式的去销毁对象。

PHP类和对象之Static静态关键字

静态属性与方法可以在不实例化类的情况下调用,直接使用类名::方法名的方式进行调用。静态属性不允许对象使用->操作符调用。

[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         private static $speed = 10;  
  4.         public static function getSpeed() {  
  5.             return self::$speed;  
  6.         }  
  7.     }  
  8.     echo Car::getSpeed();  //调用静态方法  
  9. ?>  
  10. //////  
  11. 10  
静态方法也可以通过变量来进行动态调用
[php] view plain copy
  1. $func = 'getSpeed';  
  2. $className = 'Car';  
  3. echo $className::$func();  //动态调用静态方法  

静态方法中,$this伪变量不允许使用。可以使用self,parent,static在内部调用静态方法与属性。
[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         private static $speed = 10;  
  4.   
  5.         public static function getSpeed() {  
  6.             return self::$speed;  
  7.         }  
  8.   
  9.         public static function speedUp() {  
  10.             return self::$speed+=10;  
  11.         }  
  12.     }  
  13.     class BigCar extends Car {  
  14.         public static function start() {  
  15.             parent::speedUp();  
  16.         }  
  17.     }  
  18.   
  19.     BigCar::start();  
  20.     echo BigCar::getSpeed();  
  21. ?>  
  22. //////  
  23. 20  

PHP类和对象之访问控制

访问控制通过关键字public,protected和private来实现。被定义为公有的类成员可以在任何地方被访问。被定义为受保护的类成员则可以被其自身以及其子类和父类访问。被定义为私有的类成员则只能被其定义所在的类访问。

类属性必须定义为公有受保护私有之一。为兼容PHP5以前的版本,如果采用 var 定义,则被视为公有。

[php] view plain copy
  1. class Car {  
  2.     $speed = 10; //错误 属性必须定义访问控制  
  3.     public $name;   //定义共有属性  
  4. }  

类中的方法可以被定义为公有私有受保护。如果没有设置这些关键字,则该方法默认为公有
[php] view plain copy
  1. class Car {  
  2. ​    //默认为共有方法  
  3.     function turnLeft() {  
  4.     }  
  5. }  

如果构造函数定义成了私有方法,则不允许直接实例化对象了,这时候一般通过静态方法进行实例化,在设计模式中会经常使用这样的方法来控制对象的创建,比如单例模式只允许有一个全局唯一的对象。
[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         private function __construct() {  
  4.             echo 'object create';  
  5.         }  
  6.   
  7.         private static $_object = null;  
  8.         public static function getInstance() {  
  9.             if (empty(self::$_object)) {  
  10.                 self::$_object = new Car(); //内部方法可以调用私有方法,因此这里可以创建对象  
  11.             }  
  12.             return self::$_object;  
  13.         }  
  14.     }  
  15.     //$car = new Car(); //这里不允许直接实例化对象  
  16.     $car = Car::getInstance(); //通过静态方法来获得一个实例  
  17. ?>  

PHP类和对象之对象继承

继承是面向对象程序设计中常用的一个特性,汽车是一个比较大的类,我们也可以称之为基类,除此之外,汽车还分为卡车、轿车、东风、宝马等,因为这些子类具有很多相同的属性和方法,可以采用继承汽车类来共享这些属性与方法,实现代码的复用。
[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         public $speed = 0; //汽车的起始速度是0  
  4.   
  5.         public function speedUp() {  
  6.             $this->speed += 10;  
  7.             return $this->speed;  
  8.         }  
  9.     }  
  10.     //定义继承于Car的Truck类  
  11.      class Truck extends Car {  
  12.         public function speedUp() {  
  13.             $this->speed = parent::speedUp() + 50;  
  14.         }  
  15.     }  
  16.   
  17.     $car = new Truck();  
  18.     $car->speedUp();  
  19.     echo $car->speed;  
  20. ?>  
  21. //////  
  22. 60  

PHP类和对象之重载

PHP中的重载指的是动态的创建属性与方法,是通过魔术方法来实现的。属性的重载通过__set,__get,__isset,__unset来分别实现对不存在属性的赋值、读取、判断属性是否设置、销毁属性。
[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         private $ary = array();  
  4.   
  5.         public function __set($key$val) {  
  6.             $this->ary[$key] = $val;  
  7.         }  
  8.   
  9.         public function __get($key) {  
  10.             if (isset($this->ary[$key])) {  
  11.                 return $this->ary[$key];  
  12.             }  
  13.             return null;  
  14.         }  
  15.   
  16.         public function __isset($key) {  
  17.             if (isset($this->ary[$key])) {  
  18.                 return true;  
  19.             }  
  20.             return false;  
  21.         }  
  22.   
  23.         public function __unset($key) {  
  24.             unset($this->ary[$key]);  
  25.         }  
  26.     }  
  27.     $car = new Car();  
  28.     $car->name = '汽车';  //name属性动态创建并赋值  
  29.     echo $car->name;  
  30. ?>  

方法的重载通过__call来实现,当调用不存在的方法的时候,将会转为参数调用__call方法,当调用不存在的静态方法时会使用__callStatic重载。
[php] view plain copy
  1. class Car {  
  2.     public $speed = 0;  
  3.       
  4.     public function __call($name$args) {  
  5.         if ($name == 'speedUp') {  
  6.             $this->speed += 10;  
  7.         }  
  8.     }  
  9. }  
  10. $car = new Car();  
  11. $car->speedUp(); //调用不存在的方法会使用重载  
  12. echo $car->speed;  

[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         public $speed = 10;  
  4.   
  5.         //在这里使用重载实现speedDown方法  
  6.         public function __call($name,$args){  
  7.             if ($name=='speedDown'){  
  8.                 $this->speed-=10;  
  9.             }  
  10.         }  
  11.     }  
  12.     $car = new Car();  
  13.     $car->speedDown(); //调用不存在的speedDown方法  
  14.     echo $car->speed;  
  15. ?>  
  16. //////  
  17. 0  

PHP类和对象之对象的高级特性

对象比较,当同一个类的两个实例的所有属性都相等时,可以使用比较运算符==进行判断,当需要判断两个变量是否为同一个对象的引用时,可以使用全等运算符===进行判断。
[php] view plain copy
  1. class Car {  
  2. }  
  3. $a = new Car();  
  4. $b = new Car();  
  5. if ($a == $becho '==';   //true  
  6. if ($a === $becho '==='//false  

对象复制,在一些特殊情况下,可以通过关键字clone来复制一个对象,这时__clone方法会被调用,通过这个魔术方法来设置属性的值。
[php] view plain copy
  1. class Car {  
  2.     public $name = 'car';  
  3.       
  4.     public function __clone() {  
  5.         $obj = new Car();  
  6.         $obj->name = $this->name;  
  7.     }  
  8. }  
  9. $a = new Car();  
  10. $a->name = 'new car';  
  11. $b = clone $a;  
  12. var_dump($b);  

对象序列化,可以通过serialize方法将对象序列化为字符串,用于存储或者传递数据,然后在需要的时候通过unserialize将字符串反序列化成对象进行使用。
[php] view plain copy
  1. class Car {  
  2.     public $name = 'car';  
  3. }  
  4. $a = new Car();  
  5. $str = serialize($a); //对象序列化成字符串  
  6. echo $str.'<br>';  
  7. $b = unserialize($str); //反序列化为对象  
  8. var_dump($b);  

[php] view plain copy
  1. <?php  
  2.     class Car {  
  3.         public $name = 'car';  
  4.   
  5.         public function __clone() {  
  6.             $obj = new Car();  
  7.             $obj->name = $this->name;  
  8.         }  
  9.     }  
  10.     $a = new Car();  
  11.     $a->name = 'new car';  
  12.     $b = clone $a;  
  13.     if ($a == $becho '==';   //true  
  14.     if ($a === $becho '==='//false  
  15.   
  16.     $str = serialize($a); //对象序列化成字符串  
  17.     echo $str.'<br>';  
  18.     $c = unserialize($str); //反序列化为对象  
  19.     var_dump($c);  
  20. ?>  

字符串操作

PHP字符串介绍

PHP开发中,我们遇到最多的可能就是字符串。

字符串变量用于包含字符串的值。

一个字符串 通过下面的3种方法来定义:

1、单引号
2、双引号
3、heredoc语法结构

基本用法如下,后面的节还会详细进行介绍使用技巧,这里只介绍用法:

单引号定义的字符串:$hello = 'hello world';

双引号定义的字符串:$hello = "hello world";

heredoc语法结构定义的字符串:

[php] view plain copy
  1. $hello = <<<TAG  
  2. hello world  
  3. TAG;  

PHP字符串之单引号和双引号的区别

在PHP中,字符串的定义可以使用英文单引号' ',也可以使用英文双引号" "

但是必须使用同一种单或双引号来定义字符串,如:'Hello World""Hello World'为非法的字符串定义。

单引号和双引号到底有啥区别呢?

PHP允许我们在双引号串中直接包含字串变量

而单引号串中的内容总被认为是普通字符。

[php] view plain copy
  1. $str='hello';  
  2. echo "str is $str"//运行结果: str is hello  
  3. echo 'str is $str'//运行结果: str is $str  

PHP字符串之字符串的连接

PHP中两个字符串如何连接呢,比如我有个字符串$hello='hello',还有一个字符串$world=' world',我想将这两个字符串连接在一起,跟世界打个招呼。

PHP中用英文的点号.来连接两个字符串。

[php] view plain copy
  1. $hello='hello';  
  2.   
  3. $world=' world';  
  4.   
  5. $hi = $hello.$world;  
  6.   
  7. echo $hi;//我们可以用echo函数输出一下这个字符串连接。  

[php] view plain copy
  1. <?php  
  2.     $i='I';  
  3.     $love=' Love';  
  4.     $you=' You';  
  5.     //连接一下三个字符串  
  6.     $str = $i.$love.$you;  
  7.     echo $str;  
  8. ?>  
  9. //////  
  10. I Love You  

PHP字符串之去除字符串首尾的空格

PHP中有三个函数可以去掉字符串的空格

trim去除一个字符串两端空格。
rtrim是去除一个字符串右部空格,其中的r是right的缩写。
ltrim是去除一个字符串左部空格,其中的l是left的缩写。

[php] view plain copy
  1. echo trim(" 空格 ")."<br>";  
  2. echo rtrim(" 空格 ")."<br>";  
  3. echo ltrim(" 空格 ")."<br>";  
[php] view plain copy
  1. <?php  
  2.     $str="      左侧空格要去掉";  
  3.     echo trim($str);  
  4. ?>  

PHP字符串之获取字符串的长度

php中有一个神奇的函数,可以直接获取字符串的长度,这个函数就是strlen()。

[php] view plain copy
  1. $str = 'hello';  
  2. $len = strlen($str);  
  3. echo $len;//输出结果是5  

strlen函数对于计算英文字符是非常的擅长,但是如果有中文汉字,要计算长度该怎么办?

可以使用mb_strlen()函数获取字符串中中文长度。

[php] view plain copy
  1. $str = "我爱你";  
  2. echo mb_strlen($str,"UTF8");//结果:3,此处的UTF8表示中文编码是UTF8格式,中文一般采用UTF8编码  

PHP字符串之字符串的截取

php中有非常多的字符串处理函数,其中就有字符串截取函数。

1、英文字符串的截取函数substr()

函数说明:substr(字符串变量,开始截取的位置,截取个数)

[php] view plain copy
  1. $str='i love you';  
  2. //截取love这几个字母  
  3. echo substr($str, 2, 4);//为什么开始位置是2呢,因为substr函数计算字符串位置是从0开始的,也就是0的位置是i,1的位置是空格,l的位置是2。从位置2开始取4个字  
  4. 符,就是love。  

2、中文字符串的截取函数mb_substr()

函数说明:mb_substr(字符串变量,开始截取的位置,截取个数, 网页编码)

[php] view plain copy
  1. $str='我爱你,中国';  
  2.   
  3. //截取中国两个字  
  4.   
  5. echo mb_substr($str, 4, 2, 'utf8');//为什么开始位置是4呢,和上一个例子一样,因为mb_substr函数计算汉字位置是从0开始的,也就是0的位置是我,1的位置是爱,4的位置是中。从位置4开始取2个汉字,就是中国。中文编码一般是utf8格式  

PHP字符串之查找字符串

如果有一个字符串$str = 'I want to study at imooc';,怎么样找到其中的imooc在哪个位置呢?

查找字符串,我们需要用到PHP的查找字符串函数strpos();

函数说明:strpos(要处理的字符串, 要定位的字符串, 定位的起始位置[可选])

[php] view plain copy
  1. $str = 'I want to study at imooc';  
  2. $pos = strpos($str'imooc');  
  3. echo $pos;//结果显示19,表示从位置0开始,imooc在第19个位置开始出现  

PHP字符串之替换字符串

如果有一个字符串$str = 'I want to learn js';,怎么样将js字符替换成你想学的php字符呢?

替换字符串,我们需要用到PHP的替换函数str_replace()

函数说明:str_replace(要查找的字符串, 要替换的字符串, 被搜索的字符串, 替换进行计数[可选])

[php] view plain copy
  1. $str = 'I want to learn js';  
  2. $replace = str_replace('js''php'$str);  
  3. echo $replace;//结果显示I want to learn php  

[php] view plain copy
  1. <?php  
  2.     //替换字符串  
  3.     $str = 'I Love Chian';  
  4.     $replace=str_replace('Chian','China',$str);  
  5.     echo $replace;  
  6. ?>  

PHP字符串之格式化字符串

如果有一个字符串$str = '99.9';,怎么样使这个字符串变成99.90呢?

我们需要用到PHP的格式化字符串函数sprintf()

函数说明:sprintf(格式, 要转化的字符串)

返回:格式化好的字符串

例子:

$str = '99.9';
$result = sprintf('%01.2f', $str);
echo $result;//结果显示99.90

解释下,上面例子中的格式

这个 %01.2f 是什么意思呢?

1、这个 % 符号是开始的意思,写在最前面表示指定格式开始了。 也就是 "起始字符", 直到出现 "转换字符" 为止,就算格式终止。
2、跟在 % 符号后面的是 0, 是 "填空字元" ,表示如果位置空着就用0来填满。
3、在 0 后面的是1,这个 1 是规定整个所有的字符串占位要有1位以上(小数点也算一个占位)。
    如果把 1 改成 6,则 $result的值将为 099.90
    因为,在小数点后面必须是两位,99.90一共5个占位,现在需要6个占位,所以用0来填满。
4、在 %01 后面的 .2 (点2) 就很好理解了,它的意思是,小数点后的数字必须占2位。 如果这时候,$str 的值为9.234,则 $result的值将为9.23.
    为什么4 不见了呢? 因为在小数点后面,按照上面的规定,必须且仅能占2位。 可是 $str 的值中,小数点后面占了3位,所以,尾数4被去掉了,只剩下 23。
5、最后,以 f "转换字符" 结尾。

[php] view plain copy
  1. <?php  
  2.     //格式化字符串  
  3.     $str = '100.1';  
  4.     $spr = sprintf('%01.3f',$str);  
  5.     echo $spr;  
  6. ?>  

PHP字符串之字符串的合并与分割

1、php字符串合并函数implode()

函数说明:implode(分隔符[可选], 数组)

返回值:把数组元素组合为一个字符串

例子:

$arr = array('Hello', 'World!');
$result = implode('', $arr);
print_r($result);//结果显示Hello World!

2、php字符串分隔函数explode()

函数说明:explode(分隔符[可选], 字符串)

返回值:函数返回由字符串组成的数组

例子:

$str = 'apple,banana';
$result = explode(',', $str);
print_r($result);//结果显示array('apple','banana')

[php] view plain copy
  1. <?php  
  2.     //分隔字符串  
  3.     $str = 'sun-moon-star';  
  4.     $rro=explode('-',$str);  
  5.     print_r($rro);  
  6. ?>  
  7. //////  
  8. Array  
  9. (  
  10.     [0] => sun  
  11.     [1] => moon  
  12.     [2] => star  
  13. )  

PHP字符串之字符串的转义

php字符串转义函数addslashes()

函数说明:用于对特殊字符加上转义字符,返回一个字符串

返回值:一个经过转义后的字符串

例子:

$str = "what's your name?";
echo addslashes($str);//输出:what\'s your name?

正则表达式

什么叫正则表达式

正则表达式是对字符串进行操作的一种逻辑公式,就是用一些特定的字符组合成一个规则字符串,称之为正则匹配模式。
[php] view plain copy
  1. $p = '/apple/';  
  2. $str = "apple banna";  
  3. if (preg_match($p$str)) {  
  4.     echo 'matched';  
  5. }  

其中字符串'/apple/'就是一个正则表达式,他用来匹配源字符串中是否存在apple字符串。

PHP中使用PCRE库函数进行正则匹配,比如上例中的preg_match用于执行一个正则匹配,常用来判断一类字符模式是否存在。

[php] view plain copy
  1. <?php  
  2.     //请修改变量p的正则表达式,使他能够匹配苹果  
  3.     $p = '/苹果/';  
  4.   
  5.     $str = "我喜欢吃苹果";  
  6.     if (preg_match($p$str)) {  
  7.         echo '匹配成功';  
  8.     }  
  9. ?>  

正则表达式的基本语法

PCRE库函数中,正则匹配模式使用分隔符与元字符组成,分隔符可以是非数字、非反斜线、非空格的任意字符。经常使用的分隔符是正斜线(/)、hash符号(#) 以及取反符号(~),例如:

/foo bar/
#^[^0-9]$#
~php~

如果模式中包含分隔符,则分隔符需要使用反斜杠(\)进行转义。

/http:\/\//

如果模式中包含较多的分割字符,建议更换其他的字符作为分隔符,也可以采用preg_quote进行转义。

$p = 'http://';
$p = '/'.preg_quote($p, '/').'/';
echo $p;

分隔符后面可以使用模式修饰符,模式修饰符包括:i, m, s, x等,例如使用i修饰符可以忽略大小写匹配:

$str = "Http://www.imooc.com/";
if (preg_match('/http/i', $str)) {
    echo '匹配成功';
}

元字符与转义

正则表达式中具有特殊含义的字符称之为元字符,常用的元字符有:

\ 一般用于转义字符
^ 断言目标的开始位置(或在多行模式下是行首)
$ 断言目标的结束位置(或在多行模式下是行尾)
. 匹配除换行符外的任何字符(默认)
[ 开始字符类定义
] 结束字符类定义
| 开始一个可选分支
( 子组的开始标记
) 子组的结束标记
? 作为量词,表示 0 次或 1 次匹配。位于量词后面用于改变量词的贪婪特性。 (查阅量词)
* 量词,0 次或多次匹配
+ 量词,1 次或多次匹配
{ 自定义量词开始标记
} 自定义量词结束标记

//下面的\s匹配任意的空白符,包括空格,制表符,换行符。[^\s]代表非空白符。[^\s]+表示一次或多次匹配非空白符。
$p = '/^我[^\s]+(苹果|香蕉)$/';
$str = "我喜欢吃苹果";
if (preg_match($p, $str)) {
    echo '匹配成功';
}

元字符具有两种使用场景,一种是可以在任何地方都能使用,另一种是只能在方括号内使用,在方括号内使用的有:

\ 转义字符
^ 仅在作为第一个字符(方括号内)时,表明字符类取反
- 标记字符范围

其中^在反括号外面,表示断言目标的开始位置,但在方括号内部则代表字符类取反,方括号内的减号-可以标记字符范围,例如0-9表示0到9之间的所有数字。

//下面的\w匹配字母或数字或下划线。
$p = '/[\w\.\-]+@[a-z0-9\-]+\.(com|cn)/';
$str = "我的邮箱是[email protected]";
preg_match($p, $str, $match);
echo $match[0];
[php] view plain copy
  1. <?php  
  2.     //请修改变量p的正则表达式,使他能够匹配str中的电话  
  3.     $p = '/[\d]{3,4}\-[\d]{8,9}/';  
  4.     $str = "我的电话是010-12345678";  
  5.     preg_match($p$str$match);  
  6.     echo $match[0];  
  7. ?>  

贪婪模式与懒惰模式

贪婪模式:在可匹配与可不匹配的时候,优先匹配

//下面的\d表示匹配数字
$p = '/\d+\-\d+/';
$str = "我的电话是010-12345678";
preg_match($p, $str, $match);
echo $match[0]; //结果为:010-12345678

懒惰模式:在可匹配与可不匹配的时候,优先不匹配

$p = '/\d?\-\d?/';
$str = "我的电话是010-12345678";
preg_match($p, $str, $match);
echo $match[0];  //结果为:0-1

当我们确切的知道所匹配的字符长度的时候,可以使用{}指定匹配字符数

$p = '/\d{3}\-\d{8}/';
$str = "我的电话是010-12345678";
preg_match($p, $str, $match);
echo $match[0]; //结果为:010-12345678
[php] view plain copy
  1. <?php  
  2. //请修改变量p的正则表达式,使他能够匹配str中的姓名  
  3. $p = '/(\w+\s\w+)/';  
  4. $str = "name:steven jobs";  
  5. preg_match($p$str$match);  
  6. echo $match[1];  

使用正则表达式进行匹配

使用正则表达式的目的是为了实现比字符串处理函数更加灵活的处理方式,因此跟字符串处理函数一样,其主要用来判断子字符串是否存在、字符串替换、分割字符串、获取模式子串等。

PHP使用PCRE库函数来进行正则处理,通过设定好模式,然后调用相关的处理函数来取得匹配结果。

preg_match用来执行一个匹配,可以简单的用来判断模式是否匹配成功,或者取得一个匹配结果,他的返回值是匹配成功的次数0或者1,在匹配到1次以后就会停止搜索。

$subject = "abcdef";
$pattern = '/def/';
preg_match($pattern, $subject, $matches);
print_r($matches); //结果为:Array ( [0] => def )

上面的代码简单的执行了一个匹配,简单的判断def是否能匹配成功,但是正则表达式的强大的地方是进行模式匹配,因此更多的时候,会使用模式:

$subject = "abcdef";
$pattern = '/a(.*?)d/';
preg_match($pattern, $subject, $matches);
print_r($matches); //结果为:Array ( [0] => abcd [1] => bc )

通过正则表达式可以匹配一个模式,得到更多的有用的数据。

[php] view plain copy
  1. <?php  
  2. $subject = "my email is [email protected]";  
  3. $pattern = "/[0-9a-z]+@[0-9a-z]+.com/";  
  4. //$pattern = '/\w+@(\w+\.)+\w+/';  
  5. preg_match($pattern$subject$matches);  
  6. //在这里补充代码,实现正则匹配,并输出邮箱地址  
  7.   
  8. print_r($matches[0]);//   

查找所有匹配结果

preg_match只能匹配一次结果,但很多时候我们需要匹配所有的结果,preg_match_all可以循环获取一个列表的匹配结果数组。

$p = "|<[^>]+>(.*?)</[^>]+>|i";
$str = "<b>example: </b><div align=left>this is a test</div>";
preg_match_all($p, $str, $matches);
print_r($matches);

可以使用preg_match_all匹配一个表格中的数据:

$p = "/<tr><td>(.*?)<\/td>\s*<td>(.*?)<\/td>\s*<\/tr>/i";
$str = "<table> <tr><td>Eric</td><td>25</td></tr> <tr><td>John</td><td>26</td></tr> </table>";
preg_match_all($p, $str, $matches);
print_r($matches);

$matches结果排序为$matches[0]保存完整模式的所有匹配, $matches[1] 保存第一个子组的所有匹配,以此类推。

[php] view plain copy
  1. <?php  
  2. $str = "<ul>  
  3.             <li>item 1</li>  
  4.             <li>item 2</li>  
  5.         </ul>";  
  6. //在这里补充代码,实现正则匹配所有li中的数据  
  7. $p = "/<li>(.*)<\/li>/i";  
  8. $p = "/<li>(.*)<\/li>/i";//解释下这个正则://后面的i表示不区分大小写,<li>(.*?)<\/li>表示li标签内的匹配的()内的值有多少,括号内的.表示所有单字符,*表示数量为0个或者多个。也就是li标签内有字符就显示出来  
  9. preg_match_all($p,$str,$matches);  
  10. print_r($matches[1]);  
  11.   
  12. // $p = "|<[^>]+>(.*?)</[^>]+>|i";  
  13. // $str = "<b>example: </b><div align=left>this is a test</div>";  
  14. // preg_match_all($p, $str, $matches);  
  15. // print_r($matches);  
  16.   
  17. // // 可以使用preg_match_all匹配一个表格中的数据:  
  18. // $p = "/<tr><td>(.*?)<\/td>\s*<td>(.*?)<\/td>\s*<\/tr>/i";  
  19. // $str = "<table> <tr><td>Eric</td><td>25</td></tr> <tr><td>John</td><td>26</td></tr> </table>";  
  20. // preg_match_all($p, $str, $matches);  
  21. // print_r($matches);  
  22. // // echo $matches[1];  
  23. ?>  

正则表达式的搜索和替换

正则表达式的搜索与替换在某些方面具有重要用途,比如调整目标字符串的格式,改变目标字符串中匹配字符串的顺序等。

例如我们可以简单的调整字符串的日期格式:

$string = 'April 15, 2014';
$pattern = '/(\w+) (\d+), (\d+)/i';
$replacement = '$3, ${1} $2';
echo preg_replace($pattern, $replacement, $string); //结果为:2014, April 15

其中${1}与$1的写法是等效的,表示第一个匹配的字串,$2代表第二个匹配的。

通过复杂的模式,我们可以更加精确的替换目标字符串的内容。

$patterns = array ('/(19|20)(\d{2})-(\d{1,2})-(\d{1,2})/',
                   '/^\s*{(\w+)}\s*=/');
$replace = array ('\3/\4/\1\2', '$\1 =');//\3等效于$3,\4等效于$4,依次类推
echo preg_replace($patterns, $replace, '{startDate} = 1999-5-27'); //结果为:$startDate = 5/27/1999
//详细解释下结果:(19|20)表示取19或者20中任意一个数字,(\d{2})表示两个数字,(\d{1,2})表示1个或2个数字,(\d{1,2})表示1个或2个数字。^\s*{(\w+)\s*=}表示以任意空格开头的,并且包含在{}中的字符,并且以任意空格结尾的,最后有个=号的。

用正则替换来去掉多余的空格与字符:

$str = 'one     two';
$str = preg_replace('/\s+/', ' ', $str);
echo $str; // 结果改变为'one two'
[php] view plain copy
  1. <?php  
  2. $str = '主要有以下几个文件:index.php, style.css, common.js';  
  3. //将目标字符串$str中的文件名替换后增加em标签  
  4. $p = '/\w+\.\w+/i';  
  5. $str = preg_replace($p'<em>$0</em>'$str);  
  6. echo $str;  

正则匹配常用案例

[php] view plain copy
  1. <?php  
  2. $user = array(  
  3.     'name' => 'spark1985',  
  4.     'email' => '[email protected]',  
  5.     'mobile' => '13312345678'  
  6. );  
  7. //进行一般性验证  
  8. if (empty($user)) {  
  9.     die('用户信息不能为空');  
  10. }  
  11. if (strlen($user['name']) < 6) {  
  12.     die('用户名长度最少为6位');  
  13. }  
  14. //用户名必须为字母、数字与下划线  
  15. if (!preg_match('/^\w+$/i'$user['name'])) {  
  16.     die('用户名不合法');  
  17. }  
  18. //验证邮箱格式是否正确  
  19. if (!preg_match('/^[\w\.]+@\w+\.\w+$/i'$user['email'])) {  
  20.     die('邮箱不合法');  
  21. }  
  22. //手机号必须为11位数字,且为1开头  
  23. if (!preg_match('/^1\d{10}$/i'$user['mobile'])) {  
  24.     die('手机号不合法');  
  25. }  
  26. echo '用户信息验证成功';  


会话控制(session与cookie) 

cookie简介

Cookie是存储在客户端浏览器中的数据,我们通过Cookie来跟踪与存储用户数据。一般情况下,Cookie通过HTTP headers从服务端返回到客户端。多数web程序都支持Cookie的操作,因为Cookie是存在于HTTP的标头之中,所以必须在其他信息输出以前进行设置,类似于header函数的使用限制。

PHP通过setcookie函数进行Cookie的设置,任何从浏览器发回的Cookie,PHP都会自动的将他存储在$_COOKIE的全局变量之中,因此我们可以通过$_COOKIE['key']的形式来读取某个Cookie值。

PHP中的Cookie具有非常广泛的使用,经常用来存储用户的登录信息,购物车等,且在使用会话Session时通常使用Cookie来存储会话id来识别用户,Cookie具备有效期,当有效期结束之后,Cookie会自动的从客户端删除。同时为了进行安全控制,Cookie还可以设置域跟路径,我们会在稍后的章节中详细的讲解他们。

[php] view plain copy
  1. <?php  
  2.     setcookie('test', time());  
  3.     ob_start();  
  4.     print_r($_COOKIE);   
  5.     $content = ob_get_contents();  
  6.     $content = str_replace(" "' '$content);  
  7.     ob_clean();  
  8.     header("content-type:text/html; charset=utf-8");  
  9.     echo '当前的Cookie为:<br>';  
  10.     echo nl2br($content);  
  11. ?>  

设置cookie

PHP设置Cookie最常用的方法就是使用setcookie函数,setcookie具有7个可选参数,我们常用到的为前5个:

name( Cookie名)可以通过$_COOKIE['name'] 进行访问
value(Cookie的值)
expire(过期时间)Unix时间戳格式,默认为0,表示浏览器关闭即失效
path(有效路径)如果路径设置为'/',则整个网站都有效
domain(有效域)默认整个域名都有效,如果设置了'www.imooc.com',则只在www子域中有效

$value = 'test';
setcookie("TestCookie", $value);
setcookie("TestCookie", $value, time()+3600);  //有效期一小时
setcookie("TestCookie", $value, time()+3600, "/path/", "http://localhost/.com"); //设置路径与域

PHP中还有一个设置Cookie的函数setrawcookie,setrawcookie跟setcookie基本一样,唯一的不同就是value值不会自动的进行urlencode,因此在需要的时候要手动的进行urlencode。

setrawcookie('cookie_name', rawurlencode($value), time()+60*60*24*365); 

因为Cookie是通过HTTP标头进行设置的,所以也可以直接使用header方法进行设置。

header("Set-Cookie:cookie_name=value");

[php] view plain copy
  1. <?php  
  2. $value = time();  
  3. //在这里设置一个名为test的Cookie  
  4. setcookie("test",$value);  
  5. if (isset($_COOKIE['test'])) {  
  6.     echo 'success';  
  7. }  
[php] view plain copy
  1. <?php  
  2.     setcookie('test', time());  
  3.   
  4.     //在这里试着删除test的cookie值  
  5.   
  6.   
  7.     var_dump($_COOKIE);  
  8. ?>  


cookie的删除与过期时间

我们了解了设置cookie的函数,但是我们却发现php中没有删除Cookie的函数,在PHP中删除cookie也是采用setcookie函数来实现。
setcookie('test', '', time()-1); 

可以看到将cookie的过期时间设置到当前时间之前,则该cookie会自动失效,也就达到了删除cookie的目的。之所以这么设计是因为cookie是通过HTTP的标头来传递的,客户端根据服务端返回的Set-Cookie段来进行cookie的设置,如果删除cookie需要使用新的Del-Cookie来实现,则HTTP头就会变得复杂,实际上仅通过Set-Cookie就可以简单明了的实现Cookie的设置、更新与删除。

了解原理以后,我们也可以直接通过header来删除cookie。

header("Set-Cookie:test=1393832059; expires=".gmdate('D, d M Y H:i:s \G\M\T', time()-1));

这里用到了gmdate,用来生成格林威治标准时间,以便排除时差的影响。


[php] view plain copy
  1. <?php  
  2.     setcookie('test', time()-1);  
  3.     setcookie('test''', time()-1);  
  4.     //在这里试着删除test的cookie值  
  5.     var_dump($_COOKIE);  
  6. ?>  

cookie的有效路径

cookie中的路径用来控制设置的cookie在哪个路径下有效,默认为'/',在所有路径下都有,当设定了其他路径之后,则只在设定的路径以及子路径下有效,例如:

setcookie('test', time(), 0, '/path');

上面的设置会使test在/path以及子路径/path/abc下都有效,但是在根目录下就读取不到test的cookie值。

一般情况下,大多是使用所有路径的,只有在极少数有特殊需求的时候,会设置路径,这种情况下只在指定的路径中才会传递cookie值,可以节省数据的传输,增强安全性以及提高性能。

当我们设置了有效路径的时候,不在当前路径的时候则看不到当前cookie。

setcookie('test', '1',0, '/path');  
var_dump($_COOKIE['test']);  

[php] view plain copy
  1. <?php  
  2.     setcookie('test''1', 0, '/path');  
  3.     var_dump($_COOKIE['test']);  
  4. ?>  

setcookie('test', '1', 0,'/path');记得前面又说,忘了,现在记录下,0表示有效期,浏览器关闭,cookie也就到期了

setcookie(名称 , 值 , 有效期 , 路径 , 域 , 是否通过安全传输);其中名称和值是必需的,后面的可选。

session与cookie的异同

cookie将数据存储在客户端,建立起用户与服务器之间的联系,通常可以解决很多问题,但是cookie仍然具有一些局限:

cookie相对不是太安全,容易被盗用导致cookie欺骗
单个cookie的值最大只能存储4k
每次请求都要进行网络传输,占用带宽

session是将用户的会话数据存储在服务端,没有大小限制,通过一个session_id进行用户识别,PHP默认情况下session id是通过cookie来保存的,因此从某种程度上来说,seesion依赖于cookie。但这不是绝对的,session id也可以通过参数来实现,只要能将session id传递到服务端进行识别的机制都可以使用session。

[php] view plain copy
  1. <?php  
  2.     //开始使用session  
  3.     session_start();  
  4.     //设置一个session  
  5.     $_SESSION['test'] = time();  
  6.     //显示当前的session_id  
  7.     echo "session_id:".session_id();  
  8.     echo "<br>";  
  9.   
  10.     //读取session值  
  11.     echo $_SESSION['test'];  
  12.   
  13.     //销毁一个session  
  14.     unset($_SESSION['test']);  
  15.     echo "<br>";  
  16.     var_dump($_SESSION);  
  17. ?>  

使用session

在PHP中使用session非常简单,先执行session_start方法开启session,然后通过全局变量$_SESSION进行session的读写。

session_start();
$_SESSION['test'] = time();
var_dump($_SESSION);

session会自动的对要设置的值进行encode与decode,因此session可以支持任意数据类型,包括数据与对象等。

session_start();
$_SESSION['ary'] = array('name' => 'jobs');
$_SESSION['obj'] = new stdClass();
var_dump($_SESSION);
默认情况下,session是以文件形式存储在服务器上的,因此当一个页面开启了session之后,会独占这个session文件,这样会导致当前用户的其他并发访问无法执行而等待。可以采用缓存或者数据库的形式存储来解决这个问题
[php] view plain copy
  1. <?php  
  2.     session_start();  
  3.     $_SESSION['name'] = 'jobs';  
  4.     echo $_SESSION['name'];  
  5. ?>  

删除与销毁session

删除某个session值可以使用PHP的unset函数,删除后就会从全局变量$_SESSION中去除,无法访问。

session_start();
$_SESSION['name'] = 'jobs';
unset($_SESSION['name']);
echo $_SESSION['name']; //提示name不存在

如果要删除所有的session,可以使用session_destroy函数销毁当前session,session_destroy会删除所有数据,但是session_id仍然存在。

session_start();
$_SESSION['name'] = 'jobs';
$_SESSION['time'] = time();
session_destroy();

值得注意的是,session_destroy并不会立即的销毁全局变量$_SESSION中的值,只有当下次再访问的时候,$_SESSION才为空,因此如果需要立即销毁$_SESSION,可以使用unset函数。

session_start();
$_SESSION['name'] = 'jobs';
$_SESSION['time'] = time();
unset($_SESSION);
session_destroy(); 
var_dump($_SESSION); //此时已为空

如果需要同时销毁cookie中的session_id,通常在用户退出的时候可能会用到,则还需要显式的调用setcookie方法删除session_id的cookie值。

[php] view plain copy
  1. <?php  
  2.     session_start();  
  3.     $_SESSION['name'] = 'jobs';  
  4.     //在这里删除name的session值  
  5.     unset($_SESSION['name']);  
  6.     if (isset($_SESSION['name'])) {  
  7.         echo $_SESSION['name'];  
  8.     }  
  9. ?>  

使用session来存储用户的登录信息

session可以用来存储多种类型的数据,因此具有很多的用途,常用来存储用户的登录信息,购物车数据,或者一些临时使用的暂存数据等。

用户在登录成功以后,通常可以将用户的信息存储在session中,一般的会单独的将一些重要的字段单独存储,然后所有的用户信息独立存储。

$_SESSION['uid'] = $userinfo['uid'];
$_SESSION['userinfo'] = $userinfo;

一般来说,登录信息既可以存储在sessioin中,也可以存储在cookie中,他们之间的差别在于session可以方便的存取多种数据类型,而cookie只支持字符串类型,同时对于一些安全性比较高的数据,cookie需要进行格式化与加密存储,而session存储在服务端则安全性较高。

[php] view plain copy
  1. <!DOCTYPE html>  
  2. <html lang="en">  
  3. <head>  
  4.     <meta charset="UTF-8">  
  5.     <title>Document</title>  
  6. </head>  
  7. <body>  
  8. <?php  
  9.     session_start();  
  10.     //假设用户登录成功获得了以下用户数据  
  11.     $userinfo = array(  
  12.         'uid'  => 10000,  
  13.         'name' => 'spark',  
  14.         'email' => '[email protected]',  
  15.         'sex'  => 'man',  
  16.         'age'  => '18'  
  17.     );  
  18.     header("content-type:text/html; charset=utf-8");  
  19.   
  20.     /* 将用户信息保存到session中 */  
  21.     $_SESSION['uid'] = $userinfo['uid'];  
  22.     $_SESSION['name'] = $userinfo['name'];  
  23.     $_SESSION['userinfo'] = $userinfo;  
  24.   
  25.     //* 将用户数据保存到cookie中的一个简单方法 */  
  26.     $secureKey = 'imooc'//加密密钥  
  27.     $str = serialize($userinfo); //将用户信息序列化  
  28.     //用户信息加密前  
  29.     $str = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($secureKey), $str, MCRYPT_MODE_ECB));  
  30.     //用户信息加密后  
  31.     //将加密后的用户数据存储到cookie中  
  32.     setcookie('userinfo'$str);  
  33.   
  34.     //当需要使用时进行解密  
  35.     $str = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($secureKey), base64_decode($str), MCRYPT_MODE_ECB);  
  36.     $uinfo = unserialize($str);  
  37.     echo "解密后的用户信息:<br>";  
  38.     print_r($uinfo);  
  39. ?>  
  40. </body>  
  41. </html>  


文件系统

PHP文件系统之读取文件内容

PHP具有丰富的文件操作函数,最简单的读取文件的函数为file_get_contents,可以将整个文件全部读取到一个字符串中。

[php] view plain copy
  1. <?php  
  2.     $content = file_get_contents('text.txt');  
  3.     echo $content;  
  4. ?>  

file_get_contents也可以通过参数控制读取内容的开始点以及长度。

$content = file_get_contents('./test.txt', null, null, 100, 500);

PHP也提供类似于C语言操作文件的方法,使用fopen,fgets,fread等方法,fgets可以从文件指针中读取一行,freads可以读取指定长度的字符串。

$fp = fopen('./text.txt', 'rb');
while(!feof($fp)) {
    echo fgets($fp); //读取一行
}
fclose($fp);

 

$fp = fopen('./text.txt', 'rb');
$contents = '';
while(!feof($fp)) {
    $contents .= fread($fp, 4096); //一次读取4096个字符
}
fclose($fp);

使用fopen打开的文件,最好使用fclose关闭文件指针,以避免文件句柄被占用。

[php] view plain copy
  1. <?php  
  2.     $filename = 'text.txt';  
  3.     //编写代码读取$filename的文件内容  
  4.     $content = file_get_contents($filename);  
  5.     echo $content;  
  6. ?>  
  7. //////  
  8. this is a test file.  

PHP文件系统之判断文件是否存在

一般情况下在对文件进行操作的时候需要先判断文件是否存在,PHP中常用来判断文件存在的函数有两个is_file与file_exists.

$filename = './test.txt';
if (file_exists($filename)) {
    echo file_get_contents($filename);
}

如果只是判断文件存在,使用file_exists就行,file_exists不仅可以判断文件是否存在,同时也可以判断目录是否存在,从函数名可以看出,is_file是确切的判断给定的路径是否是一个文件。

$filename = './test.txt';
if (is_file($filename)) {
    echo file_get_contents($filename);
}

更加精确的可以使用is_readable与is_writeable在文件是否存在的基础上,判断文件是否可读与可写。

$filename = './test.txt';
if (is_writeable($filename)) {
    file_put_contents($filename, 'test');
}
if (is_readable($filename)) {
    echo file_get_contents($filename);
}


[php] view plain copy
  1. <?php  
  2.     $filename = 'text.txt';  
  3.     if (file_exists($filename)) {  
  4.         echo '文件存在';  
  5.     }else{  
  6.        echo '文件不存在';  
  7.     }  
  8. ?>  

PHP文件系统之取得文件的修改时间

文件有很多元属性,包括:文件的所有者、创建时间、修改时间、最后的访问时间等。

fileowner:获得文件的所有者
filectime:获取文件的创建时间
filemtime:获取文件的修改时间
fileatime:获取文件的访问时间

其中最常用的是文件的修改时间,通过文件的修改时间,可以判断文件的时效性,经常用在静态文件或者缓存数据的更新。

$mtime = filemtime($filename);
echo '修改时间:'.date('Y-m-d H:i:s', filemtime($filename));
[php] view plain copy
  1. <?php  
  2.     $filename = 'text.txt';  
  3.     echo '所有者:'.fileowner($filename).'<br>';  
  4.     echo '创建时间:'.filectime($filename).'<br>';  
  5.     echo '修改时间:'.filemtime($filename).'<br>';  
  6.     echo '最后访问时间:'.fileatime($filename).'<br>';  
  7.   
  8.     //给$mtime赋值为文件的修改时间  
  9.     $mtime = filemtime($filename);  
  10.     //通过计算时间差 来判断文件内容是否有效  
  11.     if (time() - $mtime > 3600) {  
  12.         echo '<br>缓存已过期';  
  13.     } else {  
  14.         echo file_get_contents($filename);  
  15.     }  
  16. ?>  

PHP文件系统之取得文件的大小

通过filesize函数可以取得文件的大小,文件大小是以字节数表示的。
[php] view plain copy
  1. <?php  
  2.     $filename = 'text.txt';  
  3.     $size = filesize($filename);  
  4.     echo $size;  
  5. ?>  

如果要转换文件大小的单位,可以自己定义函数来实现。
[php] view plain copy
  1. <?php  
  2.     function getsize($size$format = 'kb') {  
  3.         $p = 0;  
  4.         if ($format == 'kb') {  
  5.             $p = 1;  
  6.         } elseif ($format == 'mb') {  
  7.             $p = 2;  
  8.         } elseif ($format == 'gb') {  
  9.             $p = 3;  
  10.         }  
  11.         $size /= pow(1024, $p);  
  12.         return number_format($size, 3);  
  13.     }  
  14.   
  15.     $filename = 'text.txt';  
  16.     $size = filesize($filename);  
  17.   
  18.     $size = getsize($size'kb'); //进行单位转换  
  19.     echo $size.'kb';  
  20. ?>  

值得注意的是,没法通过简单的函数来取得目录的大小,目录的大小是该目录下所有子目录以及文件大小的总和,因此需要通过递归的方法来循环计算目录的大小。


日期和时间

PHP日期和时间之取得当前的Unix时间戳

[php] view plain copy
  1. UNIX 时间戳(英文叫做:timestamp)是 PHP 中关于时间与日期的一个很重要的概念,它表示从 1970年1月1日 00:00:00 到当前时间的秒数之和。  
  2.   
  3. PHP提供了内置函数 time() 来取得服务器当前时间的时间戳。那么获取当前的UNIX时间戳就很简单了。  
  4.   
  5. <?php  
  6.     $time = time();  
  7.     echo $time;  
  8. ?>  
  9. //1478270126,这个数字表示从1970年1月1日 00:00:00 到我输出这个脚本时经历了1478270126秒  

PHP日期和时间之取得当前的日期

php内置了date()函数,来取得当前的日期。

函数说明:date(时间戳的格式, 规定时间戳【默认是当前的日期和时间,可选】)

返回值:函数日期和时间

例子:

//date函数,第二个参数取默认值的情况
echo date("Y-m-d");//2014-03-30

//date函数,第二个参数有值的情况
echo date("Y-m-d",'1396193923');//2014-03-30,1396193923表示2014-03-30的unix时间戳

[php] view plain copy
  1. <?php  
  2.     //date函数,第二个参数取默认值的情况  
  3.     echo date("Y-m-d")."<br/>";//2014-03-30  
  4.   
  5.     //date函数,第二个参数有值的情况  
  6.     echo date("Y-m-d",'1396193923');//2014-03-30,1396193923表示2014-03-30的unix时间戳  
  7. ?>  

[php] view plain copy
  1. <?php  
  2. //设置默认的时区  
  3. date_default_timezone_set('Asia/Shanghai');  
  4. //输出1396193923对应的日期  
  5. echo date("Y-m-d",'1396193923');  
  6. ?>  

PHP日期和时间之取得日期的Unix时间戳

UNIX 时间戳(英文叫做:timestamp)是 PHP 中关于时间与日期的一个很重要的概念,它表示从 1970年1月1日 00:00:00 到当前时间的秒数之和。

PHP提供了内置函数strtotime实现功能:获取某个日期的时间戳,或获取某个时间的时间戳。例如:

echo strtotime('2014-04-29');//1398700800,这个数字表示从1970年1月1日 00:00:00 到2014年4月29号经历了1398700800秒

echo strtotime('2014-04-29 00:00:01');//1398700801,这个数字表示从1970年1月1日 00:00:00 到2014-04-29 00:00:01时经历了1398700801秒

大家发现上面的规律了吗,其实strtotime('2014-04-29')相当于strtotime('2014-04-29 00:00:00')
[php] view plain copy
  1. <?php  
  2. //设置默认时区是中国  
  3. date_default_timezone_set("Asia/Shanghai");  
  4. //获取2014-05-01的unix时间戳  
  5. echo strtotime('2014-05-01');  
  6. ?>  

PHP日期和时间之将格式化的日期字符串转换为Unix时间戳

strtotime函数预期接受一个包含美国英语日期格式的字符串并尝试将其解析为 Unix 时间戳。

函数说明:strtotime(要解析的时间字符串, 计算返回值的时间戳【默认是当前的时间,可选】)
返回值:成功则返回时间戳,否则返回 FALSE

比如

echo strtotime("now");//相当于将英文单词now直接等于现在的日期和时间,并把这个日期时间转化为unix时间戳。这个效果跟echo time();一样。
echo strtotime("+1 seconds");//相当于将现在的日期和时间加上了1秒,并把这个日期时间转化为unix时间戳。这个效果跟echo time()+1;一样。
echo strtotime("+1 day");//相当于将现在的日期和时间加上了1天。
echo strtotime("+1 week");//相当于将现在的日期和时间加上了1周。
echo strtotime("+1 week 3 days 7 hours 5 seconds");//相当于将现在的日期和时间加上了1周3天7小时5秒。
[php] view plain copy
  1. <?php  
  2. //设置默认时区是中国  
  3. date_default_timezone_set("Asia/Shanghai");  
  4. //返回现在时间过5秒后的unix时间戳  
  5. echo strtotime("+5 seconds");  
  6. ?>  

PHP日期和时间之格式化格林威治(GMT)标准时间

gmdate 函数能格式化一个GMT的日期和时间,返回的是格林威治标准时(GMT)。

举个例子,我们现在所在的中国时区是东八区,领先格林威治时间8个小时,有时候也叫GMT+8,那么服务器运行以下脚本返回的时间应该是这样的:
当前时间假定是2014-05-01 15:15:22
echo date('Y-m-d H:i:s', time()); //输出为:2014-05-01 15:15:22 
echo gmdate('Y-m-d H:i:s', time()); //输出为:2014-05-01 07:15:22 因为格林威治时间是现在中国时区的时间减去8个小时,所以相对于现在时间要少8个小时


[php] view plain copy
  1. <?php  
  2.     //设置默认时区是中国  
  3.     date_default_timezone_set("Asia/Shanghai");  
  4.     //返回2014-05-01 12:00:01的格林威治标准时间  
  5.     echo gmdate('Y-m-d H:i:s'strtotime('2014-05-01 12:00:01'));  
  6. ?>  



图形图像操作 

PHP图形操作之GD库简介

header("content-type: image/png");
$img=imagecreatetruecolor(100, 100);创建一个真彩色的空白图片:
$red=imagecolorallocate($img, 0xFF, 0x00, 0x00);进行分配画笔颜色
imagefill($img, 0, 0, $red);进行线条的绘制,通过指定起点跟终点来最终得到线条。
imagepng($img);得到一个图片文件,指定文件名将绘制后的图像保存到文件中。
imagedestroy($img);销毁图片

[php] view plain copy
  1. GD指的是Graphic Device,PHP的GD库是用来处理图形的扩展库,通过GD库提供的一系列API,可以对图像进行处理或者直接生成新的图片。  
  2.   
  3. PHP除了能进行文本处理以外,通过GD库,可以对JPG、PNG、GIF、SWF等图片进行处理。GD库常用在图片加水印,验证码生成等方面。  
  4.   
  5. PHP默认已经集成了GD库,只需要在安装的时候开启就行。  
  6.   
  7. header("content-type: image/png");  
  8. $img=imagecreatetruecolor(100, 100);  
  9. $red=imagecolorallocate($img, 0xFF, 0x00, 0x00);  
  10. imagefill($img, 0, 0, $red);  
  11. imagepng($img);  
  12. imagedestroy($img);  

[php] view plain copy
  1. <?php  
  2.     header("content-type: image/png");  
  3.     $img=imagecreatetruecolor(200, 100);  
  4.     $red=imagecolorallocate($img, 0, 0, 0);  
  5.     imagefill($img, 0, 0, $red);  
  6.     imagepng($img);  
  7.     imagedestroy($img);  
  8. ?>  

PHP图形操作之绘制线条


要对图形进行操作,首先要新建一个画布,通过imagecreatetruecolor函数可以创建一个真彩色的空白图片:

$img = imagecreatetruecolor(100, 100);

GD库中对于画笔所用的颜色,需要通过imagecolorallocate函数进行分配,通过参数设定RGB的颜色值来确定画笔的颜色:

$red = imagecolorallocate($img, 0xFF, 0x00, 0x00);

然后我们通过调用绘制线段函数imageline进行线条的绘制,通过指定起点跟终点来最终得到线条。

imageline($img, 0, 0, 100, 100, $red);

线条绘制好以后,通过header与imagepng进行图像的输出。

header("content-type: image/png");
imagepng($img);

最后可以调用imagedestroy释放该图片占用的内存。

imagedestroy($img);

通过上面的步骤,可以发现PHP绘制图形非常的简单,但很多时候我们不只是需要输出图片,可能我们还需要得到一个图片文件,可以通过imagepng函数指定文件名将绘制后的图像保存到文件中。

imagepng($img, 'img.png');

[php] view plain copy
  1. <?php  
  2.     $img = imagecreatetruecolor(70, 20);  
  3.     $red = imagecolorallocate($img, 0xFF, 0x00, 0x00);  
  4.     //在这里绘制文字  
  5.     $str ="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";  
  6.     $str1 = " ";  
  7.     for($i=0;$i<6;$i++)//循环6次  
  8.     {  
  9.         $str1 .= $str[rand(0,(strlen($str)-1))];//连接随机字符  
  10.     }  
  11.     imagestring($img,5,0,0,$str1,$red);  
  12.     header("content-type: image/png");  
  13.     imagepng($img);  
  14.     imagedestroy($img);  


PHP图形操作之输出图像文件

通过imagepng可以直接输出图像到浏览器,但是很多时候,我们希望将处理好的图像保存到文件,以便可以多次使用。通过指定路径参数将图像保存到文件中。
$filename = 'img.png';
imagepng($img, $filename);

使用imagepng可以将图像保存成png格式,如果要保存成其他格式需要使用不同的函数,使用imagejpeg将图片保存成jpeg格式,imagegif将图片保存成gif格式,需要说明的是,imagejpeg会对图片进行压缩,因此还可以设置一个质量参数。

$filename = 'img.jpg';
​imagejpeg($img, $filename, 80);
[php] view plain copy
  1. <?php  
  2.     $img = imagecreatetruecolor(100, 100);  
  3.     $red = imagecolorallocate($img, 0xFF, 0x00, 0x00);  
  4.     imagestring($img, 5, 0, 0, "Hello world"$red);  
  5.     $filename = 'img.png';  
  6.     //在这里将图片保存到$filename文件中  
  7.     imagepng($img$filename);  
  8.   
  9.     imagedestroy($img);  
  10.     if (file_exists($filename)) {  
  11.         echo '文件保存成功';  
  12.     }  

PHP图形操作之生成图像验证码

简单的验证码其实就是在图片中输出了几个字符,通过我们前面章节讲到的imagestring函数就能实现。

但是在处理上,为了使验证码更加的安全,防止其他程序自动识别,因此常常需要对验证码进行一些干扰处理,通常会采用绘制一些噪点,干扰线段,对输出的字符进行倾斜、扭曲等操作。

可以使用imagesetpixel绘制点来实现噪点干扰,但是只绘制一个点的作用不大,因此这里常常会使用循环进行随机绘制。

for($i=0;$i<50;$i++) {
  imagesetpixel($im, rand(0, 100) , rand(0, 100) , $black); 
  imagesetpixel($im, rand(0, 100) , rand(0, 100) , $green);
} 
[php] view plain copy
  1. <?php  
  2.     $img = imagecreatetruecolor(100, 40);  
  3.     $black = imagecolorallocate($img, 0x00, 0x00, 0x00);  
  4.     $green = imagecolorallocate($img, 0x00, 0xFF, 0x00);  
  5.     $white = imagecolorallocate($img, 0xFF, 0xFF, 0xFF);  
  6.     imagefill($img,0,0,$white);  
  7.     //生成随机的验证码  
  8.     $code = '';  
  9.     for($i = 0; $i < 4; $i++) {  
  10.         $code .= rand(0, 9);  
  11.     }  
  12.     imagestring($img, 5, 10, 10, $code$black);  
  13.     //加入噪点干扰  
  14.     for($i=0;$i<400;$i++) {  
  15.       imagesetpixel($img, rand(0, 100) , rand(0, 100) , $black);   
  16.       imagesetpixel($img, rand(0, 100) , rand(0, 100) , $green);  
  17.     }  
  18.     //输出验证码  
  19.     header("content-type: image/png");  
  20.     imagepng($img);  
  21.     imagedestroy($img);  


PHP图形操作之给图片添加水印

给图片添加水印的方法一般有两种,一种是在图片上面加上一个字符串,另一种是在图片上加上一个logo或者其他的图片。

因为这里处理的是已经存在的图片,所以可以直接从已存在的图片建立画布,通过imagecreatefromjpeg可以直接从图片文件创建图像。

$im = imagecreatefromjpeg($filename);

创建图像对象以后,我们就可以通过前面的GD函数,绘制字符串到图像上。如果要加的水印是一个logo图片,那么就需要再建立一个图像对象,然后通过GD函数imagecopy将logo的图像复制到源图像中。

$logo = imagecreatefrompng($filename);
imagecopy($im, $logo, 15, 15, 0, 0, $width, $height);

当将logo图片复制到原图片上以后,将加水印后的图片输出保存就完成了加水印处理。

imagejpeg($im, $filename);
[php] view plain copy
  1. <?php  
  2.     //这里仅仅是为了案例需要准备一些素材图片  
  3.     $url = 'http://www.iyi8.com/uploadfile/2014/0521/20140521105216901.jpg';  
  4.     $content = file_get_contents($url);  
  5.     $filename = 'tmp.jpg';  
  6.     file_put_contents($filename$content);  
  7.     $url = 'http://wiki.ubuntu.org.cn/images/3/3b/Qref_Edubuntu_Logo.png';  
  8.     file_put_contents('logo.png'file_get_contents($url));  
  9.     //开始添加水印操作  
  10.     $im = imagecreatefromjpeg($filename);  
  11.     $logo = imagecreatefrompng('logo.png');  
  12.     $size = getimagesize('logo.png');  
  13.     imagecopy($im$logo, 15, 15, 0, 0, $size[0], $size[1]);   
  14.        
  15.     header("content-type: image/jpeg");  
  16.     imagejpeg($im);  


PHP异常处理

PHP异常处理之抛出一个异常

从PHP5开始,PHP支持异常处理,异常处理是面向对象一个重要特性,PHP代码中的异常通过throw抛出,异常抛出之后,后面的代码将不会再被执行。

既然抛出异常会中断程序执行,那么为什么还需要使用异常处理?

异常抛出被用于在遇到未知错误,或者不符合预先设定的条件时,通知客户程序,以便进行其他相关处理,不至于使程序直接报错中断。

当代码中使用了try catch的时候,抛出的异常会在catch中捕获,否则会直接中断。

 

1、基本语法
        try{
            //可能出现错误或异常的代码
            //catch表示捕获,Exception是php已定义好的异常类
        } catch(Exception $e){
            //对异常处理,方法:
                //1、自己处理
                //2、不处理,将其再次抛出
        }
2、处理处理程序应当包括:
Try - 使用异常的函数应该位于 "try"  代码块内。如果没有触发异常,则代码将照常继续执行。但是如果异常被触发,会抛出一个异常。
Throw - 这里规定如何触发异常。注意:每一个 "throw" 必须对应至少一个 "catch",当然可以对应多个"catch"
Catch - "catch" 代码块会捕获异常,并创建一个包含异常信息的对象。

//创建可抛出一个异常的函数
function checkNum($number){
     if($number>1){
         throw new Exception("异常提示-数字必须小于等于1");
     }
     return true;
 }
 
//在 "try" 代码块中触发异常
 try{
     checkNum(2);
     //如果异常被抛出,那么下面一行代码将不会被输出
     echo '如果能看到这个提示,说明你的数字小于等于1';
 }catch(Exception $e){
     //捕获异常
     echo '捕获异常: ' .$e->getMessage();
 }

上面代码将获得类似这样一个错误:

捕获异常:: 异常提示-数字必须小于等于1

例子解释:

上面的代码抛出了一个异常,并捕获了它:

创建 checkNum() 函数。它检测数字是否大于 1。如果是,则抛出一个异常。
在 "try" 代码块中调用 checkNum() 函数。
checkNum() 函数中的异常被抛出
"catch" 代码块接收到该异常,并创建一个包含异常信息的对象 ($e)。
通过从这个 exception 对象调用 $e->getMessage(),输出来自该异常的错误消息

[php] view plain copy
  1. <?php  
  2. $filename = 'test.txt';  
  3. try {  
  4.     if (!file_exists($filename)) {  
  5.       throw new Exception('文件不存在');  
  6.     }  
  7. } catch(Exception $e) {  
  8.     echo $e->getMessage();  
  9. }  

PHP异常处理之异常处理类

PHP具有很多异常处理类,其中Exception是所有异常处理的基类。

Exception具有几个基本属性与方法,其中包括了:

message 异常消息内容
code 异常代码
file 抛出异常的文件名
line 抛出异常在该文件的行数

其中常用的方法有:

getTrace 获取异常追踪信息
getTraceAsString 获取异常追踪信息的字符串
getMessage 获取出错信息

如果必要的话,可以通过继承Exception类来建立自定义的异常处理类。

//自定义的异常类,继承了PHP的异常基类Exception
class MyException extends Exception {
    function getInfo() {
        return '自定义错误信息';
    }
}

try {
    //使用异常的函数应该位于 "try"  代码块内。如果没有触发异常,则代码将照常继续执行。但是如果异常被触发,会抛出一个异常。
    throw new MyException('error');//这里规定如何触发异常。注意:每一个 "throw" 必须对应至少一个 "catch",当然可以对应多个"catch"
} catch(Exception $e) {//"catch" 代码块会捕获异常,并创建一个包含异常信息的对象
    echo $e->getInfo();//获取自定义的异常信息
    echo $e->getMessage();//获取继承自基类的getMessage信息
}
[php] view plain copy
  1. <?php  
  2. class MyException extends Exception {  
  3.     function getInfo() {  
  4.         return '自定义错误信息';  
  5.     }  
  6. }  
  7.   
  8. try {  
  9.     throw new MyException('error');  
  10. } catch(Exception $e) {  
  11.     echo $e->getInfo();  
  12. }  
  13. ?>  

PHP异常处理之捕获异常信息

我们可以通过try catch来捕获异常,我们将执行的代码放在try代码块中,一旦其中的代码抛出异常,就能在catch中捕获。

这里我们只是通过案例来了解try catch的机制以及异常捕获的方法,在实际应用中,不会轻易的抛出异常,只有在极端情况或者非常重要的情况下,才会抛出异常,抛出异常,可以保障程序的正确性与安全,避免导致不可预知的bug。

一般的异常处理流程代码为:

try {
    throw new Exception('wrong');
} catch(Exception $ex) {
    echo 'Error:'.$ex->getMessage().'<br>';
    echo $ex->getTraceAsString().'<br>';
}
echo '异常处理后,继续执行其他代码';
[php] view plain copy
  1. <?php  
  2. try {  
  3.     throw new Exception('wrong');  
  4. } catch(Exception $ex) {  
  5.     echo 'Error:'.$ex->getMessage().'<br>';  
  6.     echo $ex->getTraceAsString().'<br>';  
  7. }  
  8. echo '异常处理后,继续执行其他代码';  

PHP异常处理之获取错误发生的所在行

在异常被捕获之后,我们可以通过异常处理对象获取其中的异常信息,前面我们已经了解捕获方式,以及获取基本的错误信息。

在实际应用中,我们通常会获取足够多的异常信息,然后写入到错误日志中。

通过我们需要将报错的文件名、行号、错误信息、异常追踪信息等记录到日志中,以便调试与修复问题。

[php] view plain copy
  1. <?php  
  2. try {  
  3.     throw new Exception('wrong');  
  4. } catch(Exception $ex) {  
  5.     $msg = 'Error:'.$ex->getMessage()."\n";  
  6.     $msg.= $ex->getTraceAsString()."\n";  
  7.     $msg.= '异常行号:'.$ex->getLine()."\n";  
  8.     $msg.= '所在文件:'.$ex->getFile()."\n";  
  9.     //将异常信息记录到日志中  
  10.     file_put_contents('error.log'$msg);  
  11. }  


数据库操作

PHP支持哪些数据库

PHP通过安装相应的扩展来实现数据库操作,现代应用程序的设计离不开数据库的应用,当前主流的数据库有MsSQL,MySQL,Sybase,Db2,Oracle,PostgreSQL,Access等,这些数据库PHP都能够安装扩展来支持,一般情况下常说的LAMP架构指的是:Linux、Apache、Mysql、PHP,因此Mysql数据库在PHP中的应用非常广泛
[php] view plain copy
  1. <?php  
  2. if (function_exists('mysql_connect')) {  
  3.     echo 'Mysql扩展已经安装';  
  4. }  
  5. ?>  

PHP数据库扩展

HP中一个数据库可能有一个或者多个扩展,其中既有官方的,也有第三方提供的。像Mysql常用的扩展有原生的mysql库,也可以使用增强版的mysqli扩展,还可以使用PDO进行连接与操作。

不同的扩展提供基本相近的操作方法,不同的是可能具备一些新特性,以及操作性能可能会有所不同。

MySQL扩展进行数据库连接的方法:

$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password');

mysqli扩展:

$link = mysqli_connect('mysql_host', 'mysql_user', 'mysql_password');

PDO扩展

$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
[php] view plain copy
  1. <?php  
  2. $link = mysql_connect('127.0.0.1''code1'''or die('数据库连接失败');  
  3. mysql_select_db('code1');  
  4. mysql_query("set names 'utf8'");  
  5. $result = mysql_query('select * from user limit 1');  
  6. $row = mysql_fetch_assoc($result);  
  7. print_r($row);  

PHP数据库操作之连接MySQL数据库

PHP要对数据库进行操作,首先要做的是与数据库建立连接,通常我们使用mysql_connect函数进行数据库连接,该函数需要指定数据库的地址,用户名及密码。

$host = 'localhost';
$user = 'code1';
$pass = '';
$link = mysql_connect($host, $user, $pass);

PHP连接数据库的方式类似于直接在命令行下通过进行连接,类似:mysql -hlocalhost -ucode1 -p,当连接成功以后,我们需要选择一个操作的数据库,通过mysql_select_db函数来选择数据库。

mysql_select_db('code1');

通常我们会先设置一下当前连接使用的字符编码,一般的我们会使用utf8编码。

mysql_query("set names 'utf8'");

通过上面的步骤,我们就与数据库建立了连接,可以进行数据操作了。

[php] view plain copy
  1. <?php  
  2. $host = '127.0.0.1';  
  3. $user = 'code1';  
  4. $pass = '';  
  5. //在这里编写数据库连接代码  
  6. $link = mysql_connect($host$user$pass);  
  7. mysql_select_db('code1');  
  8. mysql_query("set names 'utf8'");  

PHP数据库操作之执行MySQL查询

在数据库建立连接以后就可以进行查询,采用mysql_query加sql语句的形式向数据库发送查询指令。

$res = mysql_query('select * from user limit 1');

对于查询类的语句会返回一个资源句柄(resource),可以通过该资源获取查询结果集中的数据。

$row = mysql_fetch_array($res);
var_dump($row);

默认的,PHP使用最近的数据库连接执行查询,但如果存在多个连接的情况,则可以通过参数指令从那个连接中进行查询。

$link1 = mysql_connect('127.0.0.1', 'code1', '');
$link2 = mysql_connect('127.0.0.1', 'code1', '', true); //开启一个新的连接
$res = mysql_query('select * from user limit 1', $link1); //从第一个连接中查询数据
[php] view plain copy
  1. <?php  
  2. //连接数据库  
  3. error_reporting(0);  
  4. mysql_connect('127.0.0.1''code1''');  
  5. mysql_select_db('code1');  
  6. mysql_query("set names 'utf8'");  
  7. //在这里进行数据查询  
  8. $res=mysql_query('select * from user limit 1');  
  9. $row=mysql_fetch_array($res);  
  10. var_dump($row);  

PHP数据库操作之插入新数据到MySQL中

当我们了解了如何使用mysql_query进行数据查询以后,那么类似的,插入数据其实也是通过执行一个sql语句来实现,例如:

$sql = "insert into user(name, age, class) values('李四', 18, '高三一班')";
mysql_query($sql); //执行插入语句

通常数据都是存储在变量或者数组中,因此sql语句需要先进行字符串拼接得到。

$name = '李四';
$age = 18;
$class = '高三一班';
$sql = "insert into user(name, age, class) values('$name', '$age', '$class')";
mysql_query($sql); //执行插入语句

在mysql中,执行插入语句以后,可以得到自增的主键id,通过PHP的mysql_insert_id函数可以获取该id。

$uid = mysql_insert_id();

这个id的作用非常大,通常可以用来判断是否插入成功,或者作为关联ID进行其他的数据操作。

[php] view plain copy
  1. <?php  
  2. //连接数据库  
  3. mysql_connect('127.0.0.1''code1''');  
  4. mysql_select_db('code1');  
  5. mysql_query("set names 'utf8'");  
  6. //已知的数据变量有  
  7. $name = '李四';  
  8. $age = 18;  
  9. $class = '高三一班';  
  10. //在这里进行数据查询  
  11.   
  12. //首先查看有什么数据表  
  13. print_r(mysql_fetch_array(mysql_query('SHOW TABLES')));  
  14. //查看表的结构,可以看到5个字段  
  15. $sql = mysql_query('DESC test');  
  16. var_dump(mysql_fetch_array($sql));  
  17. //查看表的数据  
  18. $sql = mysql_query('SELECT * FROM test');  
  19. var_dump(mysql_fetch_array($sql));  
  20. //插入数据  
  21. $sql = mysql_query("INSERT test('name','age','class') VALUES('$name','$age','$class')");  
  22. var_dump(mysql_insert_id());  

PHP数据库操作之取得数据查询结果

通过前面的章节,我们发现PHP操作数据库跟MySql客户端上操作极为相似,先进行连接,然后执行sql语句,再然后获取我们想要的结果集。

PHP有多个函数可以获取数据集中的一行数据,最常用的是mysql_fetch_array,可以通过设定参数来更改行数据的下标,默认的会包含数字索引的下标以及字段名的关联索引下标。

$sql = "select * from user limit 1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);

可以通过设定参数MYSQL_NUM只获取数字索引数组,等同于mysql_fetch_row函数,如果设定参数为MYSQL_ASSOC则只获取关联索引数组,等同于mysql_fetch_assoc函数。

$row = mysql_fetch_row($result);
$row = mysql_fetch_array($result, MYSQL_NUM); //这两个方法获取的数据是一样的
$row = mysql_fetch_assoc($result);
$row = mysql_fetch_array($result, MYSQL_ASSOC);

如果要获取数据集中的所有数据,我们通过循环来遍历整个结果集。

$data = array();
while ($row = mysql_fetch_array($result)) {
    $data[] = $row;
}
[php] view plain copy
  1. <?php  
  2. //连接数据库  
  3. mysql_connect('127.0.0.1''code1''');  
  4. mysql_select_db('code1');  
  5. mysql_query("set names 'utf8'");  
  6. //数据预处理 防止查询不到数据  
  7. mysql_query("insert into user(name, age, class) values('王二', 19, '高三五班')");  
  8. //进行数据查询  
  9. $sql = "select * from user limit 1";  
  10. $result = mysql_query($sql);  
  11.   
  12. //在这里获取一行数据  
  13. // $row=mysql_fetch_row($result);  
  14. $row=mysql_fetch_row($result);  
  15.   
  16. echo '<pre>';  
  17. print_r($row);  
  18. echo '</pre>';  

PHP数据库操作之查询分页数据

上一节中,我们了解到通过循环可以获取一个查询的所有数据,在实际应用中,我们并不希望一次性获取数据表中的所有数据,那样性能会非常的低,因此会使用翻页功能,每页仅显示10条或者20条数据。

通过mysql的limit可以很容易的实现分页,limit m,n表示从m行后取n行数据,在PHP中我们需要构造m与n来实现获取某一页的所有数据。

假定当前页为$page,每页显示$n条数据,那么m为当前页前面所有的数据,既$m = ($page-1) * $n,在知道了翻页原理以后,那么我们很容易通过构造SQL语句在PHP中实现数据翻页。

$page = 2;
$n = 2;
$m = ($page - 1) * $n;
$sql = "select * from user limit $m, $n";
$result = mysql_query($sql);
//循环获取当前页的数据
$data = array();
while ($row = mysql_fetch_assoc($result)) {
    $data[] = $row;
}

在上面的例子中,我们使用了$m与$n变量来表示偏移量与每页数据条数,但我们推荐使用更有意义的变量名来表示,比如$pagesize, $start, $offset等,这样更容易理解,有助于团队协作开发。

[php] view plain copy
  1. <?php  
  2. //连接数据库  
  3. mysql_connect('127.0.0.1''code1''');  
  4. mysql_select_db('code1');  
  5. mysql_query("set names 'utf8'");  
  6. //预设翻页参数  
  7. $page = 2;  
  8. $pagesize = 2;  
  9. //在这里构建分页查询  
  10. $offset = ($page - 1) * $pagesize;  
  11. $sql = "select * from user limit $offset, $pagesize";  
  12.   
  13. //获取翻页数据  
  14. $result = mysql_query($sql);  
  15. $data = array();  
  16. while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {  
  17.     $data[] = $row;  
  18. }  
  19. echo '<pre>';  
  20. print_r($data);  
  21. echo '</pre>';  

[php] view plain copy
  1. <?php  
  2. //连接数据库  
  3. mysql_connect('127.0.0.1''code1''');  
  4. mysql_select_db('code1');  
  5. mysql_query("set names 'utf8'");  
  6. //预设数据以便进行更新操作  
  7. mysql_query("insert into user(name, age, class) values('王二', 19, '高三五班')");  
  8. $id = mysql_insert_id();  
  9. //在这里更新id为$id的行的名字为李白  
  10. $sql = "update user set name='李白' where id=$id";  
  11. mysql_query($sql);  
  12. //输出更新数据条数  
  13. echo '数据更新行数:'.mysql_affected_rows();  
  14. mysql_query("delete from user where id='$id'");  

PHP数据库操作之关闭MySQL连接

当数据库操作完成以后,可以使用mysql_close关闭数据库连接,默认的,当PHP执行完毕以后,会自动的关闭数据库连接。

mysql_close();

虽然PHP会自动关闭数据库连接,一般情况下已经满足需求,但是在对性能要求比较高的情况下,可以在进行完数据库操作之后尽快关闭数据库连接,以节省资源,提高性能。

在存在多个数据库连接的情况下,可以设定连接资源参数来关闭指定的数据库连接。

$link = mysql_connect($host, $user, $pass);
mysql_close($link);
[php] view plain copy
  1. <?php  
  2. //连接数据库  
  3. mysql_connect('127.0.0.1''code1''');  
  4. mysql_select_db('code1');  
  5. mysql_query("set names 'utf8'");  
  6. //在这里关闭数据库连接  
  7. mysql_close();  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章