PHP基础

293 阅读14分钟

5、字符串操作

5.1、字符串的定义方法

5.1.1、使用单引号或双引号定义字符串

字符串通常以串的整体作为操作对象,一般引用双引号或者单引号标识一个字符串。单引号和双引号在使用上有一定区别

<?php
  $text = "PHP";
  $str = '单引号$text';
  $str2 = "双引号$text";
  echo $str;
  echo "<br>";
  echo $str2;
?>

image.png

单引号不能解释变量,而双引号可以

5.1.2、使用定界符定义字符串

定界符(<<<)是从PHP4开始的,定界符用于定义格式化的大文本,格式化是指文本中的格式将被保留,所以文本中不需要使用转义字符。在使用是后面接一个标识符,然后是格式化文本(即字符串),最后是同样的标识符结束字符串

格式: <<<str 格式化文本 str

其中,符号<<<是关键字,必须使用str为用户自定义的标识符,用于定义文本的起始标识符和结束标识符,前后标识符名字必须完全相同

<?php
$str = '使用定界符';
echo <<<ding
  <font color="red">$str</font>
ding;

?>

image.png

定界符中的字符串支持单引号、双引号,无须转义,并支持字符变量转换

5.2、字符串操作

5.2.1、去除字符串首尾空格和特殊字符

trim()函数

用于去除字符串首尾空白字符(或其他字符)

<?php
$srt = "\r\r(:我是字符:)";
echo $srt;
echo "<br/>";
echo trim($srt,"\r\r(::)");
?>

image.png

ltrim()函数

用于去除字符串左边的空白字符(或其他字符)

<?php
$srt = "@__@我是字符@__@";
echo $srt;
echo "<br/>";
echo ltrim($srt,"@__@");
?>

image.png

rtrim()函数

用于去除字符串右边的空白字符(或其他字符)

<?php
$srt = "@__@我是字符@__@";
echo $srt;
echo "<br/>";
echo rtrim($srt,"@__@");
?>

image.png

5.2.2、转义、还原字符串数据

字符串转义、还原的方法有两种,一种是手动,一种是自动

手动转义、还原字符串数据

如果要在字符串中表示单引号,则需要反斜线(\)进行转义。例如,要表示字符串I'm 则要改成 I'm

对于简单的字符串建议采用手动,复杂的字符串用自动

自动转义、还原字符串数据

  1. addslashes()函数 用于使用反斜线引用字符串
  2. stripslashes()函数 用于反引用一个引用字符串
<?php
$str = "Hello World!'PHP'";
echo $str."<br>";
$a = addslashes($str);
echo $a."<br>";
$b = stripslashes($a);
echo $b."<br>";
?>

image.png

所有数据在入数据库前,有必要应用addslashes()函数进行字符串转义,以免特殊字符未经转义在插入数据库时出现错误,另外,对于使用addslashes()函数实现的自动转义字符串可以使用stripslashes()函数进行还原,但数据在入数据库前必须再次进行转义

对指定范围的字符串进行自动转义、还原

  1. addcslashes()函数 实现转义字符串中的字符,即在指定的字符前加上反斜线
  2. stripcslashes() 函数 用来将addcslashes()函数转义的字符还原
<?php
$a = "我是字符串";
echo $a."<br>";
$b = addcslashes($a,'我是字符串');
echo $b."<br>";
$c = stripcslashes($b);
echo $c."<br>";
?>

image.png 在缓存文件中,一般对缓存数据的值采用addcslashes()函数进行指定范围的转义

5.2.3、获取字符串的长度

strlen()函数 获取长度的同时也可以检验字符串的长度

汉字占两个字符,数字、英文、小数点、下划线、宫格占用一个

<?php
if(strlen($_POST['password'])<6){
  echo "密码长度不能小于6位";
}
?>

5.2.4、截取字符串

substr()函数 截取指定字符串中指定的长度

<?php
$str = "Hello World!";
echo substr($str, 0, 5);
echo "<br>";
echo substr($str, -6, 5); 
?>

image.png

从指定的字符串中按照指定的位置截取一定长度的字符串。通过substr()函数可以获取某个固定格式字符串的一部分

5.2.5、比较字符串

按字节进行比较

  1. strcmp()函数 区分大小写
  2. strcasecmp()函数 不区分大小写
<?php
$srt = '@__@我是字符@__@';
$srt2 = "@__@我是字符@__@";
$str3 = 'str';
$str4 = 'STR';
echo strcmp($srt, $srt2);
echo strcmp($str3, $str4);
echo strcasecmp($str3, $str4);
?>

image.png

按自然排序进行比较

  1. strnatcmp() 区分大小写
  2. strnatcasecmp() 不区分大小写
<?php
$str = "str1.jpg";
$str2 = "str2.jpg";
$str3 = "str";
$str4 = "STR";
echo strnatcmp($str,$str2);
echo "<br>";
echo strnatcmp($str3,$str4);
echo "<br>";
echo strnatcasecmp($str3,$str4);
?>

image.png

指定从源字符串的位置进行比较

strncmp()函数 比较字符串的前N个字符

<?php
$str = "Hello World!";
$str2 = "PHP";
echo strncmp($str, $str2, 2); // 比较前两个字符
?>

image.png

5.2.6、检索字符串

  1. strstr() 获取指定字符串在另一个字符串中首次出现的位置到后者末尾的子字符串,成功就返回首次出现开始到结束的字符串
  2. strrchr() 正好相反 找的顺序相反,但成功就返回首次出现开始到结束的字符串,这个相同
<?php
$str = "Hello World";
echo strstr($str, "W");//从H开始找W
echo  "<br>";
echo strrchr($str, "W"); //从d开始找W
?>

image.png

  1. substr_count() 字符出现次数
<?php
$str = "我是我";
echo substr_count($str,"我");
?>

image.png

5.2.7、替换字符串

  1. str_ireplace() 使用新的字符串替换原始字符串中被指定的字符串
<?php
$str = "Hello World!";
$str2 = "NONONO";
$newStr = "你好世界!Hello World!";
echo str_ireplace($str, $str2, $newStr);
?>

image.png

  1. substr_replace() 对指定字符串中的部分字符串进行替换
<?php
$str = "Hello World!";
$newStr = "aaaaaHello World!";
echo substr_replace($newStr, $str, 0, 5);
?>

image.png

5.2.8、格式化字符串

number_format() 将数字字符串格式化

<?php
$num = 1234.94;
echo number_format($num);
echo "<br>";
echo  number_format($num, 2);
echo "<br>";
echo number_format($num, 2, "-", "/");
?>

image.png

5.2.9、分割、合成字符串

  1. explode() 字符串分割成数组
<?php
$str = "Hello-World!";
$log = explode("-", $str);
print_r($log);
?>

image.png

  1. implode() 合成 将数组合成字符串
<?php
$str = "Hello-World!";
$log = explode("-", $str);
print_r($log);
$imp = implode("-", $log);
echo($imp);
?>

image.png

6、正则

6.1、什么是正则 略

6.2、正则的语法规则

6.2.1、行定位符 (^和$)

行定位符就是用来描述字串边界。^表示开始,$表示结尾

  1. ^tm 以tm开头的
  2. tm$ 以tm结尾
  3. tm 任意位置出现tm

6.2.2 单词分界符 (\b,\B)

  1. \btm\b 单词tm 不是单词的不找 如:html 就不会找到
  2. \Btm\ 不能是单词 html就会被找到

6.2.3、字符类([])

[Ti][Mm] 忽略大小写

6.2.4、选择字符(|)

(T|t)(M|m) 以T或t开头,后面接一个M或m

和[]的区别在于,[]只能匹配单个字符,|可以匹配任意长度的字串

6.2.5、连接字符(-)

[a-zA-z] 以字母开头

6.2.6、排除字符([^])

[^a-zA-z] 排除字母开头

6.2.7 限定符(?*+{n,m})

6.2.8 点好字符(.)

匹配任意一个字符

^s.t$ s开头中间任意一个字符,t结尾

6.2.9 转义字符(\)

6.2.10 反斜线(\)

6.2.11 括号字符(())

6.2.12 反向引用

6.2.13 模式修饰符

6.3 PCRE兼容正则表达式函数

6.3.1 preg_grep()

使用数组中的元素一一比配,最后返回由所有想匹配的元素组成的数组

<?php
$preg = "/\d{3,4}-?\d{7,8}/";
$arr = array('043212345678','043-7654321','12345678');
$preg_arr = preg_grep($preg, $arr);
var_dump($preg_arr);
?>

image.png

6.3.2 preg_atch() 和 preg_match_all()

preg_atch/preg_match_all(string pattern,string subject [,array matches])

在字符串subject中匹配表达式pattern,函数返回匹配次数。如果有数组matches,那么每次匹配的结果都将被存储到数组matches

<?php
$str = 'This is an example';
$preg = '/\b\w{2}\b/';
$num1 = preg_match($preg, $str,$str1);
echo $num1.'<br>';
var_dump($str1);
$num2 = preg_match_all($preg, $str, $str2);
echo '<p>'.$num2.'</p>';
var_dump($str2);
?>

image.png

6.3.3、preg_quote()

将字符串str中的所有特殊字符进行自动转义。如果有参数delimiter那么参数所包含的字符串也将被转义。函数返回转移后的字串

<?php
$str = '!、$、b';
$str2 = 'b';
$match_one = preg_quote($str,$str2);
echo $match_one;
?>

image.png

6.3.4、preg_replace()

在字符串subject中匹配表达式pattern,并将匹配项替换成字串replacement,如果有参数limit,则替换limit

<?php
$str = '[b]粗体[/b]';
$b_rst = preg_replace('/\[b\](.*?)\[\/b\]/i', '<b>$1</b>', $str);
echo $b_rst;
?>

image.png

6.3.5、 preg_replace_callback()

preg_replace()功能相同,都用于查找和替换字串,不同的是此函数用回调函数来代替replacement参数

6.3.6、preg_split()

使用表达式pattern 来分割字符串subject。如果有参数limit,那么数组最多有limit个元素。该函数与ereg_split()使用方法相同

6.4 应用正则对用户注册信息进行验证(验证手机号)

<?php

function validate_phone($phone) {
   if (preg_match('/^1[3-9]\d{9}$/', $phone)) {
       return true;
   } else {
       return false;
   }
}

$phone = "13812345678";

if (validate_phone($phone)) {
   echo "Valid phone number";
} else {
   echo "Invalid phone number";
}

?>

7、 数组

7.1、什么是数组 略

7.2 声明数组

  1. array('xx','xx')
  2. array('1'=>"xx",'a'=>'b')

使用:print_r()输出

7.3 二维数组

array([1,2])

7.4 数组遍历

foreach

<?php
$array = array("apple" => "A", "banana" => "B", "cherry" => "C", "orange" => "D");

foreach ($array as $key => $value) {
 echo "Key: " . $key . ", Value: " . $value . "<br>";
}

?>


image.png

7.5、数组与字符串的转换

位于 5.2.9、分割、合成字符串

7.6、统计数组元素个数

count(mixed array [, int mode])

7.7、查询数组中指定元素

array_search(mixed needle,array haystack [,bool strict])

常用于购物车,实现对购物车中指定商品数量的修改和删除

7.8、 获取数组中最后一个元素

array_pop(array array)

7.9 向数组中添加元素

array_push(array array, mixed var[,mixed])

7.10删除数组中重复的元素

array_unique(array array)

10、 日期

10.1、系统时区设置

10.1.2 时区设置

data_default_timezone_set(timezone)

10.2 PHP日期和时间函数

10.2.1 获取本地化时间戳

mktime() 将一个时间转换成UNIX的时间戳 mktime(int hour, int minute, int second,int month, int day, int year, int [is_dst])

<?php
  echo '时间戳:'.mktime(12,23,56,12,10,2012);
  echo '<br/>';
  echo '日期:'.date('Y-m-d H:i:s',mktime(12,23,56,12,10,2012));
?>

image.png

10.2.2 获取当前时间

<?php
  $newTime = time() + (7*24*60*60);
  echo '当前时间:'.date('Y-m-d H:i:s');
  echo '<br/>';
  echo '下周:'.date('Y-m-d H:i:s', $newTime);
?>

image.png

10.2.4 获取日期信息

getdate(int timestamp)

<?php
  $newTime = getdate();
  print_r($newTime);
?>

image.png

10.2.5 检测时间的有效性

checkdate(int month, int day, int year)

核心技术

11、Cookie 与 Session

11.1、Cookie

11.1.1、了解Cookie

Cookie是一种在远程浏览器端存数据并以此来跟踪和识别用户的机制。简单来说,Cookie是Web服务器暂时存在用户硬盘上的一个文本文件,并随后被Web浏览器读取

在Cookie文件夹下,每个Cookie文件都是一个简单而又普通的文本文件,而不是程序。Cookies中的内容大多都经过了加密处理,因此,表面看来只是一些字母和数字组合,而只有服务器的CGI处理程序才知道它们真正的含义

注意:一般不要使用Cookie来存数据集或其他大量数据。并非所有的浏览器都支持Cookie,并且数据信息是以明文文本的形式保存在客户端中,因此最好不要保存敏感数据,否则会影响网络的安全性

11.1.2、创建Cookie

在PHP中通过setcookie()创建Cookie。在创建之前必须了解的是,Cookie是HTTP头标的组成部分,而头标必须在页面其他内容之前发送,它必须最先输出。若在setcookie()函数前输出一个HTML标记或echo语句,甚至一个空行都会报错

11.1.3、读取Cookie

$_COOKIE[]

11.1.4、删除Cookie

当Cookie被创建后,如果没有设置它的失效时间,浏览器关闭后就会删除

还可以用setcookie(),用当前时间减去一秒 即 setcookie("name",time()-1)

把过期时间设置为0,可以直接删除Cookie

11.2、Session管理

11.2.1、了解Session

Seeion译为‘会话’,其本义值有始有终的一系列动作/消息,如打电话是从拿起电话拨号到挂断电话都可以成为一个Seesion

  1. Session工作原理

当启动一个Session会话时,会生成一个随机且唯一的session_id,也就是Session的文件名,此时session_id会存放在服务器的内存中,当关闭页面时此ID会自动注销,重新登录此页面,会再次生成以一个唯一的ID

  1. Session的功能

Session在Web技术中非常重要,由于网页是一种无状态的连接程序,因此无法得知用户的浏览状态。通过Session则可记录用户的有关信息,以供用户再次以此身份对Web服务器提交要求时做确定

11.2.2、创建会话

  1. 启动会话(二选一即可)
  1. session_start() 使用前浏览器不能有任何输出,不然会报错
  2. session_register()
  1. 注册会话
<?php
session_start();
$_SESSION['user'] = 'admin';
?>
  1. 删除会话

unset($_SESSION['user'])

注意:不能unset($_SESSION),因为会将全局变量$_SESSION销毁,而且不能恢复

删除多个:

$_SESSION = array()

结束当前会话:

session_destroy()

11.2.3、Session设置时间

  1. session_set_cookie_params() (不推荐用,因为在浏览器会可能会出现问题)

session_set_cookie_params() 要在 session_start()之前

<?php
$time = 1*60;
session_set_cookie_params($time);
session_start();
$_SESSION['user'] = 'admin';
?>
  1. setcookie()
<?php
session_start();
$time = 60;
setcookie(session_name(), session_id(), time() + $time, '/');
$_SESSION['user'] = 'admin'
?>

客户端禁止Cookie

当客户端禁用Cookie时,Session页面间传递会失效

  1. 在登录前提醒用户必须打开Cookie,这是很多论坛的方法
  2. 设置php.ini文件种的session.use_trans_sid = 1,或编译时打开-enable-trans-sid选项,让PHP自动跨页面传递session_id
  3. 通过GET方法,隐藏表单传递session_id
  4. 使用文件或者数据库存session_id,在页面中手动调用

14 面向对象

14.2.1 类的定义

php通过class来定义

class name{
  ...
}

14.2.2 成员方法

类中的函数被称为成员方法。函数和成语方法唯一的区别就是,函数实现的是某个独立的功能,成员方法是实现类中的一个行为,是类的一部分

14.2.3 类的实例化

调用格式

对象名->成员方法

14.2.4 成员变量

调用格式

对象名->成员变量

14.2.5 类常量

const PI=3.14

调用格式

类名::常量名

14.2.6 构造方法和析构方法

构造方法

当一个类实例化一个对象时,可能会随着对象初始化一些成员变量

image.png

可以看到如果要赋值的话,要一个一个赋值,会很麻烦

因此可以使用构造方法

格式如下:

void __construct()

 public function __construct(){  
  }

image.png

构造方法是初始化对象时使用的。如果类中没有构造方法,那么php会自动生成一个,自动生成的构造方法没有任何参数,没有任何操作

析构方法

析构方法的作用正好与构造相反,是对象被销毁时被调用的,作用是释放内存。

格式如下:

void __destrct(void)

image.png

PHP使用的是一种“垃圾回收”机制,自动清除不再使用的对象,释放内存。就是说即使不使用unset(),析构方法也会自动被调用,这里只是明确一下析构函数在何时被调用,一般情况下是不需要手动创建析构方法的

14.2.7 继承和多态的实现

继承和多态最根本的作用就是完成代码的重。

继承

子类继承父类的所有成员变量和方法,包括构造函数,当子类被创建时,PHP会先在子类中找构造方法,没有就去调用父类中的构造方法

多态

多态存在的两种形式:覆盖和重载

覆盖

所谓覆盖就是在子类中重写父类的方法,而在两个子类的对象中虽然调用的是父类中相同的方法,但返回结果不一样

重载

函数重载指一个标识符被用作多个函数名,且能够通过函数的参数个数或参数类型将这些同名的函数区分开。好处是可实现代码宠用,不用为了对不同的参数类型或参数个数而写多个函数

<?php
class MyClass {
  public function __call($name, $num) {
    echo "方法名称:".$name."</br>";
    echo "参数个数:".count($num)."</br>";
    if (count($num) == 1) {
      echo $this->list1($num[0]);
    }
    if (count($num) == 2) {
      echo $this->list2($num[0], $num[1]);
    }
  }
 
  public function list1($a) {
    return "这是一个参数为1的方法,参数值为:".$a;
  }
 
  public function list2($a, $b) {
    return "这是一个参数为2的方法,参数值为:".$a."和".$b;
  }
 }
 
 $myObject = new MyClass();
 echo $myObject->someMethod("Hello"); // 输出:方法名称:someMethod</br>参数个数:1</br>这是一个参数为1的方法,参数值为:Hello
 echo $myObject->someMethod("Hello", "World"); // 输出:方法名称:someMethod</br>参数个数:2</br>这是一个参数为2的方法,参数值为:Hello和World
?>

这段PHP代码是一个类的方法,称为__call。它是一个特殊的方法,当调用对象的方法时,如果对象没有这个方法,那么就会自动调用__call方法。这在面向对象编程中非常有用,因为它允许我们实现一个接口,而无需对每个实现类都进行修改。

__call方法接收两个参数:$name$num$name是方法名,$num是方法参数。在这个例子中,$name是调用__call方法的方法名,$num是方法参数。

首先,它输出方法名称和参数个数。然后,它根据参数个数进行不同的处理。如果参数个数为1,那么它调用list1方法并输出结果。如果参数个数为2,那么它调用list2方法并输出结果。

14.2.8 $this-> 和 :: 的使用

php是通过伪变量$this->和作用域操作符:: 来实现一些功能的

$this->

在定义类时,根本无法得知对象的名称是什么,这时如果想调用类中的方法,就要用伪变量this>this-> 。 this 的意思就是本身,所以$this->只能在类的内部使用

::

相比伪变量只能在类的内部使用,操作符更为强大,它可以在没有声明任何实例的情况下访问类中的成员方法或成员

格式:

关键字::变量名/常量名/方法名

关键字:

  1. parent:可以调用父类中的成员变量、成员方法和常量
  2. self:可以调用当前类中静态成员和常量
  3. 类名:而已调用本类中的变量、常量、方法
<?php
  class Book{
    const NAME = 'computer';
    function __construct(){
      echo '本月的销售冠军是:'.Book::NAME.'<br>';// 调用本类的常量
    }
  }
  class I_book extends Book{
    const NAME = 'foreign language';
    function __construct(){
      parent::__construct(); // 调用父类的构造函数
      echo '本月的销售冠军是:'.self::NAME.'<br>'; // 调用本类的常量
    }
  }
  $boj = new I_book();
?>

14.2.9 数据隐藏

public(公共成员)

顾名思义,就是公开的、没有必要隐藏的数据信息。可在程序中的任何位置被其他类和对象调用,子类可以继承和使用父类中的所有的公共成员

private(私有成员)

被其修饰的变量和方法,只能在所属类的内部被调用和修改,不可以在类外部被访问,在子类中也不可以

protected(保护成员)

可以将数据完全隐藏起来,除了本类外,其他地方都不可调用,子类可以,对于有些变量希望子类能够调用,但对于另外的类来说,还要做到封装,就可以用这个修饰

14.2.10 静态变量(方法)

格式如下

关键字::静态成员

  1. self:在内部调用静态成员
  2. 静态成员所在的类名,在类外调用类内部的静态成员

在静态方法中,只能调用静态变量,不能调用普通变量,而普通方法则可以调用静态变量 使用静态成员,除了可以不需要实例化对象,还可以在对象被销毁时,继续保留被修改的静态成员,以便下次使用

14.3.1 final关键字

final 表示最终的,说明被其修饰后就不能被继承了,也不能再有子类

14.3.2 抽象类 abstract

abstract ,抽象类和普通类相似,包含成员变量,成员方法。两者区别在于,抽象类至少要包含一个抽象方法。抽象方法没有方法体。其功能的实现只能在子类中完成。抽象方法也是使用此关键字修饰

抽象类和抽象方法主要应用在复杂的层次关系中,这种层次关系要求每个子类都要重写某些方法

14.3.3 接口的使用 interface implements

继承特性简化了对象、类的创建,增加了代码的可重性。但php只继承单继承,如果想实现多重继承,就要使用接口

不要用public以外的关键词来修饰接口中的类成员,对于方法,不写关键字也可以,这是一个接口类自身的属性决定的

implements,子类用其实现接口

14.3.4 克隆对象 clone

  $obj = new className();
  $obj2= clone $obj;

__clone 方法

有时除了单纯的克隆对象外,还需要克隆出来的对象可以拥有自己的属性和行为。这时就可以使用__clone方法来实现。__clone方法的作用是:在克隆对象的过程中,调用__clone方法,可以使克隆出来的对象保持自己的一些行为及属性

<?php
  class Book{
    private $id=1;
    public function setId($id){
      $this->id = $id;
    }
    public function getId(){
      return $this->id;
    }
    public function __clone(){
      $this->id = 100;
    }
  }
  $book1 = new Book();
  $book2 = clone $book1;
  echo $book1->getId();
  echo "<br>";
  echo $book2->getId();
?>

14.3.5 对象比较

== 是比较两个对象的内容

=== 是比较对象的引用地址

14.3.6 对象类型检测

instanceof 检测当前对象属于哪个类

格式为:

ObjectName instanceof ClassName

14.3.7 魔术方法

两个下划线开头的方法,被成为魔术方法

PHP中保留了所有以__开头的方法,所以只能使用在PHP文档中已有的这些方法,不要自己创建,如果希望调用这些魔术方法,必须在类中定义,否则不会执行未创建的魔术方法

__set 、 __get

  1. 当程序试图写入一个不存在或者不可见的成员变量时,PHP会执行__set 。__set包含两个参数,分别为变量的名称,变量值,两个参数不可省略
  2. 当程序调用一个未定义或不可见的成员变量时,可以通过__get方法来读取变量值。__get方法有一个参数,表示要调用的变量
<?php
  class Book{
    private $id;
    public function  __get($name){
      if(isset($this->$name)){
        echo "变量名称:".$this->name.'<br>';
      }else{
        echo "变量名称:".$name."不存在!";
        $this->$name =  0;
      }
    }
    public function __set($name,$value){
      if(isset($this->$name)){
        $this->$name = $value;
        echo "变量名称:".$this->name."赋值为:".$value."<br>";
      }else{
        $this->$name = $value;
        echo "变量名称:".$name."被初始化为".$value."<br>";
      }
    }
  }
  $myObj = new Book();
  $myObj->id = 1;
  $myObj->name ;
?>

__call方法

当程序试图调用不存在或者不可见的成员方法时,就会调用__call方法的内容,参数为 方法名和方法参数

__sleep 和 __wakeup

使用serialize()函数可以实现序列化对象。就是将对象中的变量全部保存下来,对象中的类则只保存类名,在使用serialize()时,如果实例化的对象包含__sleep方法,则会先执行__sleep方法。该方法可以清除对象并返回一个该对象中所有变量的数组。使用__sleep方法的目的是关闭对象可能具有的数据库连接等类似的善后工作

unserialize()函数 还原被serialize()序列化的对象 __wakeup方法是恢复在序列化中可能丢失的数据库连接及相关工作

<?php
 class SportObject{
  private $type = "DIY";
  public function getType(){
   return $this->type;
  }
  public function __sleep(){
    echo "使用serialize()将对象保存起来,可以放到文本文件中,或者数据库中<br>";
    return array('type');
  }
  public function __wakeup(){
    echo "使用unserialize()将对象从文本文件中读取出来,或者数据库中<br>";

  }
 }
 $myBook = new SportObject();
 $i = serialize($myBook);
 echo "序列化后的字符串:".$i;
 $reBook = unserialize($i);
 echo "反序列化后的对象:".$reBook->getType();
?>

__toString

当使用echo或者print输出对象时,将对象转化为字符串

<?php
  class Book{
    private $type = "DIY";
    public function __toString(){
      return $this->type;
    }
  }
  $my = new Book();
  echo "值:";
  echo $my;
?>
  1. 如果没有__toString方法,直接输出对象将会发生致命错误
  2. 输出对象时应注意,echo或print后面直接跟要输出的对象,中间不要加多余的字符,否则__toString方法不会被执行

__autoload(已弃用,替换为spl_autoload_register()函数)

将一个独立、完整的类保存到PHP页中,并且文件名和类名保持一致、这是每个开发人员都需要养成的良好习惯。这样重复使用某个类时能很好找到。但问题是在一个页面中引进很多的类,需要使用include_once()函数或者require_once()一个一个的引进

因此有了__autoload :自动实例化需要使用的类

当程序要用到一个类,但该类还没有被实例化时使用,在指定的路径下自动查找和该类名称相同的文件,找到程序就继续执行

1.创建一个index.php文件

<?php
  function my_autoloader($class_name){  //创建自动实例化方法
    $fileName = $class_name . '.php'; //类文件路径
    if (file_exists($fileName)) { //判断文件是否存在
      require_once $fileName;
      return true;
    }
    return false;
  }
  spl_autoload_register('my_autoloader'); // 调用函数
  $myBook = new SportObject('江山'); //实例化对象
  echo $myBook; //输出内容 
?>

  1. 同级下创建SportObject.php
<?php
class SportObject{ // 声明类SportObject
  private $cont;    //声明私有变量
  public function __construct($cont){  //声明构造方法
    $this->cont = $cont;
  }
  public function __toString(){  //创建__toString
    return $this->cont;
  }
}

?>

14.3.8 类的异常

Exception 类

使用try、catch、throw

<?php 
  try{
    ...
  }catch(Exception $e){
    throw new Exception($e->getMessage());
  }
?>

PHP异常处理机制在开发过程中不是必须的,但一个好的程序员应该具有排查错误的能力

过多的使用try会导致PHP程序执行效率低,如果没有必要,少用,通常只在文件处理、远程网络处理等功能时才使用

15 PHP 加密技术

15.1 PHP加密函数

15.1.1 使用crypt()函数进行加密

格式如下: string crypt(string str [,string salt])

str 需要加密的字符串,salt为加密时使用的干扰串。如果省略会随机生成一个干扰串

crypt()支持4种算法和salt参数

算法长度
CRYPT_STD_DES2-character(默认)
CRYPT_EXT_DES9-character
CRYPT_MD512-character(以11开头)
CRYPT_BLOWFISH16-character(以22开头)

默认情况下,PHP使用一个或两个字符的DES干扰串,如果系统使用的是MD5,则会使用12个字符。可以通过CRYPT_SALT_LENGTH变量来查看当前所使用的干扰串的长度

15.1.2 使用md5函数进行加密

格式如下: string md5(string str[,bool raw_output])

str 需要加密的明文,raw_output如果设为true,则返回一个二进制形式的密文,默认为false

<?php 
$password = 'my_password';
echo md5($hashed_password);
?>

15.1.3 使用sha1()函数进行加密

string sha1(string str [,bool raw_output])

函数返回一个40位的十六进制数,如果raw_output为true,则返回一个20位的二进制数,默认false

<?php 
$password = 'my_password';
echo sha1($hashed_password);
?>

15.2 PHP加密扩展库

18 PHP操作MySQL数据库

18.1 PHP操作MySQL数据库的方法

18.1.1 连接数据库

格式如下 :

mysqli mysqli_connect([string server [,string username[,string password[,string dbname[,int port[,string socket]]]]]])

成功就返回一个MySQL连接标识,失败返回false

参数说明
serverMySQL服务器地址
username用户名,默认值是服务器进程所有者的用户名
password密码。默认值是空密码
dbname连接的数据库名
port端口号
socketUNIX域socket
<?php 
$server = '127.0.0.1';
$username = 'root';
$password = '123456';
$mySql = mysqli_connect($server, $username, $password);
if($mySql){
  echo "连接成功!";
}else{
  echo "连接失败!";
}
?>

18.1.2 选择MySQL数据库

image.png

可以直接写数据库名,可以用函数来选择

格式如下: bool mysqli_select_db(mysqli link,string dbname)

  1. link:为必选参数,应用mysqli_connect()函数成功连接数据库后返回连接标识
  2. dbname:为数据库名字
<?php 
$server = '127.0.0.1';
$username = 'root';
$password = '123456';
$mySql = mysqli_connect($server, $username, $password);
if(mysqli_select_db($mySql, 'test')){
    echo '数据库连接成功';
}else{
  echo '数据库连接失败';
}
?>

在实际的程序开发过程中,将MySQL服务器的连接和数据库的选择存在一个单独的文件中, 在需要使用的脚本中通过require语句包含这个文件即可

18.1.3 执行SQL语句

格式: mixed mysqli_query(mysqli link, string query [,int resultmode])

  1. link:为必选参数,应用mysqli_connect()函数成功连接数据库后返回连接标识
  2. query:为必须参数,所要执行的查询语句
  3. resultmode:可选

18.1.4 将结果集返回到数组中

格式: array mysqli_fetch_array(resource result [,int result_type])

  1. result:资源类型的参数,要传入的是由mysqli_query()函数返回的数据指针
  2. result_type:可选项,设置结果集数组的表述方式:如下
  • MYSQLI_ASSOC:返回一个关联数组,数组的小标由表的字段名组成
  • MYSQLI_NUM:返回一个索引数组,数组下标由数字组成
  • MYSQLI_BOTH:返回一个同时包含关联和数字索引的数组,默认值是MYSQLI_BOTH

mysqli_fetch_array返回的字段名区分大小写,这是初学者最容易忽略的问题

18.1.5 从结果集中获取一行作为对象

格式: mixed mysqli_fetch_object(resource result)

这个函数和mysqli_fetch_array类似,只有一个区别,它返回的是一个对象而不是一个数组,即只能通过字段名来访问数组

18.1.6 从结果集中获取一行作为枚举数组

格式: mixed mysqli_fetch_row(resource result)

返回根据所取得的行生成的数组,如果没有更多行则返回null。返回数组的偏移量从0开始,即以$row[0]的形式访问第一个元素(只有一个元素时也是如此)

在应用mysqli_fetch_row逐行获取结果集中的记录时,只能使用数字索引来读取数组中的数据,而不像mysqli_fetch_array那样可以使用关联索引获取数组中的数据

18.1.7 从结果集中获取一行作为关联数组

格式: mixed mysqli_fetch_assoc(resource result)

返回根据所取得的行生成的数组,如果没有更多的行返回null,该数组的下标为数据表中字段的名称

18.1.8 获取查询结果集中的记录数

格式: int mysqli_num_rows(resource result)

返回结果集中行的数目,此命令仅对select语句有效

18.1.9 释放内存

格式: void mysqli_free_result(rexource result)

将释放所有与标识符result所关联的内存,该函数仅需要在考虑到返回很大的结果集时会占用多少内存时调用,在脚本结束后所有关联的内存都会被自动释放

18.1.10 关闭连接

格式: bool mysqli_close(mysqli link)

link:为必选参数,应用mysqli_connect()函数成功连接数据库后返回连接标识

PHP 中与数据库的连接并是非持久连接,系统会自动回收,一般不用设置关闭,但如果一次性返回的结果集比较大,或网络访问量比较多,则最好使用mysqli_close进行手动关闭

18.1.11 连接与关闭MySQL服务器的最佳时机

MySQL服务器连接应该及时关闭,但不是说每一次数据库操作后都要立即关闭连接

例如:在book_query()函数中实现MySQL服务器的连接,在查询数据表中的数据之后释放内存并关闭连接

image.png

以上的代码每调用一次book_query(),都会打开新的MySQL服务器连接和关闭MySQL服务器,浪费服务器的资源

image.png

19 PDO数据库抽象层