批改状态:合格
老师批语:基本一个项目, 就是一个个不同的类的组合
<?php// 父类: 设计类abstract class User{// 这里的访问控制符,如果这个成员允许在子类中使用,应该声明为protected,否则privateprotected $name = '超级用户';public function write1(){return '姓名: ' .$this->name;}// 抽象方法: 没有实现,只有声明, 子类中必须实现它abstract protected function write2();}// 子类:实现类, 工作类, 真正干活的是子类class Work extends User{protected $profession = '最大管理员';public function write2(){return parent::write1() . ', 职业: ' . $this->profession;}}// User类只当作父类就不应该允许被实例化// $user = new User();// 必须通过它的子类来调用抽象类中的方法// 客户端代码$work = new Work();// echo $work->write1();echo $work->write2();
<?php// 1. 接口使用场景: 单接口(是否还有双接口,多接口?)interface iUser{// 在接口中所有成员都是抽象的// 接口成员的访问控制必须是public// 不允许有属性,但允许有接口常量, 禁止重写const NATION = 'CHINA';public function write();// 接口还可以有构造方法(后面讲)}// 2. 接口的实现类class User implements iUser{protected $profession = '最大管理员';// 接口中的抽象方法,实现类中必须实现public function write(){return '职业:'.$this->profession. ', 国籍: ' . iUser::NATION;}}// 客户端调用$user = new User();echo $user->write();
<?php// 接口应用场景2: 接口之间的继承// php中禁止多重继承: 单继承(一个接口只能继承一个接口,不能继承多接口)// 接口1interface iUser{const NATION = 'CHINA';}// 接口2interface iUser1 extends iUser{const USER_NAME = '机器猫';}// 接口3interface iUser2 extends iUser, iUser1{public function write();}// 实现类// class User implements iUser, iUser1, iUser2// iUser2已经继承了iUser, iUser1,所以只需要实现iUser2就可以了class User implements iUser2{// 必须实现接口中的抽象方法public function write(){return '姓名:'.iUser1::USER_NAME. ', 国籍: ' . iUser::NATION;}}// 调用echo (new User)->write();
<?php// 接口应用场景3: 用抽象类来实现接口// ① 定义一个数据库的CURD接口interface iDbBase{// 新增public static function insert($db, $data);// 查询public static function select($db, $optoins=[]);// 更新public static function update($db, $options);// 删除public static function delete($db, $where);}// ② 实现类使用抽象类来充当abstract class aDb implements iDbBase{// 使用单例模式连接: 创建类的唯一实例,唯一对象protected static $db = null;// 抽象类充当接口实现类时, 不用必须实现接口中的抽象方法// 当实现类中的方法中有一些公共操作时,可以将这些操作放在中间的抽象类中实现它。例如这里的数据库连接。public static function connect($dsn, $username, $password){if (is_null(self::$db)) {// 如果当前连接对象是null,表示未连接数据库self::$db = new PDO($dsn, $username, $password);}return self::$db;}}// ③ 类的真正实现类。实现一些具体的操作。class DB extends aDb{// 新增public static function insert($db, $data){}// 查询public static function select($db, $optoins=[]){return $db->query('SELECT * FROM `users` LIMIT 3')->fetchAll(PDO::FETCH_ASSOC);}// 更新public static function update($db, $options){}// 删除public static function delete($db, $where){}}// 客户端代码// 连接参数$config = [// 类型'type' => $type ?? 'mysql',// 默认数据库主机名(IP)'host' => $host ?? 'localhost',// 默认数据库名'dbname' => $type ?? 'phpedu',// 默认字符编码集'charset' => $type ?? 'utf8',// 默认端口号'port' => $type ?? '3306',// 默认用户名'username' => $username ?? 'root',// 默认用户的密码'password' => $password ?? 'root'];$dsn = sprintf('%s:host=%s;dbname=%s;',$config['type'],$config['host'],$config['dbname']);$username = $config['username'];$password = $config['password'];$db =DB::connect($dsn, $username, $password);// 调用实现类DB中的select()进行查询foreach (DB::select($db) as $user) {print_r($user);}
<?php// Trait: 特性// trait: 临时类,类中类, 可以嵌入到宿主类// trait: trait实现了一个类的横向功能扩展, 继承实现了类的垂直功能扩展// trait:可以使用类的语句,但不是类。因此不能实例化等。需要用use traitname去调用(有点像php文件间的require)。trait tDemo{// 1.常规成员protected $name = '机器猫';public function getName(){return $this->name;}// 2. 静态成员protected static $gender = '男';public static function getGender(){return self::$gender;}// 3. 抽象成员public static $age;abstract static function getAge();}// 在一个宿主类/工作类/实现类中使用class User{// 类中使用use 关键字引用trait成员use tDemo;// 在宿主类中还必须将trait中的抽象方法实现了static function getAge(){return self::$age;}}// 实例化$user = new User;User::$age = 39;echo $user->getName() . ': ' . $user->getGender(), ': ' .$user->getAge();
<?phpinterface iDB{public static function insert($db, $data);public static function delete($db, $where);public static function update($db, $options);public static function select($db, $options);}abstract class aDB implements iDB{protected static $db = null;public static function connect($dsn, $username, $password){if (is_null(self::$db)){self::$db = new PDO($dsn, $username, $password);}return self::$db;}}class cDB extends aDB{public static function insert($db, $data){$sql = 'INSERT INTO `shao` (`date`, `title`, `label`, `others`) VALUES (?, ?, ?, ?)';$stmt = $db->prepare($sql);$stmt->execute($data);if ($stmt->rowCount() > 0) echo '新增成功 ' . $stmt->rowCount() . ' 条记录,主键id: ' . $db->lastInsertId();unset($db);}public static function delete($db, $where){$sql = 'DELETE FROM `shao` WHERE id = ?';// 这个地方很有趣,只能传递已经有了的字段的值,不能传递字段名。例如将id也用?代替就不行。// 不过这块可以通过if条件来进行字段,及中间等号,大于号等的选择。$stmt = $db->prepare($sql);$stmt->execute($where);// if ($stmt->rowCount() > 0) echo '新增成功 ' . $stmt->rowCount() . ' 条记录,主键id: ' . $db->lastInsertId();// 删除成功后的提示,可以另外考虑。应该是删除前后的rowcount对比之类,或者查询之类的。unset($db);}public static function update($db, $options){$sql = 'UPDATE `shao` SET `date`=?, `title`=?, `label`=?, `others`=? WHERE id = ?';$stmt = $db->prepare($sql);$stmt->execute($options);unset($db);}public static function select($db, $options=[])//这个地方也很奇怪,必须有=[],否则会报错。但其他的几个貌似都不需要。{$sql = 'SELECT * FROM `shao` WHERE id > ?';$stmt = $db->prepare($sql);$stmt->execute($options);return $stmt->fetchALL(PDO::FETCH_ASSOC);var_dump($stmt);unset($db);}}$config = [// 类型'type' => $type ?? 'mysql',// 默认数据库主机名(IP)'host' => $host ?? 'localhost',// 默认数据库名'dbname' => $type ?? 'liangtest',// 默认字符编码集'charset' => $type ?? 'utf8',// 默认端口号'port' => $type ?? '3306',// 默认用户名'username' => $username ?? 'liang',// 默认用户的密码'password' => $password ?? 'xxxxxx'];extract($config);$dsn= sprintf('%s:host=%s;dbname=%s;charset=%s;port=%s',$type,$host,$dbname,$charset,$port);$db = cDB::connect($dsn, $username, $password);//$data = ['2020-07-23','多test六下,没准你就成功了','努力,自我训练','NULL'];//cDB::insert($db,$data);//$where = ['28'];//cDB::delete($db,$where);//$options = ['2020-07-22', 'test八下,肯定会成功','个人,发展','NULL','22'];//cDB::update($db,$options);$options = ['25'];foreach (cDB::select($db,$options) as $item){print_r($item);}
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号