2.PHP对象实例化
<?php
class Student
{
//成员属性
public $name = "张三四";
private $age = 24;
//公共的成员方法
public function showInfo()
{
echo __FILE__;
}
}
//实例化对象,从类上创建对象的过程
$obj1 = new Student();
$obj2 = new Student();
//打印变量类型
var_dump($obj1,$obj2);
/*
一个类可以生产N多个对象
对象的编号不能一样,一样说明时同一个对象
两个对象的数据是一样的
*/
?>
3.访问对象的属性
<?php
class Student
{
//成员属性
public $name = "张三四";
private $age = 24;
//公共的成员方法
public function showInfo()
{
echo __FILE__;
}
}
//实例化对象,从类上创建对象的过程
$obj1 = new Student();
$obj2 = new Student();
//打印变量类型
var_dump($obj1,$obj2);
/*
一个类可以生产N多个对象
对象的编号不能一样,一样说明时同一个对象
两个对象的数据是一样的
*/
?>
4.对象属性操作
<?php
class Student
{
//公共的成员属性
public $name = "张三四";
}
$obj = new Student;
$obj->name = "传智播客";
$obj->age = 24;
unset($obj->age);
echo "我的名字叫: {$obj->name}";
?>
5.成员方法操作
<?php
//成员方法操作
class Student
{
public function showInfo($name,$age)
{
return "{$name}的年龄是{$age}岁";
}
}
$obj = new Student;
echo $obj->showInfo('刘明娟',25);
?>
6.$this关键字使用
<?php
//$this关键字使用
class Student
{
private $name = "张三丰";
private $age = 24;
protected function showLine()
{
return "<hr>";
}
public function showInfo()
{
$str = "<h2>{$this->name}的基本信息</h2>";
$str .=$this->showLine();
$str .="{$this->name}的年龄是{$this-age}岁!";
echo $str;
}
}
$obj = new Student;
$obj->showInfo();
/*
将obj对象传递到showInfo()方法中
在showInfo()方法中,使用$this代替$obj对象
*/
?>
将obj对象传递到showInfo()方法中
在showInfo()方法中,使用$this代替$obj对象
7.类常量的定义和调用格式
//(2)访问类常量
//谁的东西谁来访问,对象的东西用对象调用,类的东西用类的调用
//使用类名来访问类的元素,这种方式又称为"静态化调用方式"
//类常量,不用创建对象,直接就能访问
ClassName::类常量;
<?php
class Student
{
const DB_HOST = "localhost";
const DB_USER = "root";
const DB_PASS = "root";
//公共的成员方法 想调用类内的东西只能使用成员方法
public function showInfo()
{
$str = "<h2>在类内访问类常量</h2>";
$str .="主机名: " .Student::DB_HOST;
$str .="<br>用户名: " .Student::DB_USER;
$str .="<br>密码 " .Student::DB_PASS;
echo $str;
}
}
//用静态化方式,直接访问类常量,不需要创建对象
$str = "<h2>在类内访问类常量</h2>";
$str .="主机名: " .Student::DB_HOST;
$str .="<br>用户名: " .Student::DB_USER;
$str .="<br>密码 " .Student::DB_PASS;
echo $str;
//创建学生类对象
$obj = new Student();
$obj->showInfo();
?>
8.构造方法
<?php
class Student
{
//私有的成员属性: 在项目中,成员属性没有具体的数据,可以有默认值
//所有数据都来自外部传递,所有属性一般都是私有的
private $name;
private $sex;
private $age;
//公共的构造方法
public function __construct($name2,$sex2,$age2)
{
$this->name = $name2;
$this->sex = $sex2;
$this->age = $age2;
}
//公共的成员方法 想调用类内的东西只能使用成员方法
public function showInfo()
{
$str = "姓名: {$this->name}";
$str .="<br>性别: {$this->sex}";
$str .="<br>年龄: {$this->age}" ;
echo $str;
}
}
//创建学生类对象
$obj = new Student("张三","男",26);
$obj->showInfo();
?>
9.析构方法
<?php
class Student
{
public function __destruct()
{
echo "对象即将销毁!";
}
}
$obj = new Student();
echo "这是网页的最后一行代码 <br>";
?>
![`<?php
class Student
{
public function __destruct()
{
echo "对象即将销毁!";
}
}
$obj = new Student();
echo "这是网页的最后一行代码 <br>";
//手动删除对象
// unset($obj);
// echo "这是网页的最后一行代码";
?>`]
(https://img-blog.csdnimg.cn/20200814173422570.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDI3MDY4Mw==,size_16,color_FFFFFF,t_70#pic_center)
10.静态属性和静态方法
<?php
class Student
{
//私有的保存人数的静态属性: 所有对象共享
private static $count = 60;
//公共的静态方法
public static function showInfo()
{
$str = "当前文件名: " .__FILE__;
$str .="<br>当前函数名: " .__FUNCTION__;
$str .="<br>当前方法名: " .__METHOD__;
$str .="<br>班级人数: " .Student::$count;
echo $str;
}
}
//在类外访问公共的静态方法
//访问类的内容(类常量、静态属性、静态方法),不需要创建对象,直接访问
Student::showInfo();
?>
<?php
//self关键字
class Student
{
//定义类常量
const TITLE = "<h2>第69PHP就业班</h2>";
//私有的保存人数的静态属性: 所有对象共享
private static $count = 60;
//公共的静态方法: 在静态方法中$this不存在
public static function showInfo()
{
$str = self::TITLE;
$str .="当前文件名: " .__FILE__;
$str .="<br>当前函数名: " .__FUNCTION__;
$str .="<br>当前方法名: " .__METHOD__;
$str .="<br>班级人数: " .self::$count;
echo $str;
//var_dump($this); $this不能存在于静态方法
}
}
//在类外访问公共的静态方法
//访问类的内容(类常量、静态属性、静态方法),不需要创建对象,直接访问
//对象可以调用: 成员属性、成员方法、静态方法
Student::showInfo();
// $obj = new Student();
// $obj->showInfo();
?>
实例1:学生类设计
<?php
/*
定义一个"学生类", 并由次类实例化两个"学生对象" 。 该类包括姓名,性别,年龄等基本信息,并至少包括一个静态属性
(表示总学生数)和一个常量,以及包括构造方法和析构方法。该对象还可以调用一个方法进行"自我介绍"(显示其中的所有属性)。
构造方法可以自动初始化一个学生的基本信息,并显示 "XX 加入传智",当前有XX个学生。
*/
class Student
{
const TITLE = "<h2>php第69期就业班</h2>";
//私有的静态的保存人数的属性
private static $count = 0;
//私有的成员属性
private $name;
private $sex;
private $age;
//公共的构造方法 : 对象初始化
public function __construct($name2,$sex2,$age2)
{
$this->name = $name2;
$this->sex = $sex2;
$this->age = $age2;
self::$count++;
$this->showInfo();
}
//私有的自我显示方法
private function showInfo()
{
$str = self::TITLE;
$str .="姓名: {$this->name}";
$str .="<br>性别: {$this->sex}";
$str .="<br>年龄: {$this->age}";
$str .="<br>{$this->name}加入传智, 当前有".self::$count."个学生! ";
echo $str;
}
public function __destruct()
{
self::$count;
}
}
$obj1 = new Student("张三丰","男",25);
$obj2 = new Student("李四","男",25);
$obj3 = new Student("李五","男",25);
$obj4 = new Student("李六","男",25);
$obj5 = new Student("李莉","女",25);
?>
11.OOP中内存的分配情况
对于海量数据,使用"引用传地址",要比“传值”速度要快
其他类型变量使用引用传递
如果其他类型变量使用引用传递 只需要在引用的变量前加 & 符号即可
<?php
//值传递的变量,变成"引用传地址"
//实例: 定义一个函数,实现给数组添加元素、
$arr1 = ['10010','张三丰',24];
$school1 = "北京科技大学";
function addElement(&$arr2,$school2)
{
$arr2[] = $school2;
print_r($arr2);
}
addElement($arr1,$school1);
print_r($arr1);
?>
11.类的封装性
实例: 数据库连接类:
<?php
//定义一个数据库工具类
class Db
{
private $db_host;
private $db_port;
private $db_root;
private $db_pass;
private $db_name;
private $charset;
public function __construct($config=array())
{
$this->db_host = $config['db_host'];
$this->db_port = $config['db_port'];
$this->db_root = $config['db_root'];
$this->db_pass = $config['db_pass'];
$this->db_name = $config['db_name'];
$this->charset = $config['charset'];
$this->connectDb();
$this->selectDb();
$this->setCharset();
}
private function connectDb()
{
if(!$this->link = @mysqli_connect($this->db_host.":".$this->db_port,$this->db_root,$this->db_pass))
{
echo "连接数据库{$this->db_name}失败!";
die();
}
}
private function selectDb()
{
if(!mysqli_select_db($this->link,$this->db_name))
{
echo "选择数据库{$this->db_name}失败";
die();
}
}
private function setCharset()
{
mysqli_set_charset($this->link,$this->charset);
}
public function __destruct()
{
mysqli_close($this->link);
}
}
$arr = array(
'db_host' => 'localhost',
'db_port' => '3308',
'db_root' => 'root',
'db_pass' => '',
'db_name' => 'itcast',
'charset' => 'utf8'
);
$db = new Db($arr);
var_dump($db);
?>
12.类的继承性
代码格式:
<?php
//继承的语法格式
class SubClass extends ParentClass
{
//子类的内容定义
}
其中,
SubClass代表要出啊关键的子类名称
extends 是继承的关键字
ParentClass 代表已经存在的父类的名称
?>
单继承和多继承:Java php C
单继承:只能从一个父类来继承功能
实例演示:
<?php
class Student
{
const TITLE = "<h2>PHP第69期就业班</h2>";
protected static $count = 60;
protected $name = "张三丰";
protected static function readMe()
{
return __METHOD__;
}
protected function showInfo()
{
return __METHOD__;
}
}
//继承
class ItcastStudent extends Student
{
public function abc()
{
$str = self::TITLE;
$str .="班级人数: " .ItcastStudent::$count;
$str .="<br>姓名: {$this->name}";
$str .="<br>静态方法: ".self::readMe();
$str .="<br>成员方法: " .$this->showInfo();
echo $str;
}
}
$obj = new ItcastStudent();
$obj->abc();
//继承的语法格式
// class SubClass extends ParentClass
// {
// //子类的内容定义
// }
// 其中,
// SubClass代表要出啊关键的子类名称
// extends 是继承的关键字
// ParentClass 代表已经存在的父类的名称
?>
关键字parent::
父类和子类都有同名常量和静态属性,那么,子类常量和静态属性,会覆盖继承过来的.如果还需
父类的常量和静态属性,通过parent调用。
<?php
class Student
{
const TITLE = "PHP第69期就业班";
protected static $count = 60;
}
class ItcastStudent extends Student
{
const TITLE = "PHP第70期就业班";
protected static $count = 160;
public function showInfo()
{
$str = "父类常量: ".parent::TITLE;
$str .="<br>子类常量: ".self::TITLE;
$str .="<br>父类静态属性: ".parent::$count;
$str .="<br>子类静态属性: ".self::$count;
echo $str;
}
}
$obj = new ItcastStudent();
$obj -> showInfo();
/*
父类和子类都有同名常量和静态属性,那么,子类常量和静态属性,会覆盖继承过来的.如果还需
父类的常量和静态属性,通过parent调用。
*/
?>
方法重写的要求:
方法重写实例:
<?php
class Student
{
public static function showInfo($a,$b)
{
}
}
class ItcastStudent function Student
{
//重写父类的showInfo()方法
public static function showInfo($name,$age)
{
}
}
//4个一一对应
?>
实例:商品类:
<?php
//实例: 类的三大特性
//定义一个基础商品类(最顶层)
//基础类是为了继承,不能直接创建对象
class Shop
{
//私有的商品属性
private $name; //商品名称
private $price; //商品价格
//受保护的构造方法
protected function __construct($name2,$price2)
{
$this->name = $name2;
$this->price = $price2;
}
//受保护的显示商品方法
protected function showInfo()
{
$str = "商品名称: {$this->name}";
$str .="<br>商品价格: {$this->price}";
return $str;
}
}
//创建手机类,并继承商品类
class Mobile extends Shop
{
//私有的手机属性
private $pinpai; //手机品牌
private $city; //手机产地
//重写父类的构造方法
public function __construct($name2,$price2,$pinpai2,$city2)
{
//调用父类的构造方法
parent::__construct($name2,$price2);
$this->pinpai = $pinpai2;
$this->city = $city2;
}
//重写父类的showInfo()方法
public function showInfo()
{
$str = parent::showInfo();
$str .="<br>手机品牌: {$this->pinpai}";
$str .="<br>手机产地: {$this->city}";
return $str;
}
}
//创建图书类,并继承商品类
class Book extends Shop
{
//私有的手机属性
private $author; //作者
private $publish; //出版社
//重写父类的构造方法
public function __construct($name2,$price2,$author2,$publish2)
{
//调用父类的构造方法
parent::__construct($name2,$price2);
$this->author = $author2;
$this->publish = $publish2;
}
//重写父类的showInfo()方法
public function showInfo()
{
$str = parent::showInfo();
$str .="<br>作者: {$this->author}";
$str .="<br>出版社: {$this->publish}";
return $str;
}
}
$obj1 = new Mobile('Iphone 11',4599,'苹果','深圳');
echo $obj1->showInfo();
echo "<hr>";
$obj2 = new Book('PHP入门到放弃',199.00,'武大郎','武大郎烧饼铺');
echo $obj2->showInfo();
?>
最终类和最终方法
<?php
class Student
{
//声明一个最终类的方法: 该方法只能继承,不能重写
final public function showInfo()
{
}
}
//定义一个传智学生类,并继承学生类
class ItcastStudent extends Student
{
public function showInfo()
{
}
}
?>
抽象类:
<?php
//定义抽象学生类: 子类方法的目录大纲
abstract class Student
{
const TITLE = "PHP第69期就业班";
//定义成员的抽象方法
abstract protected function showInfo($a,$b);
//定义静态的抽象方法
abstract static public function readMe();
}
//定义传智学生类,并继承学生类
final class ItcastStudent extends Student
{
//重写showInfo()抽象方法
public function showInfo($name,$age)
{
echo "{$name}的年龄是{$age}岁! <br>";
}
//重写readMe()抽象方法
public static function readMe()
{
echo self::TITLE;
}
}
$obj = new ItcastStudent;
$obj->showInfo("张三",24);
$obj->readMe();
?>
13.接口技术
简单实现:
<?php
//定义第一个接口InterA
interface InterA
{
const TITLE = "PHP第69期就业班";
//定义一个成员抽象方法
public function showInfo($a,$b);
}
//定义第2个接口InterB
interface InterB
{
public static function readMe();
}
//定义学生类,并实现接口功能
class Student implements InterA,InterB
{
//重写showInfo()抽象方法
public function showInfo($name,$age)
{
echo "{$name}的年龄是{$age}岁! <br>";
}
//重写readMe()抽象方法
public static function readMe()
{
echo self::TITLE;
}
}
$obj = new Student();
$obj->showInfo('张三四',26);
$obj->readMe();
?>
手机类
<?php
//定义小灵通的接口
interface XiaoLingTong
{
//定义打电话的抽象方法
public function tel();
}
//定义MP3接口
interface Mp3
{
//定义听音乐的抽象方法
public function music();
}
//定义Mp4接口,并继承mp3继承
interface Mp4 extends Mp3
{
//定义看电影的抽象方法
public function video();
}
//定义手机类,并实现以上所有的接口功能
class Mobile implements XiaoLingTong,Mp4
{
//重写tel()抽象方法
public function tel()
{
echo "正在打电话! <br>";
}
//重写music()抽象方法
public function music()
{
echo "正在听音乐! <br>";
}
//重写video()抽象方法
public function video()
{
echo "正在看电影! <br>";
}
//添加打游戏方法 普通类直接添加功能
public function game()
{
echo "正在打游戏! <br>";
}
}
$obj = new Mobile();
$obj->tel();
$obj->music();
$obj->video();
$obj->game();
?>
14.类的自动加载
实例:有名函数:
atuoload1.php:
<?php
//类的自动加载: 注册类的装载规则
spl_autoload_register("func1");
spl_autoload_register("func2");
function func1($className)
{
//构建类文件的路径
$filename = "./public/$className.class.php";
//如果类文件存在,则包含
if(file_exists($filename)) require_once($filename);
}
function func2($className)
{
$filename = "./libs/$className.cla.php";
if(file_exists($filename)) require_once($filename);
}
$obj1 = new Student();
$obj2 = new Teacher();
?>
Teacher.cla.php:
<?php
//定义一个教师类
class Teacher
{
private $name = "刘保峰";
private $school = "北京科技大学";
public function __construct()
{
echo "{$this->name}毕业于{$this->school}!";
}
}
?>
Student.class.php:
<?php
class Student
{
private $name = "张三";
private $age = 24;
public function __construct()
{
echo "{$this->name}的年龄是{$this->age}岁!<br>";
}
}
?>
<br>
实例:匿名函数:
<?php
//类的自动加载: 注册类的装载规则
spl_autoload_register(function($className){
//构建所有不同规则类文件路径
$arr = array(
"./public/$className.class.php",
"./libs/$className.cla.php",
);
//循环数组
foreach($arr as $filename)
{
//如果类文件存在,则包含
if(file_exists($filename)) require_once($filename);
}
});
$obj1 = new Student();
$obj2 = new Teacher();
?>
15.克隆对象:
<?php
class Student
{
private $name = "张三丰";
private $age = 24;
//克隆方法: 当对象克隆完成时,自动调用方法
public function __clone()
{
$this->name = "方俊英";
$this->age = 29;
}
}
$obj1 = new Student();
//克隆对象: 将$obj1克隆一份,传给$obj2
//克隆对象,是两个独立的新对象
$obj2 = clone $obj1;
var_dump($obj1,$obj2);
?>
16.遍历对象
<?php
class Student
{
protected $name = "张三丰";
private $age = 24;
public $edu = "大专";
//在类内遍历对象属性
public function showInfo()
{
//在类内遍历对象的属性
echo "<h2>在类内遍历对象的属性</h2>";
foreach($this as $key=>$value)
{
echo "\$this->{$key} = {$value}<br>";
}
}
}
$obj = new Student();
$obj->showInfo();
//在类外遍历对象的属性
echo "<h2>在类外遍历对象的属性</h2>";
foreach($obj as $key => $value)
{
echo "\$obj->{$key} = {$value}<br>";
}
?>
17.PHP魔术方法
1.__toString():
变相屏蔽错误
<?php
class Student
{
protected $name = "张三丰";
private $age = 24;
public $edu = "大专";
//魔术方法__toString(): 当将对象转成字符串时,自动调用
public function __toString()
{
return "我喝多了!";
}
}
$obj = new Student();
//将对象转成字符串,然后再输出
echo $obj;
?>
2.__invoke(): 魔术方法__invoke(): 当将对象转成字符串时,自动调用
<?php
class Student
{
protected $name = "张三丰";
private $age = 24;
public $edu = "大专";
//魔术方法__invoke(): 当将对象转成字符串时,自动调用
public function __invoke()
{
echo "我喝多了!";
}
}
$obj = new Student();
//将对象转成字符串,然后再输出
$obj();
//*********************************
//数组元素的值,八大数据类型都可以
$arr = array(10,20,30);
$arr[0] = function()
{
echo "ok";
};
$arr[0]();
?>
17.面向对象设计模式
1.单例设计模式
<?php
//单例设计模式的核心代码
class Db
{
//私有的静态的保存对象的属性
private static $obj = null;
//私有的构造方法: 阻止类外new对象
private function __construct()
{
}
//私有的克隆方法: 阻止类外clone对象
private function __clone(){}
//公共的静态的创建对象的方法
public static function getInstance()
{
//判断当前对象是否存在
if(!self::$obj instanceof self)
{
//如果对象不存在,创建并保存它
self::$obj = new self();
}
//返回对象
return self::$obj;
}
}
//创建数据库类的对象
$db1 = Db::getInstance();
$db2 = Db::getInstance();
var_dump($db1,$db2);
?>
数据库工具类:(单例模式)
<?php
//单例设计模式的核心代码
class Db
{
//私有的静态的保存对象的属性
private static $obj = null;
//数据库成员属性
private $db_host;
private $db_port;
private $db_root;
private $db_pass;
private $db_name;
private $charset;
private $link;
//私有的构造方法: 阻止类外new对象
private function __construct($config=array())
{
$this->db_host = $config['db_host'];
$this->db_port = $config['db_port'];
$this->db_root = $config['db_root'];
$this->db_pass = $config['db_pass'];
$this->db_name = $config['db_name'];
$this->charset = $config['charset'];
$this->connectDb();
$this->selectDb();
$this->setCharset();
}
//私有的克隆方法: 阻止类外clone对象
private function __clone(){}
//公共的静态的创建对象的方法
public static function getInstance($config = array())
{
//判断当前对象是否存在
if(!self::$obj instanceof self)
{
//如果对象不存在,创建并保存它
self::$obj = new self($config);
}
//返回对象
return self::$obj;
}
private function connectDb()
{
if(!$this->link = @mysqli_connect($this->db_host.":".$this->db_port,$this->db_root,$this->db_pass))
{
echo "连接数据库{$this->db_name}失败!";
die();
}
}
private function selectDb()
{
if(!mysqli_select_db($this->link,$this->db_name))
{
echo "选择数据库{$this->db_name}失败";
die();
}
}
private function setCharset()
{
mysqli_set_charset($this->link,$this->charset);
}
public function __destruct()
{
mysqli_close($this->link);
}
}
//创建数据库类的对象
$arr = array
(
'db_host' => 'localhost',
'db_port' => '3308',
'db_root' => 'root',
'db_pass' => '',
'db_name' => 'itcast',
'charset' => 'utf8',
);
$db1 = Db::getInstance($arr);
$db2 = Db::getInstance($arr);
var_dump($db1,$db2);
?>
工厂类:
接口类:
Shape.class.php:
<?php
//定义形状接口
interface Shape
{
//绘制方法
public function draw();
}
?>
矩形形状接口: Rectangle.class.php
<?php
//定义矩形类,并实现形状接口
class Rectangle implements Shape
{
//重写draw()方法
public function draw()
{
echo "正在绘制矩形";
}
}
工厂类: Factory.class.php
<?php
//定义形状工厂类: 生产不同形状对象的工厂
class Factory
{
//公共的静态的创建不同类对象的方法
public static function getInstance($className)
{
//根据传递不同类名参数,返回不同类对象
switch($className)
{
case "Rectangle":
return new Rectangle();
break;
case "Circle":
return new Circle();
break;
case "Line":
return new Line();
break;
default:
return null;
}
}
}
?>
应用: Gongchang.php
<?php
//类的自动重载
spl_autoload_register(function($className){
//构建类文件的路径
$filename = "./libs/$className.class.php";
//如果类文件存在,则包含
if(file_exists($filename))
{
echo $filename."<br>";
require_once($filename);
}
});
//创建矩形对象
$rectangle = Factory::getInstance("Rectangle");
$rectangle->draw();
echo "<hr>";
// //创建圆形对象
// $circle = Factory::getInstance("Circle");
// $circle->draw();
// echo "<hr>";
// //创建线段对象
// $line = Factory::getInstance("Line");
// $line->draw();
?>
重载
魔术方法:
__get:
<?php
class Student
{
private $name = "张三";
private $age = 24;
//当访问不可访问属性时,__get()魔术方法会自动调用
public function __get($n)
{
return $this->$n;
}
}
//创建学生类对象
$obj = new Student();
//访问私有的属性
echo "{$obj->name}的年龄是{$obj->age}岁!";
?>
__set:
<?php
class Student
{
//私有的成员属性
private $name = "张三";
private $age = 24;
//当给不可访问的属性赋值时.__set()魔术方法自动调用
public function __set($n,$v)
{
$this->$n = $v;
}
}
//创建学生类
$obj = new Student();
//修改私有属性
$obj->name = "刘明明";
$obj->age = 29;
var_dump($obj);
?>
__isset:
<?php
class Student
{
private $name = "张三";
private $age = 24;
//当对不可访问的属性应用isset()或empty()时,__isset()会自动调用
public function __isset($n)
{
return isset($this->$n);
}
}
$obj = new Student();
//判断私有属性是否存在
if(isset($obj->name))
{
echo "存在";
}else
{
echo "不存在或不可访问";
}
?>
__unset:
<?php
class Student
{
private $name = "张三";
private $age = 24;
//当私有属性应用unset()时,魔术方法__unset()自动调用
public function __unset($n)
{
unset($this->$n);
}
}
$obj = new Student();
//删除对象属性
unset($obj->name);
var_dump($obj);
?>
__call:
<?php
class Student
{
private $name = "张三";
private $age = 24;
//当访问不存在或访问不可访问的方法时,魔术方法__call()自动调用
//参数: $func是传递过来的方法名称,$args是传递过来的参数数组
public function __call($func,$args)
{
echo "方法{$func}(".implode(',',$args).")不存在或不可访问 ";
}
}
$obj = new Student();
//调用一个不存在的方法
$obj->showInfo("张三",24);
?>
__callStatic:
<?php
class Student
{
private $name = "张三";
private $age = 24;
//用静态化方式访问不存在或不可访问的方法时,魔术方法__callStatic()自动调用
//参数:$func 是传递过来的方法名称,$args是传递过来的参数数组
public static function __callStatic($func,$args)
{
echo "方法{$func}(".implode(',',$args).")不存在或不可访问";
}
}
Student::showInfo('张三四',24,'男');
?>
序列化
变量序列化
serialize():
<?php
//数组变量序列化
$arr = array(
'db_host' => 'localhost',
'db_user' => 'root',
'db_pass' => 'root',
'db_name' => 'itcast'
);
//序列化: 将变量转成可保存的字符串
$str = serialize($arr);
//将序列化字符串,保存到记事本
file_put_contents('./1.txt',$str);
反序列化: unserialize():
<?php
//反序列化: 序列化字符串,还原成原始变量
//读取记事本的数据
$str = file_get_contents('./1.txt');
//将序列化字符串,还原成变量
$arr = unserialize($str);
print_r($arr);
?>
对象序列化
<?php
//对象序列化
class Db
{
private $db_host;
private $db_port;
private $db_root;
private $db_pass;
private $db_name;
private $charset;
private $link;
public function __construct($config=array())
{
$this->db_host = $config['db_host'];
$this->db_port = $config['db_port'];
$this->db_root = $config['db_root'];
$this->db_pass = $config['db_pass'];
$this->db_name = $config['db_name'];
$this->charset = $config['charset'];
$this->connectDb();
$this->selectDb();
$this->setCharset();
}
private function connectDb()
{
if(!$this->link = @mysqli_connect($this->db_host.":".$this->db_port,$this->db_root,$this->db_pass))
{
echo "连接数据库{$this->db_name}失败!";
die();
}
}
private function selectDb()
{
if(!mysqli_select_db($this->link,$this->db_name))
{
echo "选择数据库{$this->db_name}失败";
die();
}
}
private function setCharset()
{
mysqli_set_charset($this->link,$this->charset);
}
//当对象序列化时,魔术方法__sleep()会自动调用
//在__sleep()中工作:清理不需要的属性
public function __sleep()
{
//返回要序列化的对象属性的数组
return array('db_host','db_port','db_root','db_pass','db_name','charset');
}
}
$arr = array(
'db_host' => 'localhost',
'db_port' => '3306',
'db_root' => 'root',
'db_pass' => '',
'db_name' => 'itcast',
'charset' => 'utf8'
);
$db = new Db($arr);
$str = serialize($db);
echo $str;
file_put_contents('./2.txt',$str);
?>
对象反序列化
<?php
//定义一个数据库工具类
class Db
{
private $db_host;
private $db_port;
private $db_root;
private $db_pass;
private $db_name;
private $charset;
public function __construct($config=array())
{
$this->db_host = $config['db_host'];
$this->db_port = $config['db_port'];
$this->db_root = $config['db_root'];
$this->db_pass = $config['db_pass'];
$this->db_name = $config['db_name'];
$this->charset = $config['charset'];
$this->connectDb();
$this->selectDb();
$this->setCharset();
}
private function connectDb()
{
if(!$this->link = @mysqli_connect($this->db_host.":".$this->db_port,$this->db_root,$this->db_pass))
{
echo "连接数据库{$this->db_name}失败!";
die();
}
}
private function selectDb()
{
if(!mysqli_select_db($this->link,$this->db_name))
{
echo "选择数据库{$this->db_name}失败";
die();
}
}
private function setCharset()
{
mysqli_set_charset($this->link,$this->charset);
}
public function __wakeup()
{
$this->connectDb();
$this->selectDb();
$this->setCharset();
}
}
$str = file_get_contents('./2.txt');
$db = unserialize($str);
var_dump($db);
?>
18.静态延时绑定
<?php
//定义一个学生类
class Student
{
//声明一个类常量
const TITLE = "localhost";
//声明一个成员方法
public function showInfo()
{
echo "主机名: ".self::TITLE;
echo "<br>主机名: ".static::TITLE;
echo "<br>姓名: " .static::$name;
}
}
//定义传智学生类,并继承学生类
class ItcastStudent extends Student
{
//声明一个类常量
const TITLE = "127.0.0.10";
//声明一个静态属性
public static $name = "张三四";
}
//创建传智学生类对象
$obj = new ItcastStudent();
$obj->showInfo();
?>
19.命名空间
namespace.php:
<?php
//声明一个App命名空间
namespace App;
//(1)定义一个学生类
class Student
{
private $name = "张三丰";
private $age = 24;
public function __construct()
{
echo "{$this->name}的年龄是{$this->age}岁! <br>";
}
}
//(2)定义一个普通函数
function getMaxInt()
{
echo "PHP最大整数: ".PHP_INT_MAX. "<br>";
}
//(3)定义一个局部常量(const)
const TITLE = "PHP第69期就业班";
//(4)其他的普通代码(除以上三种类型外)
//普通代码不存在空间中, 普通代码存在于全局空间中
$a = 100;
应用:
npc.php
<?php
//包含namespace.php文件
require_once("./namespace.php");
//(1)创建学生类对象
$obj = new App\Student();
//(2)调用getMaxInt()函数
App\getMaxInt();
//(3)访问const定义的常量
echo App\TITLE;
//(4)普通代码直接访问,不带空间名
//原来怎么访问,还怎么访问
echo "<br>" .$a;
子命名空间: z-namespace.php
<?php
//子命名空间
//声明一个App命名空间
namespace App\Home\Controller;
//(1)定义一个学生类
class Student
{
private $name = "张三丰";
private $age = 24;
public function __construct()
{
echo "{$this->name}的年龄是{$this->age}岁! <br>";
}
}
//(2)定义一个普通函数
function getMaxInt()
{
echo "PHP最大整数: ".PHP_INT_MAX. "<br>";
}
//(3)定义一个局部常量(const)
const TITLE = "PHP第69期就业班";
//(4)其他的普通代码(除以上三种类型外)
//普通代码不存在空间中, 普通代码存在于全局空间中
$a = 100;
npc2.php
<?php
//子命名空间
//包含namespace.php文件
require_once("./namespace.php");
//(1)创建学生类对象
$obj = new App\Home\Controller\Student();
//(2)调用getMaxInt()函数
App\Home\Controller\getMaxInt();
//(3)访问const定义的常量
echo App\Home\Controller\TITLE;
//(4)普通代码直接访问,不带空间名
//原来怎么访问,还怎么访问
echo "<br>" .$a;
使用命名空间::
namespace3.php
<?php
//声明第一个命名空间
namespace App\Home\Controller;
//定义一个学生类
class Student
{
private $name = "张三丰";
private $age = 24;
public function __construct()
{
echo "{$this->name}的年龄是{$this->age}岁!<br>";
}
}
//创建学生类: 非限定名称,不带任何前缀
$obj = new Student();
//声明第2个命名空间
namespace App\Home;
//创建学生类对象: 限定名称,带相对空间前缀
$obj = new Controller\Student();
npc3.php
<?php
//包含namespace.php文件
require_once('./namespace3.php');
//完全限定名称: 从根空间开始查找
//创建App\Home\Controller中的Student的对象
$obj = new \App\Home\Controller\Student();
起别名:
namespace4.php
<?php //声明第1个命名空间
namespace App\Home\Controller;
//定义一个学生类
class Student
{
private $name = "张三丰";
private $age = 24;
public function __construct()
{
echo "{$this->name}的年龄是{$this->age}岁!<br>";
}
}
npc4.php
<?php
//包含namespace4.php文件
require_once("./namespace4.php");
//定义一个学生类
class Student
{
private $name = "周更生";
private $age = 24;
public function __construct()
{
echo "{$this->name}的年龄是{$this->age}岁! <br>";
}
}
//导入App\Home\Controller空间中的Student类
//使用use导入空间中的类,如果类名与当前环境下类名冲突,使用as关键字起别名
//最后一个"\"后面就是类名
//use App\Home\Controller\Student; //不冲突写法
use App\Home\Controller\Student as Student1;
//创建App\Home\Controller空间中的Student类对象
$obj1 = new Student1();
$obj2 = new Student();
20.PDO类:
$pdo->exec():
<?php
//数据库配置信息
$dsn = "mysql:host=127.0.0.1;port=3308;dbname=itcast;charset=utf8";
$username = "root";
$password="";
//创建PDO类的对象
$pdo = new PDO($dsn,$username,$password);
//执行插入的SQL语句
$sql = "INSERT INTO student VALUES(null,'刘东明',1,default,'大专',6000,400,'山东省')";
$records = $pdo->exec($sql);
echo "成功插入了{$records}条记录!";
PDO->query:
<?php
//数据库配置信息
$dsn = "mysql:host=127.0.0.1;port=3308;dbname=itcast;charset=utf8";
$username = "root";
$password = "";
//创建PDO类的对象
$pdo = new PDO($dsn,$username,$password);
//执行查询的SQL语句,返回结果集对象(pdoStatement类)
$sql = "SELECT * FROM student ORDER BY id DESC";
$PDOStatement = $pdo->query($sql);
var_dump($PDOStatement);
$PDO->lastinsertid()
<?php
//数据库配置信息
$dsn = "mysql:host=127.0.0.1;port=3308;dbname=itcast;charset=utf8";
$username = "root";
$password = "";
//创建PDO类的对象
$pdo = new PDO($dsn,$username,$password);
//执行插入的SQL语句
$sql = "INSERT INTO student(name,salary,bonus,city) VALUES('刘茫茫',8000,400,'安徽省')";
$pdo->exec($sql);
//获取最后插入成功的记录的id
$id = $pdo->lastInsertId();
echo "最后插入成功的记录ID是:{$id}";
PDO::setAttribute (自行查找手册)
<?php
//配置信息
$dsn = "mysql:host=127.0.0.1;port=3308;dbname=itcast;charset=utf8";
$username = "root";
$password = "";
//创建PDO类
$pdo = new PDO($dsn,$username,$password);
//设置PDO属性: 设置从结果集提取数组的类型为关联数组
$pdo->setAttribute(pdo::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC);
//执行查询的SQL语句,执行成功返回结果集对象(PDOStatement类)
$sql = "SELECT * FROM student";
$PDOStatment = $pdo->query($sql);
//遍历结果集对象,取出每一行数据(一维数组)
foreach($PDOStatment as $arr)
{
print_r($arr);
}
//纯属示范 实际不这样使用
PDO::ATTR_DEFAULT_FETCH_MODE: 设置默认的提取模式。关于模式的说明可以在 PDOStatement::fetch() 文档找到。
PDOStatement::fetch
◦ PDO::FETCH_ASSOC:返回一个索引为结果集列名的数组
PDOStatement->fetch:
<?php
//数据库配置信息
$dsn = "mysql:host=127.0.0.1;port=3308;dbname=itcast;charset=utf8";
$username = "root";
$password = "";
//创建PDO类的对象
$pdo = new PDO($dsn,$username,$password);
//执行查询的sql语句,执行成功返回结果集对象(PDOStatement类)
$sql = "SELECT * FROM student";
$PDOStatement = $pdo->query($sql);
//从结果集对象循环取出所有行数据
while($arr = $PDOStatement->fetch(PDO::FETCH_ASSOC))
{
print_r($arr);
}
PDOStatement->fetchall
<?php
//配置信息
$dsn = "mysql:host=127.0.0.1;port=3308;dbname=itcast;charset=utf8";
$username = "root";
$password = "";
//创建PDO类对象
$pdo = new PDO($dsn,$username,$password);
//执行查询的SQL语句,执行成功返回结果集对象(PDOStatement类)
$sql = "SELECT * FROM student";
$PDOStatement = $pdo->query($sql);
//从结果集对象获取多行数据
$arrs = $PDOStatement->fetchAll(PDO::FETCH_ASSOC);
print_r($arrs);
PDOStatement->rowCount ![在这里插入图片描述](https://img-blog.csdnimg.cn/2020090509534438.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDI3MDY4Mw==,size_16,color_FFFFFF,t_70#pic_center)
<?php
//配置信息
$dsn = "mysql:host=127.0.0.1;port=3306;dbname=itcast;charset=utf8";
$username = "root";
$password = "root";
//创建PDO对象
$pdo = new PDO($dsn,$username,$password);
//执行查询的SQL语句,执行成功返回结果集对象(PDOStatement类)
$sql = "SELECT * FROM student";
$PDOStatement = $pdo->query($sql);
//获取查询记录数
$records = $PDOStatement->rowCount();
echo "总记录数为{$records}条";
21.PDO错误处理
<?php
//配置信息
$dsn = "mysql:host=127.0.0.1;port=3306;dbname=itcast;charset=utf8";
$username = "root";
$password = "root";
//创建PDO类的对象
$pdo = new PDO($dsn,$username,$password);
//执行查询的SQL语句,执行成功返回结果集对象(PDOStatement类)
$sql = "SELECT * FROM student WHERE id = abc";
$PDOStatement = $pdo->query($sql);
//获取错误信息
echo "错误编号: ".$pdo->errorCode();
echo "<br>错误信息: ";
print_r($pdo->errorInfo());
编号错误为5个0,说明没有错误
<?php
//配置信息
$dsn = "mysql:host=127.0.0.1;port=3306;dbname=itcast;charset=utf8";
$username = "root";
$password = "root";
//创建PDO类对象
$pdo = new PDO($dsn,$username,$password);
//设置错误报告模式为: 警告模式
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
//执行查询的SQL语句,执行成功返回结果集对象(PDOStatement类)
$sql = "SELECT * FROM student WHERE id = abc";
echo "错误编号: ".$pdo->errorCode();
echo "<br>错误信息: ";
print_r($pdo->errorInfo());
异常模式
<?php
//配置信息
$dsn = "mysql:host=127.0.0.1;port=3306;dbname=itcast;charset=utf8";
$username = "root";
$password = "root";
//创建PDO对象
$pdo = new PDO($dsn,$username,$password);
//设置错误报告模式为:异常模式
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
try{
//执行查询的SQL语句,执行成功返回结果集对象(PDOStatement类)
$sql = "SELECT * FROm student WHERE id = abc";
$PDOStatement = $pdo->query($sql);
}catch(Exception $error)
{
//输出异常信息
echo "错误编号: ".$error->getCode();
echo "<br>错误行号: ".$error->getLine();
echo "<br>错误文件: ".$error->getFile();
echo "<br>错误信息: ".$error->getMessage();
}
PDO预处理步骤:
bindValue:
<?php
//数据库配置信息
$dsn = "mysql:host=127.0.0.1;port=3306;dbname=itcast;charset=utf8";
$username = "root";
$password = "root";
//创建PDO类对象
$pdo = new PDO($dsn,$username,$password);
//制作相同的SQL语句,数据部分用占位符代替
$sql = "INSERT INTO student(name,salary,bonus,city) VALUES(:name,:salary,:bonus,:city)";
//$sql = "INSERT INTO student(name,salary,bonus,city) VALUES(?,?,?,?)";
//预编译相同结构的SQL语句(含有占位符)
$PDOStatement = $pdo->prepare($sql);
//给命名参数(:value)占位符绑定数据: 每个命名参数必须要加引号
$PDOStatement->bindValue(':name','四张五');
$PDOStatement->bindValue(':salary',8000);
$PDOStatement->bindValue(':bonus',900);
$PDOStatement->bindValue(':city','山东省');
//给问号(?)占位符绑定数据: 1对应第一个问好,2对应第2个问好,以此类推...
// $PDOStatement->bindValue(1,'张四五');
// $PDOStatement->bindValue(2,9000);
// $PDOStatement->bindValue(3,900);
// $PDOStatement->bindValue(4,'山西省');
//执行绑定数据预处理SQL语句
$PDOStatement->execute();